What PHP 5.5 might look like

What PHP 5.5 might look like

PHP 5.4 was released just four months ago, so it probably is a bit too early to look at the next PHP version. Still I’d like to give all the people who aren’t following the internals mailing list a small sneak peek at what PHP 5.5 might look like.

via: nikic.github.com

Now, without further ado, the list of stuff being worked on for PHP 5.5:

Backwards compatibility breaks

We’ll start off with two changes that already landed in master and represent BC breaks (to some degree at least):

Windows XP and 2003 support dropped

Status: landed; Responsible: Pierre Joye

PHP 5.5 will no longer support Windows XP and 2003. Those systems are around a decade old, so PHP is pulling the plug on them.

/e modifier deprecated

Status: landed; Responsible: myself

The

e

modifier instructs the

preg_replace

function to evaluate the replacement string as PHP code instead of just doing a simple string replacement. Unsurprisingly this behavior is a constant source of problems and security issues. That’s why use of this modifier will throw a deprecation warning as of PHP 5.5. As a replacement you should use the

preg_replace_callback

function. You can find more information on this change in the corresponding RFC.

Function and class additions

Next we’ll look at some the planned function and class additions:

boolval()

Status: landed; Responsible: Jille Timmermans

PHP already implements the

strval

,

intval

and

floatval

functions. To be consistent the

boolval

function is now added, too. It does exactly the same thing as a

(bool)

cast, but can be used as a callback function.

hash_pbkdf2()

Status: landed; Responsible: Anthony Ferrara

PBKDF2 stands for “Password-Based Key Derivation Function 2” and is – as the name already says – an algorithm for deriving a cryptographic key from a password. This is required for encryption algorithms, but can also be used for password hashing. For a more extensive description and usage examples see the RFC.

Intl additions

Status: landed; Responsible: Gustavo André dos Santos Lopes

There have been many improvements to the intl extension . E.g. there will be new

IntlCalendar

,

IntlGregorianCalendar

,

IntlTimeZone

,

IntlBreakIterator

,

IntlRuleBasedBreakIterator

,

IntlCodePointBreakIterator

classes. I sadly don’t know much about the intl extension, so I will just direct you to the mailing list announcements for Calendar and BreakIterator , if you want to know more.

array_column()

Status: proposed; Responsible: Ben Ramsey

There is a proposal pending for a new

array_column

(or

array_pluck

) function that would behave as follows:

<?php $userNames = array_column($users, 'name'); // is the same as $userNames = []; foreach ($users as $user) { $userNames[] = $user['name']; } 

So it would be like fetching a column from a database, but for arrays.

A simple API for password hashing

Status: proposed; Responsible: Anthony Ferrara

The recent password leaks (from LinkedIn etc) have shown that even large websites don’t get how to properly hash passwords. People have been advocating the use of bcrypt for years, but still most people seem to be using completely unsafe

sha1

hashes.

We figured that the reason for this might be the really hard to use API of the

crypt

function. Thus we would like to introduce a new, simple API for secure password hashing:

<?php $password = "foo"; // creating the hash $hash = password_hash($password, PASSWORD_BCRYPT); // verifying a password if (password_verify($password, $hash)) { // password correct! } else { // password wrong! } 

The new hashing API comes with a few more features, which are outlined in the RFC.

Language changes

Now comes the really interesting stuff: New language features and enhancements.

Constant dereferencing

Status: landed; Responsible: Xinchen Hui

“Constant dereferencing” means that array operations can be directly applied to string and array literals. Here two examples:

<?php function randomHexString($length) { $str = ''; for ($i = 0; $i < $length; ++$i) { $str .= "0123456789abcdef"[mt_rand(0, 15)]; // direct dereference of string } } function randomBool() { return [false, true][mt_rand(0, 1)]; // direct dereference of array } 

I don’t think that this feature is of much use in practice, but it makes the language a bit more consistent. See also
the RFC.

empty() works with function calls (and other expressions)

Status: landed; Responsible: myself

Currently the

empty()

language construct can only be used on variables, not on other expressions. In particular code like

empty($this->getFriends())

would throw an error. As of PHP 5.5 this becomes valid code. For more info see the RFC.

Getting the fully qualified class name

Status: proposed; Responsible: Ralph Schindler

PHP 5.3 introduced namespaces with the ability to alias classes and namespaces to shorter versions. This does not apply to string class names though:

<?php use Some\Deeply\Nested\Namespace\FooBar; // does not work, because this will try to use the global `FooBar` class $reflection = new ReflectionClass('FooBar'); 

To solve this a new

FooBar::class

syntax is proposed, which returns the fully qualified name of the class:

<?php use Some\Deeply\Nested\Namespace\FooBar; // this works because FooBar::class is resolved to "Some\\Deeply\\Nested\\Namespace\\FooBar" $reflection = new ReflectionClass(FooBar::class); 

For more examples see the RFC.

Parameter skipping

Status: proposed; Responsible: Stas Malyshev

If you have a function accepting multiple optional parameters there is currently no way to change just the last one, leaving all others at their default.

Taking the example from the RFC , if you have a function like the following:

function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }

Then there is no way to set

$report_errors = false

without replicating the other two default values. To solve this a way of skipping parameters is proposed:

create_query("deleted=0", "name", default, default, false);

Personally I’m not particular fond of this proposal. In my eyes code that needs this feature is just badly designed. Functions shouldn’t have 12 optional parameters.

Scalar typehinting

Status: proposed; Responsible: Anthony Ferrara

Scalar typehinting was originally planned to go into 5.4, but never made it due to lack of consensus. For more info on why scalar typehints haven’t made it into PHP yet, see: Scalar typehints are harder than you think.

For PHP 5.5 the discussion has come up again and I think there is a fairly decent proposal for scalar typehints with casting.

It would work by casting the input value to the specified type, but only if the cast can occur without data loss . E.g.

123

,

123.0

,

"123"

would all be valid inputs for an

int

parameter, but

"hallo world"

would not. This matches the behavior of internal functions.

function foo(int $i) { ... } foo(1); // $i = 1 foo(1.0); // $i = 1 foo("1"); // $i = 1 foo("1abc"); // not yet clear, maybe $i = 1 with notice foo(1.5); // not yet clear, maybe $i = 1 with notice foo([]); // error foo("abc"); // error 

Getters and setters

Status: proposed; Responsible: Clint Priest

If you’ve never been a fan of writing all those

getXYZ()

and

setXYZ($value)

methods, then this should be a welcome change for you. The proposal adds a new syntax for defining what should happen when a property is set / read:

<?php class TimePeriod { public $seconds; public $hours { get { return $this->seconds / 3600; } set { $this->seconds = $value * 3600; } } } $timePeriod = new TimePeriod; $timePeriod->hours = 10; var_dump($timePeriod->seconds); // int(36000) var_dump($timePeriod->hours); // int(10) 

There are also some more features like read-only properties. If you want to know more, have a look at the RFC.

Generators

Status: proposed; Responsible: myself

Currently custom iterators are used only rarely, because their implementation requires lots of boilerplate code. Generators solve this issue by providing an easy and boilerplate-free way to create iterators.

For example, this is how you could define the

range

function, but as an iterator:

<?php function *xrange($start, $end, $step = 1) { for ($i = $start; $i < $end; $i += $step) { yield $i; } } foreach (xrange(10, 20) as $i) { // ... } 

The above

xrange

function has the same behavior as the builtin

range

function with one difference: Instead of returning an array with all the values, it returns an iterator which generates the values on-the-fly.

For more in-depth introduction into the topic see the RFC.

List comprehensions and generator expressions

Status: proposed; Responsible: myself

List comprehensions provide a simple way to do small operations on arrays:

$firstNames = [foreach ($users as $user) yield $user->firstName];

The above list comprehension is equivalent to the following code:

$firstNames = []; foreach ($users as $user) { $firstNames[] = $user->firstName; }

It is also possible to filter arrays this way:

$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user];

Generator expressions are similar, but return an iterator (which generates the values on-the-fly) instead of an array.