Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Short array syntax finally in PHP 5.4 (php.net)
110 points by harisenbon on July 24, 2011 | hide | past | favorite | 78 comments


My big complaint about arrays wasn't declaring them. It was the endless array functions you have to use afterwards.

array_push

array_pop

array_slice

array_shift

array_unshift

array_map

array_key_exists

It kind of feels like they missed the point, saving 5 characters when you declare the array once, ignoring all of the other operations you do afterwards.

And this RFC, simple as it is, took 3.5 years to come to fruition.


I for one would love to see these replaced or complemented by a more OO syntax like:

[1,2,3]->push(..) [3,5,6,]->pop(..) [7,8,9]->map(..)

etc..


(Un)fortunately, depending on how you look at it, "everything is an object" is left out in PHP. I personally agree with having some non-object values (use one of the Spl* classes if you want something like that).


The best step forward for PHP, in my opinion, would be to deprecate all of those fake-namespaced functions, and start treating instances of built-in types as objects. This would also be the chance to fix all the 'needle/haystack, haystack/needle?' type inconsistencies.

The older functions could still exist for backwards compatibility, but people who want to write clean OO code could use the new style. $anArray->map(function(){}), $aString->pos('cow'), etc.

This would be a big step for PHP, and bringing the language closer to parity with Ruby and Python. Not sure how it works with eager type coercion, but JavaScript does it somehow.


Loose typing plus strong OO for basic types is a pretty horrifying cmbination, IMO. What happens if you call $aString->pos() when PHP decides that $aString can be an int because it happens to be holding a string that's composed of numbers?


You mean, PHP decides that $aString has to be coerced to an int, not 'can' be, because it's being used in a function that requires an in to make sense? It doesn't matter if it's a string composed of numbers, either - if needed, any string will be coerced regardless of contents, to 0.

What do ECMAScript interpreters do in such a situation?

In the example you gave, this is dependent upon operator precedence. Presumably any method calls are resolved prior to type coercion. This is how PHP and most languages work anyhow, correct? If you do `$this->do_something() + 20`, the method's return value is used. It doesn't try to turn $this into an integer and then call a method upon it. Same for `bcadd($anObj->meth(),34)`. So... I think that isn't a problem.


PHP does that only if you are trying to use $aString as an int.


While I would love them to bring the array functions more into line with other OO langauges, the entire language is not structured around that concept, so you would be in essence writing a whole new language.

Because almost all the modern PHP frameworks use arrays to pass data, the short-array syntax makes viewing multi-dimensional arrays much easier, and thus will hopefully result in less bugs.

Example:

  $this->link('My Link', array('names'=> array('a', 'b', 'c'), 'values'=> array('a1', 'a2', 'a3') ) );
becomes:

  $this->link('My Link', ['names'=> ['a', 'b', 'c'], 'values'=> ['a1', 'a2', 'a3'] ]);
Just removing the word array makes the code much easier to read, especially when you have deeply nested arrays.


"so you would be in essence writing a whole new language"

After having to use PHP for a while, it's no coincidence that these days I am using a whole new language.


Not to mention the wonderfully inconsistent count() and sort(). Pah.


Kludgy as it sounds, I just made a list and dict object that was expandable and had more pythonic way of dealing with arrays.


Hard to say that it is simple unless you know the internals.


2 lines in the parser: http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_langua...

The RFC (https://wiki.php.net/rfc/shortsyntaxforarrays) was actually rejected by the developers, I think it's only really been put in to appease large userland pressure. Find it rather amusing that a 2 change to the parser for an alias would be rejected on 'maintainability' grounds.


The voting results on the RFC page is from 2008 when it was rejected. The recent vote that decided its inclusion was here: https://wiki.php.net/todo/php54/vote. I think it had pretty solid support from core developers as well as userland people this time around.


And why should everyone know or care about language internals?


If someone is making a statement about how "simple" something is to implement, they should know what they're talking about, no?


agreed. this is one of my pet peeves with PHP also.


With the removal of bad legacy features like register_globals, magic_quotes_gpc, and safe_mode combined with new features like array de-referencing and traits, I'm really excited for PHP 5.4. :)

For anyone who's curious, here's a list of the changes in 5.4 alpha 1: http://www.php.net/releases/NEWS_5_4_0_alpha1.txt


Now if only when a function returns an array we needn't a variable...

  function boo(){
  return array(1,2,3)
  }

  echo boo()[1];



Thanks!


It's not quite what you're asking for, but there is a way to handle array results from functions where you know the number of elements that will be returned.

For example:

// explode splits the string on the provided boundary

// and returns an array containing each segment.

// using list() we can assign the two segments to two

// variables within the same statement

$size = "1000x1000";

list( $width, $height ) = explode( "x", $size );


Ah yes, I love nothing more than functions on the left side of assignment.

Edit: Yes, it is a special form, but its still irregular, and that makes it shitty.


http://www.php.net/manual/en/function.list.php

It's a language construct, not a function.


It's a pretty common feature of a lot of languages (Python, Perl, etc) so it's really not that irregular.


It looks more obviously "language feature" in Perl, Python, and JavaScript, though:

   my ($foo, $bar) = f;
   (foo, bar)      = f()
   var [foo, bar]  = f();


How are any of those examples significantly different from:

   list($foo, $bar) = f();
Given that PHP uses the array() keyword for constructing arrays, it is perfectly symmetrical. My IDE highlights the list() keyword just the same as all the other keywords.


`list` is a special form, not a function.


Especially since you can do $a->b->c->d


I don't see how this will ever be useful. The state "echo boo()[1];" assumes you're only ever going to need that one value from the array. The rest of the array is lost. What if the next line in the code needs index 3 from the array? Now you have to run the function again.

I also don't agree that PHP needs constructors to return $this for the same reason. You need to assign the object to a variable so you can reuse it.

  $a = new Foo()->bar();
In this case if I later want to call another method on the Foo instance I have recreate it.


you're assuming that cases don't exist where you won't reuse something. this is a false assumption, e.g. if all I wanted was the creation date of a file: stat("filepath")[7] is a reasonable way to do this in php, but you can't currently.


Just looked through the RFCs... and I'm a bit surprised noone proposed unification of types yet. It seems a bit silly that the resources, objects, arrays, strings are different types at the language level. They could throw out / reorganise a lot of the randomly named functions this way. Just add the proper methods to the actual types and sort out the (haystack, needle) order, underscores or lack of them, etc.


Right, but wouldn't that make PHP code too good looking? The core devs wouldn't allow it ;)

