Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123

    [5.4a1!!!] Traits Syntax


    PHP 5.4a1 was released a couple of weeks ago and looks really good, especially with the removal of some legacy features.

    One really interesting feature is traits.

    Unfortunately, I've not yet been able to get an installation up and running yet

    So, has anyone got an installation of 5.4a1 up and running? and can anyone tell me if the traits syntax is as described here https://wiki.php.net/rfc/traits?
    Last edited by Northie; July 13th, 2011 at 10:53 AM. Reason: typos
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  2. #2
  3. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,958
    Rep Power
    9397
    It doesn't seem fully supported (at least not the Win32 build of rev. 313197).
    - No "instead" (Conflict Resolution)
    - No visibility overriding in the derived class (Visibility)
    - No aliasing or renaming of specific methods (Aliasing vs. Renaming)

    Everything else works.
    PHP Code:
    <?php

    trait Ability 
    {
        public abstract function 
    getName();
    }

    trait Burnable {
        use 
    Ability;
        public function 
    burn() { echo "Burned this "$this->getName(), "\n"; }
    }
    trait Cutable {
        use 
    Ability;
        public function 
    cut() { echo "Cut this "$this->getName(), "\n"; }
    }

    class 
    Forest {
        use 
    Burnable;
        public function 
    getName() { return "Forest"; }
    }
    class 
    Paper {
        use 
    BurnableCutable;
        public function 
    getName() { return "Paper"; }
    }

    $objects = array(
        new 
    Forest(),
        new 
    Paper()
    );
    foreach (
    $objects as $o) {
        
    // downside to resolving traits at compile-time: no inheritance
        //if ($o instanceof Burnable) $o->burn();
        //if ($o instanceof Cutable) $o->cut();
    }

    // one alternative is, of course, reflection

    function instanceof_trait($o$trait) {
        
    $rc = new ReflectionClass($o);
        return 
    in_array($trait$rc->getTraitNames());
    }

    foreach (
    $objects as $o) {
        if (
    instanceof_trait($oBurnable)) $o->burn();

        
    // magic? nope.
        
    error_reporting(E_ALL);
        if (
    instanceof_trait($oCutable)) $o->cut();
        
    error_reporting(E_ALL & ~E_NOTICE);
    }
    /*
    Burned this Forest

    Notice: Use of undefined constant Cutable - assumed 'Cutable'...
    Burned this Paper

    Notice: Use of undefined constant Cutable - assumed 'Cutable'...
    Cut this Paper
    */

    // but a better way would be to use interfaces

    interface IBurnable {
        public function 
    burn();
    }
    interface 
    ICutable {
        public function 
    cut();
    }

    class 
    Wire implements ICutable {
        use 
    Cutable;
        public function 
    getName() { return "Wire"; }
    }
    class 
    Wood implements IBurnableICutable {
        use 
    BurnableCutable;
        public function 
    getName() { return "Wood"; }
    }

    // note that you cannot put interfaces on traits
    // with interfaces you can use IBurnable/ICutable as normal interfaces,
    // then Burnable/Cutable as "default" implementations

    $objects[] = new Wire();
    $objects[] = new Wood();
    foreach (
    $objects as $o) {
        if (
    $o instanceof IBurnable$o->burn();
        if (
    $o instanceof ICutable$o->cut();
    }
    /*
    Cut this Wire
    Burned this Wood
    Cut this Wood
    */
    // (remember that the first two objects didn't use the IBurnable/ICutable interfaces)

    ?>
    And a more realistic example:
    PHP Code:
    <?php

    interface IIdentifiable {
        public function 
    getID();
    }
    trait TIdentifiable {
        private 
    $id null;
        public function 
    getID() { return $this->id; }
    }


    class 
    User implements IIdentifiable {
        use 
    TIdentifiable;

        public function 
    __construct($id) {
            
    $this->id $id;
        }
    }

    $u = new User(123);
    echo 
    $u->getID(); // 123

    ?>
    If you're wondering about the whole "private $id" thing and how User can access it, remember one important note about traits: they are not classes by themselves. They're class fragments, and PHP will transparently merge it into a destination class. In effect, User is defined with a private $id and public getID() - the fact that it used a trait to do so has absolutely no bearing on anything.
  4. #3
  5. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    Didn't even know a new version was out. I went ahead and made a throw-away vps to test it out on. Not a whole lot of free time so I only installed a basic php, no db or web server or non-standard extensions.

    Not quite sure where i'd use this, but could be interesting.

    If anyone wants to mess with it, I setup an ssh login people can use

    host: l2.aoeex.com
    user: dshed
    pass: php54alpha


    PING and SMTP packets are blocked by the firewall, no being bad allowed.

    Comments on this post

    • ManiacDan agrees
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  6. #4
  7. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,958
    Rep Power
    9397
    Maybe you want to keep the login details out of the post and let people PM you for them?
  8. #5
  9. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    Originally Posted by requinix
    Maybe you want to keep the login details out of the post and let people PM you for them?
    I figure it's throw away, so not that concerned about it. I have absolutely nothing on there worth any value. I setup the firewall to prevent people using it for spam/flood hopefully.

    I'll probably monitor for anything funky, take it down after a few days
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  10. #6
  11. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    Fantastic news

    I'm fed up with boiler plating my php classes and see traits as the big work around for this.

    One thing I will be very interested in is if/how traits can be auto loaded

    will try again at getting an installation sorted out for myself

    Kicken - thanks for the SSH info, but couldn't find where to put any test files - didn't even look like there was a web server on it. Maybe I mis-understood what you were making available, maybe someone trashed it before I got there, maybe I just don't know enough about linux/ubuntu to find what I was looking for
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  12. #7
  13. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    Originally Posted by Northie
    Kicken - thanks for the SSH info, but couldn't find where to put any test files - didn't even look like there was a web server on it. Maybe I mis-understood what you were making available, maybe someone trashed it before I got there, maybe I just don't know enough about linux/ubuntu to find what I was looking for
    I didn't have time to setup a full lamp environment when I built it quick, so I just compiled a basic php.

    You can just store the files in the home directory, anywhere is fine, then use the php cli executable to run them. When I get a spare moment I will try and install apache. Going to be traveling today, so maybe on the first layover if the airport has wifi.
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  14. #8
  15. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    Update: I installed apache on the box. I created a folder called 'public' which serves as the document root. Site can be accessed through http://l2.aoeex.com/
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2007
    Posts
    1,513
    Rep Power
    1424
    Originally Posted by requinix
    - No "instead" (Conflict Resolution)
    It's just named "insteadof"
    Originally Posted by requinix
    - No aliasing or renaming of specific methods (Aliasing vs. Renaming)
    Aliasing seems to work in my tests

    @Northie: Thanks for the test host

    //EDIT: I just saw, I gave credit to the wrong person for the test host. Therefor: Thanks, kicken. And sorry for my messing up.

    Regards, Jens

    Comments on this post

    • requinix agrees
    Last edited by JClasen; July 18th, 2011 at 02:59 PM.
  18. #10
  19. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    My First Test on Kicken's server:



    PHP Code:
    <?php

    session_start
    ();

    trait Singleton {
            private static 
    $instance;

            public static function 
    Load() {
                    if(!isset(
    self::$instance)) {
                            
    $c __CLASS__;
                            
    self::$instance = new $c;
                    }

                    return 
    self::$instance;

            }

    }

    class 
    Test {
            use 
    Singleton;

            private function 
    __construct() {

            }

            public function 
    get($key) {
                    return 
    $_SESSION[$key];
            }

            public function 
    set($key,$val) {
                    
    $_SESSION[$key] = $val;
            }
    }

    Test::Load()->set('Test','Northie');
    Test::Load()->set('Test2','Northie2');

    echo 
    Test::Load()->get('Test');

    print_r($_SESSION);
    resulted in

    Code:
    Fatal error: Cannot instantiate trait Singleton in /home/dshed/public/northie/index.php on line 11
    It appears that the use of __CLASS__ within a trait does not, at present, give the name of the class that calls the trait, but instead has the name of the trait

    As it seems that traits are supposed to be a programmatic replacement for copy-and-paste, then I would expect __CLASS__ to have the name of the calling class and __TRAIT__ to give the name of the trait

    Have I missed something, or would you agree with me?

    EDIT
    ===================

    using a bit of reverse engineering I've got this, which works as expected


    PHP Code:
    trait Singleton {
            private static 
    $instance;

            public static function 
    Load() {

                    if(!isset(
    self::$instance)) {

                            
    $d debug_backtrace();
                            
    $c $d[0]['class'];
                            
    self::$instance = new $c;
                    }

                    return 
    self::$instance;

            }


    You can look at

    http://l2.aoeex.com/northie/index.php and
    http://l2.aoeex.com/northie/test2.php

    And if you have sevrer access then you can see the full code in test2.php
    Last edited by Northie; July 15th, 2011 at 04:41 AM.
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  20. #11
  21. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    Originally Posted by Northie
    As it seems that traits are supposed to be a programmatic replacement for copy-and-paste, then I would expect __CLASS__ to have the name of the calling class and __TRAIT__ to give the name of the trait
    I agree, it would be nice to have the separate constants like that.

    As an alternative, rather than do this:
    Code:
    $c = __CLASS__;
    self::$instance=new $c;
    You can just do this, and it works as expected:
    Code:
    self::$instance = new self;
    ;
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  22. #12
  23. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    PHP Code:
    self::$instance = new self
    Worked,

    Thanks! My debug_backtrace method seemed a little too much like a hack
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  24. #13
  25. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,958
    Rep Power
    9397
    __CLASS__ is a compile-time constant (has a special token and everything) and is always the value of the class it was used in. Thus Singleton and not Test.

    Also, stickied.
  26. #14
  27. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    I've updated the test server to PHP 5.4 Alpha 2. I've also installed mysql and enabled a few more extensions in the php build.

    phpinfo - http://l2.aoeex.com/

    Mysql databases can be setup using the mysql cli tool via SSH. You can create and fully control any database which has a 'dshed' prefix. User/pass for the mysql instance is the same as ssh.

    host: localhost
    user: dshed
    pass: php54alpha


    Have fun!

    Comments on this post

    • JClasen agrees : Thanks - that's what I call service ;)
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  28. #15
  29. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,932
    Rep Power
    4033
    So I did a little browsing around the wiki and other stuff to find out what is in store of 5.4 (and beyond). A few interesting things.

    A few other things I noticed which are already implemented.
    - File upload progress bars are now possible using sessions. Seems a bit complicated, and appears to require session.auto_start=1 in the ini file. It does work in the latest alpha though. http://l2.aoeex.com/kicken/upl/
    - Array callbacks can be called directly (no need for call_user_func). ie, $arr=array($obj, 'method'); $arr(1, 2, 3);
    - Returned arrays can be used without needing a temp variable. ie, $first = explode(' ', 'this is a string')[0];

    And a few things that might make it into 5.4, or perhaps later.
    - There is an RFC to make <?= always available, no longer depends on short_open_tags.
    - There's an RFC to allow easy object-oriented session handling by extending the SessionHandler class. Not sure if this will make it in this round, would be nice.


    And here's a few things on the table, but no decission yet, which I like or find interesting
    - array/object literal syntax (json like)
    - Autoboxing, automatically convert primitives to an object allowing chain method calling (ie, like jquery) support.
    - Various PDO improvements (ie, IN clause handling, better emulation, better consistency)
    - __toString like support for other data types. Being able to cast to an int or bool, etc.
    - extended type hinting
    - conversion of errors to exceptions
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo