Late Static Binding – Changes to parent

If you have been following the PHP internals list for the last few weeks you probably have seen a discussion concerning the current behaviour of late static binding (lsb) and how it seems to be unnecessarily limited when it comes to inheritance. I first posted about the limitations of the current lsb implementation as it relates to inheritance in Late Static Binding…Sorta. It has since been revived in this thread on the internals mailing list: RE: [PHP-DEV] late static binding php6.

I won’t rehash all of the arguments as you can quite easily find out my full thoughts by previous posts and on that mailing list thread. To put it simply I feel that somehow there needs to be a way to call methods in a parent class without losing the ability to reference back to the original called static.

<?php

class A
{
    public static function test()
    {
        echo get_called_class(),"\n";
    }
}

class B
{
    public static function test()
    {
        //do additional work ...
        parent::test()
    }
}

B::test(); //outputs B

?>

This (or anything like it) is currently impossible in the current lsb implementation. I spent a bit of my extended weekend preparing three different patches to work around this problem. I just now sent them to the internals mailing list so they can be discussed. You can view this email and get a summary of the patches by viewing my recent php-dev posting.

All of the above patches are against 5.3. I was having some strange problems with the test suite in php6 so I moved onto php5.3 so I could make sure things weren’t breaking on me :P. If anyone reading this feels as strongly as I do that there should be a way to do this I hope to encourage you to make your thoughts known on PHP-Dev.

Share
This entry was posted in PHP. Bookmark the permalink.

5 Responses to Late Static Binding – Changes to parent

  1. Mitchell says:

    Sweet. This would make life simpler. Kudos.

  2. sf says:

    It is good information :)

  3. Anonymous says:

    Cannot access parent:: when current class scope has no parent

  4. prezzio says:

    Here is some ugly workaround in PHP.

    class O
    {
    final protected static function parent( $foo )
    {
    // getting method info
    $c = new ReflectionClass( get_called_class() );
    $m = new ReflectionMethod( $c->getParentClass()->getName(), $foo );

    // getting method location
    $start = $m->getStartLine();
    $end = $m->getEndLine();

    // gettig a code – it will fail for oneliner :P
    $code = trim( implode( “\n”, array_slice( file( $m->getFileName() ), $start, $end – $start ) ) );

    // checking if there is block begin at the beggining
    if ( $code[0] != ‘{‘ )
    $code = ‘{‘ . $code;

    // managing args
    $func_get_args = func_get_args();
    unset( $func_get_args[0] );

    $func_get_args = array_values( $func_get_args );

    foreach( $m->getParameters() as $key => $val )
    {
    if ( isset( $func_get_args[$key] ) )
    ${$val->getName()} = $func_get_args[$key];
    }

    // running code
    eval( $code );
    }
    }

    class A extends O
    {
    static public $x = ‘aaa’;

    public static function test( $a = ‘aa’, $x = ‘sas’)
    {
    echo get_called_class(); // works as supposed! writes B for B :: test();

    echo “\n

    \n”;
    var_dump( func_get_args() ); // wrong.. first argument is method name!
    echo “\n

    \n”;
    var_dump( $func_get_args ); // correct!

    echo static :: $x; // ok

    // echo self :: $x; // not ok; (wants O :: $x)

    echo A :: $x; // ok
    }
    }

    class B extends A
    {
    static public $x = ‘bbb’;

    public static function test()
    {
    // code of test() ran as parent(); but sees the correct class name
    // executed almost like parent :: test( ‘a’, new O() ); but in B-class context
    static :: parent( ‘test’, ‘a’, new O() );
    }
    }

    B::test(); //outputs B

  5. Adam says:

    So many things that need PHP needs to improve on!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>