syntax I miss in PHP

Here are some syntax additions I’d like to see in PHP:

1. a()()
When a() returns a callable object (such as a closure) the second set of brackets would call it. That would allow to write some neat code. I am working on a patch for that but it’s a bit harder than I thought.

2. a()[$x]
This is kind of obvious, I wonder why don’t we have it? Should also be able to be an lvalue, though unless a() returns by-ref or return value is an object it may not do what one wanted.

3. foo(1,2,,4)
Syntax to skip a parameter in a call, which then will be substituted with the default as defined by the function. Would come handy if you have function with many defaults, and you only want to change the last one but leave the rest alone – now you don’t have to look up the actual default’s values.

4. foo(“a” => 1, “c” => 2, “d” => 4)
Named parameters call, which allows you to specify parameters in arbitrary order by name. Would allow to build nice APIs which could accept wider ranges of parameters without resorting to using arrays. That’d also imply call_user_func_array() would accept named arguments.
The problem here might be what to do with unknown arguments – i.e. ones that the function did not expect. I guess the function could just ignore them.

5. $a = ["a", "b" => "c"];
I’d really like to have short array syntax. Yes, I know it was rejected so many times already, but I still like it.

About these ads

64 thoughts on “syntax I miss in PHP

  1. You know what I would like to have? Correct variable types! int $var, char $var and all the other stuff! You know why? Because the Type Juggling of PHP SUCKS!!!

      • I totally agree. 99% of the time the “dreaded” type juggling does what you want. Occasionally it doesn’t, but I love not having to worry whether a numeric string from a form is a string or a float, etc. I believe type-hinting is coming, but I’m not really missing it.

        Stanislav:
        Any idea, though, why PHP 5.3.x forbade using func_get/num_args() in an include within a function? My PAR() workaround to enable named and skipped parameters broke with this change, and now requires reflection or an ugly stack trace to get the current scope’s vars.

        Very annoying. I looked at the code:

        It looks like they did it on purpose:

        if (p<EG(argument_stack).elements) {
        zend_error(E_WARNING, "func_get_args(): Called from the global scope – no function context");
        RETURN_FALSE;
        }

        Totally pointless? :(

    • Maybe you suck at type casting? :P

      Seriously though, there was a heated debate (on php internals list) on primitive type hinting for function arguments, and given what was said there, don’t expect anything like that in PHP ever ;) If anything, you can wish for SplTypes extension to be finished.

  2. i would love to have all of these features … especially “named parameters” would be a huge benefit for PHP. imo,

  3. Additional to a()(), it would be awesome to have SOME_DEFINE()
    Then it would be possible to hook system functions (in theory anyway), like this:


    Define('mail','_mail_hook');

    function _mail_hook($to, $subject, $message, $headers = false, $params = false)
    {
    $headers .= "From: somename ";
    mail($to, $subject, $message, $headers, $params);
    }

    mail(...);

  4. Nice post, you activated a few minds..

    Something I’d really like:

    $blog_posts = new blogManager()->getPosts();

    This would spare a lot of temporary variables, and avoid a couple of unnecessary Singletons.

    • This is actually doable by wrapping object creation into an function, as easy as this:

      function foo(){
      return new foo();
      }
      class foo{
      public function bar(){
      return ‘whatever’;
      }
      }

      //you can drop the “new”
      $something = foo()->bar();
      echo $something; //whatever

  5. You can also use proxy pattern to wrap all requests to an object, but it involves another layer. Also, using __call all your methods must be private or protected, so you can’t implement an interface this way…

  6. It would be cool if there could be another type of variable/method scope in a class (after public,private and protected) called for example ‘secured’ every variable/method declared with secured before access a magic (user defined) function would be called which would check if the access to the variable/method is permitted, this could be very handy ;).

    Usage example

    class Example {
       secured $foo;
       secured $bar;
       public function __isPermitted($name,$arguments,$caller){
            if(//some logic ){
                 return true;
            }
            return false;
       }
    }
    
    $ex = new Example();
    $var = $ex->foo;
    
    //if isPermitted returns false
    FATAL_ERROR: access denied
    
    
    
    • actually that’s kind of pointless.

      You can just use the __get() and __set() magic methods to implement this. Just put your ‘secured’ properties in an array set to be a private property.

      class Example {
         private $properties;
      
         public function __get($name){
              if(//some logic ){
                   return $this->properties[$name];
              }
              trigger_error('access denied',E_USER_FATAL);
              return;
         }
      }
      
      $ex = new Example();
      $var = $ex->foo;
      //if your property isn't accessible you'll get a fatal error
      

      You can do the same thing with method calls using __call()

  7. this would be also nice and posible, for arrays and strings (python style)
    //$a = [0,1,2,3,4,5,6,7]
    $a[3] == 3
    $a[-1] == 7
    $a[2:4] == [2, 3]
    $a[1:] == [1, 2, 3, 4, 5, 6, 7]
    $a[:3] == [0, 1, 2]
    $a[::2] == [0, 2, 4, 6] # Only even numbers.
    $a[::-1] = [7, 6, 5, 4, 3 , 2, 1, 0] # Reverse order.

  8. 1, 2, 3 would be so very, very nice to see in PHP. After using 1 & 2 in JS you’re just feeling sad that PHP doesn’t allow for it.

    Thanks for some good suggestions :)

    Regards
    Fake

  9. 1. a()()
    I agree with 1, but I also agree that it would lead to a world of pain for people to debug and just generally read. You can do object chaining, which I use every single day. $foo()->bar();

    2. a()[$x]
    YES! This is something I’ve always wanted to have in PHP. Javascript can do it… and I love it. even if you can’t set a value, just retrieving a value is nice.

    3. foo(1,2,,4)
    yeah there’s no need for this… this is how it’s done foo(1,2,null,4). no need to do anything else.

    4. foo(”a” => 1, “c” => 2, “d” => 4)
    This would be pretty cool to have, and if the parameter didn’t exist on the function signature it could just make the variables available for use within the scope of the function. a better syntax would be something like foo(‘a’:1,’c’:2,’d’:4); mostly for readability.

    5. $a = ["a", "b" => "c"];
    YES! I’d like to have this too, but not that important, array() isn’t too hard to type.

    Alot of people poopoo’d #4 because it’s kind of hard to read. But, you must remember, PHP doesn’t care about whitespace. so you could write the function call like this:

    foo(
    ”a” => 1,
    “c” => 2,
    “d” => 4
    );

  10. foo(1,2,,4) is not good feature to ask although it may seem good idea. I am 100% sure that this feature will get same abused as it got in VBA. Developers will happily call methods with long argument list this way as they have tools that make those calls convenient.

    I think named parameters is way better thing to have. :)

  11. I’d like the possibility to call a method on the same line as creating the object:

    $result = new Object()->theMethod( $a, $b );

    The only way I can do this now is with a factory method:

    class Object
    {
    public static function create()
    {
    return new Object();
    }
    }

    $result = Object::create()->theMethod();

    Well it’s clear you need to store the object somewhere, otherwise you would just use a static method or function.
    But it would make sense if all the mothods allways return the same object:

    $result = new Object()->populate()->merge( new Object()->populate() );

    • Agreed, I’ve come across this siutation more than often.
      This is also a spot where php falls short in comparison with the other OOP-languages.

      Good one! :D

  12. Pingback: PHP 10.0 Blog: syntax I miss in PHP | PHP

  13. Pingback: PHP 10.0 Blog: syntax I miss in PHP | Webs Developer

  14. What about
    a( {'a'=1, 'b'=2} );
    Or even better
    a( { $a = 1, $b = 2 } );

    -> this is in place object generation like in javascript (all properties are public, and can only be atomic)


    $options = { $a = 1, $b = 2 };
    a( $options );

    In PHP these objects could also be ArrayObjects ofcourse. Using function calls is always slower then using language constructs (eg: a(array(‘a’=>1,’b’=>2))).

    This also holds for


    if($a IN [1,2,3]); // Array
    if($a IN {$a=1,$b=2}); // Object
    if(in_array($a,array(1,2,3)));
    if(property_exists($a, new StdClass()));

    and same with BETWEEN

    But arrays are more or less fine as they are in PHP, I would concentrate on the object notation.

  15. Hi,
    Yes I like those enhancements. But my favorite is ‘IN’ like Ricardo explained in a previous post.
    IN (or even better the superset ‘junctions’) is something you use over and over again when you have the possiblility.

  16. 1. a()() – Simply a bad programing practice. Not transparent and requires additional comments and jumping throught the code to understand what it actualy does. Hopefuly it wont be implemented.

    2. a()[$x] – Prety much the same as above. a()[3]()()[4] looks nice but its just one big mess.

    3. foo(1,2,,4) – Function should have as little parameters as possible. 0 is perfect, 1 is nice, 2 is ok, more then 2 means that your coding is really bad and your function does way to many things. You can use single array parameter for such case, where order of keys is not important. functionWithManyParams(array(‘param1′ => 1, ‘param3′ => 3))

    4. foo(”a” => 1, “c” => 2, “d” => 4) – Same as above. Use an array as single parameter to a function call. functionWithManyParams(array(‘param1′ => 1, ‘param3′ => 3)).

    5. $a = ["a", "b" => "c"] – Could be useful.

    6. if ($i IN (3, 6, 8)) – if (in($i, 3, 6, 8)) – Only single good point i see here is that you could program php code simply by learning MySQL.
    7. if ($i BEETWEEN 2 AND 15) – if(beetween($i, 2, 15)) – Same as above

    Hopefuly none of above will ever get implemented, php is already enough of a mess.

    • Your comments regarding 1 and 2 are not right.
      Since functions are first-class they can be passed on, they can be wrapped in other functions, they can be stacked etc.
      So it is quite valid use case to get a function back and call it immediately. This is good for lazy evaluation, factories etc.

      a()[3]()()[4] is quite a contrived example isn’t it? You need to work really hard to get into such an situation. And if you are in that situation you might consider applying for a different profession.
      With every tool you can make ugly things.

      I’ve many times come across the situation that I am only interested in the single element of some query result.


      $sth = $dbh->prepare("SELECT count(*) FROM fruit");
      $sth->execute();
      echo $sth->fetchAll()[0];

      Open your mind for functional programming!! :D

      • Hey Ace, yeah of course I know that. But this approach will pose problems with buffered queries and pdo/mysql.

        Also, think about other examples. It is so silly to have

        $resultInAnArray = $obj->returnSomething();
        $yeahRealResult = $resultInAnArray[0]

        blegh.

        Why object against a proposal that repairs the array accessor? Why so afraid?

        If you know other languages, you would have known that this simply is a bug, nothing more, nothing less. Please don’t defend bugs, it makes php the risé of programming languages and I’m so tired of it.

        best regards

    • These are pretty fast-and-loose comments.

      All of these syntaxes are useful. Some more than others. a()[$x] is probably more useful than a()(). I could do without the latter, but both have irked me a few times.

      (3) is implemented by C#, and Microsoft thought about it a lot. Same re: (4). Almost every language except PHP has a short array grammar.

      I’ve implemented IN as:

      function EQ()
      {
      $args = func_get_args();
      return Utils::inArray($args[0], array_slice($args, 1));
      }

      The same could be done for between. Functions sometimes can make up for a lack of an operator. Sure it’s prefix notation, but whatever :)

  17. About points 1,2,3 I see the point, but I guess that someone would then abuse that, I could get a big headache working on something like

    1. $a = foo()()()()()()()()();

    2. $b = foo()()()()[$x][$y][$z];

    3. foo(,,,,1,,,,2,,,,,,,4,,);

    Obviously a bad programmer could write awful code using just if…else

    if (cond1) if (cond2) if (cond3) else else else foo();

    About point 4 and 5 I completely agree and just posted something playing with php 5.3. Hope for something new with php 7 ;-)

  18. 3. foo(1,2,,4) is something i thought about more then one time, would be very handy but maybe not that good for code readability.

    Also i like the idea of Zé Ricardo:

    $i IN (3, 6, 8 )

    but i think it should be still enclosed in a if-statement. MySQL-Syntax is similar. A BETWEEN syntax could be handy too.

    if( $i BETWEEN 2 AND 15 )

    • Okay let’s not get out of hand with the BETWEEN/IN crap. ‘IN’ I can see as actually being useful, though you can replicate it with in_array already. ‘BETWEEN’? Just extra cruft. Type out the extra… 1 character. Or the exact same if you use ‘&&’.

      if ($i >= 2 AND $i <= 15)
      if ($i BETWEEN 2 AND 15)
      

      Just my two cents, though. This isn’t SQL ;)

  19. Pingback: blog.about-orkan.de » Blog Archive » Syntaxwünsche

    • You could just do

      if (in_array($i, array(3, 6, 8)))

      While it’s not as clean looking as $i IN (3, 6, 8) it’s a hell of a lot cleaner looking than

      if ($i == 3 || $i == 6 || $i == 8)

      • A better way

        function EQ() {
        $args = func_get_args();
        return in_array($args[0], array_slice($args, 1));
        }

        if EQ($value, 1, 2, 3) { // do stuff if it’s 1 or 2 or 3 }

        Done.

    • 1. Yes, I did, but that’s not the point
      2. It sounds like me saying “I wish my friend Joe stopped wearing that weird hat” and getting response “have you considered being friends with Steven instead?”

  20. 2. I have a patch whipped up for this, the problem is behavior for assignment and then we have references.

    function a() { return array('a', 'b', 'c'); }
    a()[0] = 'd';

    • So why is that a problem.

      
      function a() { 
      	return array('a', 'b', 'c'); 
      }
      a()[0] = 'd';
      

      It is useles, because you are changing a datastructure, but you can never access the structure again.
      PHP has decided to treat functions as first-class citizens too since version 5.3—and that is really applaudable—but this means that your treatment shouldn’t be half-baked, i.e. you need to support 1 and 2 also.

      These are long-waited improvements. If you are in the position to repair php in that respect, I would owe you a lot!

      • Its more ;) but still most of the things proposed are in Python.
        Named parameters are very handy. You can specify only that you need and make the code more clearer what you’re passing if you use meaningful names of course.

  21. Personally if I had the shortened array syntax I could do without named parameters.

    I already use arrays like this quite often but it’s a bit clunky.

  22. you can fake the behavior of 5 by just wrapping it in a json_decode() call. not that cool, but it works.

    1,2,3 and 5 would come in handy from time to time, but 4 will lead to lots of unreadable code.

  23. This would certainly be cool. Can’t really imagine that point 5 was rejected.

    But I think the named parameter call should be something like this: foo(a=1, c=2, d=4)

  24. The syntax on the list i miss the most is the named parameter call. I would mainly use it to juggle with the parameter order but i also thing it comes with a another catch than you already mentioned.

    How is a mix of named and unnamed parameters going to get treated? will the unnamed parameters be handled in the order as they appear in the function definition? Will the order of the parameters in the function call determine the parameter handling? Or will it be up to the programmer to handle the unnamed parameters?

  25. Nice!

    I would absolutely love if we got those syntax in next versions… I hate to use Array() constructor when calling a function with array parameter…

  26. 4) Why not: foo(array(“a” => 1, “c” => 2, “d” => 4)) ? Sure, not as elegant as what you proposed, but works the same way…

    • Because arrays need special treatment. That’s like having the language only support calls with one argument. Sure you can use arrays, etc. and overcome this limitation – but it’d be nicer if you hadn’t to.

Comments are closed.