SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    OOP, static variables in methods.

    PHP Code:
    <?php

    class myClass
    {
        function 
    myMethod($in null)
        {
            static 
    $i 0;
            !
    $in or $i++;
            echo 
    $i;
        }
    }

    $class = new myClass();
    $class->myMethod();
    $class->myMethod(1);

    $class2 = new myClass();
    $class2->myMethod();
    $class2->myMethod(1);

    $class3 = new myClass();
    $class3->myMethod();
    $class3->myMethod(1);

    ?>
    That prints:
    Code:
    011223
    Is that the expected bahaviour or a bug? I thought each new object was unique and nothing going on in another object should affect it but this shows that is not the case.

    Any thoughts on this?

  2. #2
    SitePoint Enthusiast
    Join Date
    Jul 2005
    Posts
    86
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is expected behaviour.

    Static variable is tied to the class not the object. You do not get a new instance of the static variable when creating a new object, you are still changing the same value.

  3. #3
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A method belongs to a class, i.e. all instances of the class share the same "instance" of the method. Since static variables are part of the method, they are also shared between all instances.

  4. #4
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This does what you expect:
    PHP Code:
    <?php

    class myClass
    {
        var 
    $i 0;
        function 
    myMethod($in null)
        {
            !
    $in or $this->i++;
            echo 
    $this->i;
        }
    }

    $object = new myClass();
    $object->myMethod();
    $object->myMethod(1);

    $object2 = new myClass();
    $object2->myMethod();
    $object2->myMethod(1);

    $object3 = new myClass();
    $object3->myMethod();
    $object3->myMethod(1);
    ?>

  5. #5
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    This does what you expect:
    Well that's what I had originally but I want to switch due to the big speed advantage of the static variable.

  6. #6
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bokehman View Post
    Well that's what I had originally but I want to switch due to the big speed advantage of the static variable.
    Who told you that non-sense?

  7. #7
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    Who told you that non-sense?
    Just for you, here is some scientific proof: http://bokehman.com/StaticDynamicTest/

  8. #8
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bokehman View Post
    Just for you, here is some scientific proof: http://bokehman.com/StaticDynamicTest/
    The biggest thing you are testing in that test is actually memory usage.

    Here is a far more sensible test for what you're trying to test:
    PHP Code:
    <?php

    class Tester {

        public 
    $var 0;

        public function 
    staticMethod() {
            static 
    $var 0;
            return ++
    $var;
        }

        public function 
    dynamicMethod() {
            return ++
    $this->var;
        }

    }


    $n 100;

    $tester = new Tester();

    $time microtime(true);
    for (
    $x=0$x<$n$x++) {
        
    $tester->dynamicMethod();
    }
    echo 
    "DYNAMIC: " number_format($dynamic = (microtime(true) - $time), 5) . "\n";


    $time microtime(true);
    for (
    $x=0$x<$n$x++) {
        
    $tester->staticMethod();
    }
    echo 
    "STATIC:  " number_format($static = (microtime(true) - $time), 5) . "\n";


    echo 
    'RATIO:   ' number_format($dynamic $static5) . "\n\n";
    When $n = 100:
    Code:
    $ php ./test-static.php
    DYNAMIC: 0.00152
    STATIC:  0.00139
    RATIO:   1.08740
    When $n = 1000:
    Code:
    $ php ./test-static.php
    DYNAMIC: 0.01447
    STATIC:  0.01882
    RATIO:   0.76904
    When $n = 5000:
    Code:
    $ php ./test-static.php
    DYNAMIC: 0.07730
    STATIC:  0.12661
    RATIO:   0.61050
    <.smarter.web.development.>
    PHP Stuff: Plexus | Chocolate (BDD Framework... coming soon)
    Graphite

  9. #9
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bokehman View Post
    Just for you, here is some scientific proof: http://bokehman.com/StaticDynamicTest/
    A static variable is basically a variant of a global variable. This code:
    PHP Code:
    function foo() {
        static 
    $foo 42;
        echo 
    $foo;

    Is another way of expressing this:
    PHP Code:
    $foo 42;
    function 
    foo() {
        global 
    $foo;
        echo 
    $foo;

    The only difference being that $foo is only accessible from within the function foo() in the first case, while in the second case, $foo can be accessed from anywhere.

    The reason for the difference in your example between StaticFunction and DynamicFunction is that in the first case, you're only creating one variable, while in the second example, you're creating 100 variables.
    The first case is going to be significantly faster than the second, but that's because they are doing two different things. You can't compare them to each other.

  10. #10
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape View Post
    Here is a far more sensible test for what you're trying to test
    You are moving the goal posts. I am using the variable as a reference while you are writing to it. Also my variable is a real variable and as my code demonstrates having it static is definitely the way to go otherwise every time I use the function the variable needs to be loaded and unloaded from the RAM.

  11. #11
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    You can't compare them to each other.
    The mechanism is not relevant to me only the outcome. What is fact is adding the word "static" to my function speeds it up 2000 times.

  12. #12
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bokehman View Post
    I thought each new object was unique and nothing going on in another object should affect it (...)
    If you declare a variable static, then there is only one variable for the entire program. If you use a member variable ($this->foo), you get one variable per object.

    Quote Originally Posted by bokehman View Post
    The mechanism is not relevant to me only the outcome.
    Then why did you ask?

  13. #13
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    Then why did you ask?
    I didn't ask about the mechanism, I asked if it was a bug. You then went on to (wrongly) tell me I was talking nonsense when I pointed out there was a speed advantage to using a static variable in read context.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •