access child static property

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bilibytes
    New Member
    • Jun 2008
    • 128

    access child static property

    hi,
    i need some help here.
    how can i access a static property of a subclass.

    i have an abstract class which will be extended...

    each extending class will have a static property that will store an array like this:

    Code:
    protected static $_multiLevelArray = array('one'=> [B]array(...)[/B], 'two'=> [B]array(...)[/B])
    protected static $_finalArray;
    each class will have these two properties. But each key of the $_multiLevelArr ay will store diferent arrays (where i have array(...))
    that is why i cannot simpy store the array in the abstract class.

    however i would like to be able to set something like this from the abstract class:
    Code:
    protected static setChildStaticProperty($key){
         child::$_finalArray = child::$_multiLevelArray[$key];
    }
    is this "child::" valid in php5?

    or i should have the same method replicated on each extending class?

    any suggestion?

    cheers
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    Originally posted by bilibytes
    is this "child::" valid in php5?
    no.

    Originally posted by bilibytes
    however i would like to be able to set something like this from the abstract class:
    Code:
    protected static setChildStaticProperty($key){
         child::$_finalArray = child::$_multiLevelArray[$key];
    }
    I think that approach does not make sense in terms of OOP (why should a parent class handle actions, that only occur in the child class?). both properties are not even known to the parent class.

    Comment

    • bilibytes
      New Member
      • Jun 2008
      • 128

      #3
      It was to avoid method duplication, but if it's no good practice...
      thanks for your reply. I will create a method in each subclass.

      Comment

      • Atli
        Recognized Expert Expert
        • Nov 2006
        • 5062

        #4
        This is a tricky question, because static methods and members aren't inherited by child classes. They simply forward calls to them back to their parents.
        And, like you say, there is nothing like the "child" keyword that can be used. (Not that that would be a good solution to this)

        So to create a static method in a parent class that could be used by child classes to edit the members of the child class isn't really a practical possibility (At least not in a way I can see).
        Any calls to the "inherited" static method on the child class would simply be forwarded back to the parent, where it would edit the parent's members.


        But...
        For the sake of it; there is a way to do it.
        You are not going to want to use it, but it does exists.

        Using reflection, you can manipulate static members and methods by their name. (Which will be made obsolete in 5.3, when they allow static members to be referenced by their class names)
        And he Magic Constants give us a way to dynamically detect a class name from within it's methods.

        So, combining those two, you can do:
        [code=php]<?php
        class cParent {
        public static $error;

        public static function setVariable($ke y, $owner=__CLASS_ _) {
        try {
        $refClass = new ReflectionClass ($owner);
        $childStorage = $refClass->getStaticPrope rtyValue("stora ge");
        $refClass->setStaticPrope rtyValue("final ", $childStorage[$key]);
        }
        catch(Reflectio nException $ex) {
        self::$error = $ex->getMessage() ;
        }
        }
        }

        class cChild extends cParent {
        public static $storage = array("First", "Second", "Third");
        public static $final;

        // This override method is not needed, but makes
        // this functionality easier to use.
        // Downside is that you will have to duplicate it in every child.
        public static function setVariable($ke y, $owner=__CLASS_ _) {
        parent::setVari able($key, $owner);
        }
        }

        // By adding the setVariable override
        // to the child class you can do this.
        cChild::setVari able(2);
        echo cChild::$final; // Prints: Three

        // If you leave it out you would have to do:
        cParent::setVar iable(0, "cChild");
        echo cChild::$final; // Prints: One
        ?>[/code]

        Would be much simpler to just copy/paste a simple method into all the child classes:
        [code=php]<?php
        class cParent {
        protected static $storage = array("First", "Second", "Third");
        public static $final;
        public static function setVariable($ke y) {
        self::$final = self::$storage[$key];
        }
        }

        class cChild extends cParent {
        protected static $storage = array("Child's First", "Child's Second", "Child's Third");
        public static $final;
        public static function setVariable($ke y) {
        self::$final = self::$storage[$key];
        }
        }

        class cGrandChild extends cParent {
        protected static $storage = array("Fourth", "Fifth", "Sixth");
        public static $final;
        public static function setVariable($ke y) {
        self::$final = self::$storage[$key];
        }
        }

        cChild::setVari able(2);
        echo cChild::$final;

        cGrandChild::se tVariable(2);
        echo cGrandChild::$f inal;
        ?>[/code]

        Comment

        • bilibytes
          New Member
          • Jun 2008
          • 128

          #5
          very good answer! I appreciate.

          My design is in the border of many solutions but none of them is "very" satisfying.

          Because i have:
          -a) many subclasses
          -b) many instances per subclass
          -c) a method with a big body

          which means that the solutions which would consist of:
          -1) duplicating the static method in each subclass is not a good solution ----->
          a)because there are many subclasses.
          -2) not setting the properties as static to allow the parent to edit its child properties is not a good solution ----> b)because there are many instances per subclass, and it would imply a lot of duplicated data

          between the two options, I would choose 1) because i have less subclasses than the sum of all subclasses' instances. The properties will not be duplicated. However b) the method is quite big so i should consider the difference of bytes between the sum of duplicated properties and the sum of duplicated methods.

          but i won't do that calculation!!! lol

          i'll stick to 1)

          thank you very much

          i learnt a bit of "reflection " in the way.

          Comment

          • bilibytes
            New Member
            • Jun 2008
            • 128

            #6
            Late Static Binding

            Originally posted by Dormilich
            I think that approach does not make sense in terms of OOP (why should a parent class handle actions, that only occur in the child class?). both properties are not even known to the parent class.
            I discovered last week that PHP 6 has a solution to my problem.

            They call it "Late Static Binding" and instead of "child" as i mentioned in my first post, you access the descendant static members with the word "static".

            Based on my example:

            i have an abstract class which will be extended...

            each extending class will have a static property that will store an array like this:

            Code:
            protected static $_multiLevelArray = array('one'=> array(...), 'two'=> array(...))
            protected static $_finalArray;
            each class will have these two properties. But each key of the $_multiLevelArr ay will store diferent arrays (where i have array(...))
            that is why i cannot simpy store the array in the abstract class.

            however i would like to be able to set something like this from the abstract class:
            Code:
            protected static setChildStaticProperty($key){
                 child::$_finalArray = child::$_multiLevelArray[$key];
            }
            instead of this:
            Code:
            protected static setChildStaticProperty($key){
                 child::$_finalArray = child::$_multiLevelArray[$key];
            }
            you would access it like this:
            Code:
            protected static setChildStaticProperty($key){
                [B]static[/B]::$_finalArray = [B]static[/B]::$_multiLevelArray[$key];
            }
            I'm impatient to try it!

            cheers.

            Comment

            • Atli
              Recognized Expert Expert
              • Nov 2006
              • 5062

              #7
              Nice. I'm going to have to look into that. Haven't really gone over the new features in PHP6. (Only just started thinking about PHP5.3)

              You can try it out tho.
              They release Windows Binaries of the source snapshots for all the PHP versions under development. (6.0, 5.3 and 5.2)

              Expect them to be buggy tho :)

              Comment

              • Markus
                Recognized Expert Expert
                • Jun 2007
                • 6092

                #8
                Originally posted by Atli
                Nice. I'm going to have to look into that. Haven't really gone over the new features in PHP6. (Only just started thinking about PHP5.3)

                You can try it out tho.
                They release Windows Binaries of the source snapshots for all the PHP versions under development. (6.0, 5.3 and 5.2)

                Expect them to be buggy tho :)
                Now I just gotta wrestle with Windows so it plays nice and upgrades smoothly -.-

                Comment

                • Atli
                  Recognized Expert Expert
                  • Nov 2006
                  • 5062

                  #9
                  If you get Windows to play nice, please let me know.
                  I always prefer knowing about impending apocalypses before hand :)

                  Comment

                  • Markus
                    Recognized Expert Expert
                    • Jun 2007
                    • 6092

                    #10
                    Originally posted by Atli
                    If you get Windows to play nice, please let me know.
                    I always prefer knowing about impending apocalypses before hand :)
                    I tried for 15 minutes... nada. Apache keeps complaining of not finding a module, blah blah. I wish I could get Ubuntu connected to the net on this damn computer; it'd make things much, much easier.

                    Comment

                    • Atli
                      Recognized Expert Expert
                      • Nov 2006
                      • 5062

                      #11
                      Yea, I couldn't get it to work either. Not in the mood to troubleshoot a snapshot version :P
                      I'll try again tomorrow. Maybe somebody will have fixed whatever is causing it by then. (I would try, but I wouldn't even know where to start.)

                      Ubuntu doesn't connect to the net on your PC?
                      That's odd... Graphics problems I'd expect, but not network issues.

                      Comment

                      • Markus
                        Recognized Expert Expert
                        • Jun 2007
                        • 6092

                        #12
                        Originally posted by Atli
                        Yea, I couldn't get it to work either. Not in the mood to troubleshoot a snapshot version :P
                        I'll try again tomorrow. Maybe somebody will have fixed whatever is causing it by then. (I would try, but I wouldn't even know where to start.)

                        Ubuntu doesn't connect to the net on your PC?
                        That's odd... Graphics problems I'd expect, but not network issues.
                        I'll give it (PHP 6) another shot later. I suppose I could just run it from the command line; that would not require little configuration, I guess.

                        Everything works when I install Linux, apart from the internet. I think I tried for maybe 5+ hours trying to get it to run, constantly rebooting into Vista to find extra information and then back into Ubuntu to apply all the small rays of hope I had found. All the no avail though. I'm installing Ubuntu again, actually, as we speak. I fancy giving it another shot.

                        Comment

                        • Atli
                          Recognized Expert Expert
                          • Nov 2006
                          • 5062

                          #13
                          You could always just use VirtualBox.
                          Very good for testing out this sort of stuff.

                          I'm actually compiling PHP6 on Ubuntu via Windows7+Virtua lBox atm :P

                          Comment

                          Working...