My only wish is that they implement something that evaluates {} to (object)array(). It would come in handy when used with anonymous functions.

Anyway, I am pleased with the new syntax, but sadly, I have to use 5.2 as most of the time I'm working on WordPress projects...


That's great news, finally we can do

  $a = [1, 2, 3];
and it also will make function calls with named parameters much more readable.

Sadly, it will be years before the majority of hosting providers adopt 5.4...


Also arrays of arrays have a much more compact syntax:

  $a = [1 => [4, 5, 6], 2 => [7, 8, 9], 3 => [10, 11, 12]];

  $a = array(1 => array(4, 5, 6), 2 => array(7, 8, 9), 3 => array(10, 11, 12));


Uh, why wouldn't

  [[4, 5, 6], [7, 8, 9], [10, 11, 12]]
work?

I know PHP has a weird history of rebelling against its C-family-syntax heritage, but requiring the syntax in your example would seem specifically calculated just to make developers' lives harder.


Your example would work, but there's a reason you might want different keys. My company's current web app is written in CakePHP, which has a love for arrays. Some of my queries look like this:

  $booking = $this->Booking->find('first', array('conditions' => array('Booking.booking_id' => $id), 'contain' => array('Review', 'Desk' => array('fields' =>
 array('provider_id', 'category_id'), 'Provider' => array('city', 'name'), 'ProviderCategory' => array('fields'   => array('provider_id', 'category_id'), 'DeskCategory' => 'name')))));
It's essentially not readable, but with [] it would work much better, and I still want to give keys to arrays.


As an FYI, you might want to look into custom find methods if you haven't already: https://github.com/josegonzalez/documentation/blob/master/03...


Well, arrays start with index 0, so if the indexes where 1 less it would be the same. Your example would be equivalent to

  [0 => [4, 5, 6], 1 => [7, 8, 9], 2 => [10, 11, 12]]


In addition, you only need to specify the first key to create a one-based array. Indexing will carry on from there.

    [1 => [4, 5, 6], [7, 8, 9], [10, 11, 12]]



> Sadly, it will be years before the majority of hosting providers adopt 5.4...

With VPS hosting as low as $6/month, what reason is there to continue using shared hosting anyways?


Personally, I'm quite happy with VPS and would never go back to shared hosting without a good reason. But if you're writing software that is going to be used on lots of "standard hosting" packages you have to take this kind of delay into account.


Still strikes me as a useless bit of syntactic sugar. Is it really that much work to write array('foo' => 'bar')? As far as I can tell, writing ['foo' => 'bar'] isn't that much shorter in the first place.

sigh Can the PHP devs focus on the real problems now? cough Unicode anyone? Ridiculously inconsistent naming of string and array functions? The woefully incomplete and useless STL? The lack of OO in arrays and strings?


This has been requested by the community for a while now. Synatctic sugar? Definitely. But it's also more.

An actual patch has been submitted for this before, and rejected by the PHP high muck-a-mucks, even though the community desperately wanted it, and the work was already done.

The fact that they finally gave in and included it means not only do we get a nice bit of sugar to sweeten up our programs, but also that maybe the community CAN steer the devs towards issues they care about.

Time will tell.


Agreed. I don't see how this solves a real problem other than just another way to write the code, which, I guess, is the whole point of this update.


> cough Unicode anyone?

Why are you coughing about unicode? It works just fine as long as you use utf-8, and there is little reason not to.


What he meant to say was, "I wish PHP has a 'string' type instead of octet buffers".


Why?


Hey, I've been complaining about PHP's lack of Unicode support forever. Every time I do, though, an apologist comes out of the woodwork to tell me about the mb_*() functions. Apparently the PHP community is quite comfortable not caring about non-ASCII characters.


http://www.slideshare.net/andreizm/the-good-the-bad-and-the-...

Andrei Zmievski has been giving this presentation on what happened to Unicode in PHP. A huge amount of work went into making it happen but it eventually could not continue due to several reasons, including design decisions, lack of contributors & interest in the project.


I brought down a production site by innocently changing some string ops to mb_* string ops. It turns out that they're so slow as to be useless.


I use unicode all the time, and I have not had any trouble. All the php functions are binary safe. If you use utf-8 you won't have any touble.

Do you have actual real issues, or do you just like to complain about things you heard other people say?


My complaint about arrays in PHP is warnings for reading a array member that may not exist, such as when reading a form input that might not be there.

    $foo = $_POST["foo"];
Undefined array key! Oh, no! Tragedy! A crime has been committed! Are you kidding? Just set $foo to undefined and let me deal with the consequences, please?


They're notices, not warnings. They can be disabled via a simple call to the error_reporting function.

I fundamentally disagree with you though. For me, notices are very useful for identifying typos and other coding mistakes that can lead to incorrect behavior.

Consider the following lines of code:

    $user_info = array(
            'id'            => 1,
            'username'      => 'nbpoole',
            'is_guess'      => false
    );

    if (!$user_info['is_guest'])
    {
            echo 'Member stuff';
    }
When I run that script with error_reporting set to E_ALL, I get an "undefined index" notice pointing me to the line where I do the comparison: at that point, I can track down where in my code I misspelled the word guest. Without the notice, I might not immediately realize that the 'is_guest' index was mis-spelled somewhere.


You really wouldn't like Python or even stricter languages such as Scala or java, then. In Python, an attempt to access a nonexistent dictionary key will throw an exception which halts execution if not caught. (similar to calling a nonexistent method or function in PHP, but since PHP doesn't have a well-thought out exception system/std. lib as Python does, you can't catch anything in that situation in PHP).


In Python, if you're expecting a potentially missing key, you can just use dict.get('key') rather than dict['key']. The equivalent in PHP would be something like:

  $val = array_key_exists('key', $dict) ? $dict['key'] : NULL;
Being able to say "I expect a potentially nil value (and am okay with that)" via get() rather than array index is both semantically useful, and far more beautiful than the PHP equivalent.


Sure, or you can catch a KeyError and do something else entirely. I'm aware of all this, just pointing out some differences to the person to whom I replied.

Python's dict.get is a bit like the getOrElse found in Scala. It's quite handy and can be seen as advanced conceptually.

I actually added some code like that to a recent post about PHP here: http://news.ycombinator.com/item?id=2771304


The more so because get() can also take a default value to return if the key is not present in the dict ;-)


I think those warnings are very helpful. They help to develop better and more secure code.

Ever tried to assign a non-existing variable in another language? I think you will get a compile error.

This isn't too hard:

  $foo = isset($_POST["foo"]) ? $_POST["foo"] : null;


This is exactly what PHP does. Yes, it issues you a notice, not a warning, not an exception. And it does not break execution. Just set your error_reporting variable to a lower level, and you won't get the Notice at all.


I think they're helpful too! Just use isset() to check whether variables exist, and you shouldn't get any errors unless you make a mistake (in which case, wouldn't it be nice to know?).


That's good to see, but like many have said, I'd really like to see proper OO stuff like $myArray->pop();

What about short object declaration syntax:

$obj = { param:'blah' };

PHP already has stdClass, so I doubt it would take much of a parser change to implement that.


While I don't use PHP any more, this is still a massive improvement for those that do. Next on the list: Array and String literals as proper objects!


"Perfection is achieved not when there is nothing more to add, but when there is nothing more to cut off."

Adding fancy syntax does not magically transform that crapware to something almost perfect like python3 or ruby (in its way) where these syntactic forms are among foundations of the language and are supported through all basic idioms. ^_^


Looks like they decided NOT to include the scalar type hint. https://wiki.php.net/todo/php54

Even better would be bool/float/int/string/func ref type hinting...


What's the release roadmap and dates for 5.4?



$I $wish $they $would $get $rid $of $prefixing $every $variable $with $a $dollar $sign.


So does => quote the lhs, like Perl? Otherwise, what's the point?


I take it you don't know anything about PHP?


But PHP isn't a transmitted language like javascript, why even bother? It will only make the parser slower?


They're trying to be nicer to the humans. (Though IMO, any human who wanted to be kind to himself would just not use PHP to begin wtih.)


Right now those humans would not choose to start a project in php, but a few years ago there were not too much alternatives. It's not for nothing that the world's second biggest website is written in php.


Do you mean Facebook? They only use PHP for templating and legacy purposes, as far as I understand. Much of their newer code is written in a variety of languages, including C++, Python and Erlang.


In the immortal words, I am not even able rightly to apprehend the kind of confusion of ideas that could provoke a question like that.

Slower parsing, really? Is that what you are worrying about?


Any site that needs real speed will be using APC or eAccelerator anyway, so that's not really relevant.


It's just an additional alias in the grammar, no real measurable slow down given the size of the parser as is.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: