[PHP] static variables inside static methods
Hello, everybody. While working with static variables inside static class' methods, I have found this very interesting (at least for me) behavior of PHP. Consider the following class definitions (example #1): class X { public final static function test() { static $i; return ++$i; } } class Y extends X { } By executing this code: echo X::test(); echo Y::test(); // note Y class here one would expect to see 12 as output, but apparently I get 11. That's a bit confusing if you logically assume that static vars are tied to the scope they're defined in. Since this static variable is defined in a specific static method test(), that is NOT overloaded by class Y, in my opinion it shoul've preserved it's value across static calls. Let's look at another example (example #2): class X { public static $x =0; public final static function test() { return ++static::$x; // note static keyword here } } class Y extends X { } If you run this code: echo X::test(); echo Y::test(); you get 12 as output - the expected output. Notice that the ++static::$x expr. is taking advantage of late static binding. Now, if you change body of test() to the following code: public final static function test() { return ++self::$x; } then you also get 12 as output. Is this a bug that static context of $i is not preserved in example #1 or do I misunderstand something? I could not find any hints on this in the PHP documentation. Dmitry.
Re: [PHP] static variables inside static methods
The second case is referencing the varible of the class. Maybe you are right. However, I don't really think that there is a true reference to the class var in example #2. PHP documentation of static keywords does not unambiguously explain behavior of static variables inside methods in example #1. I believe that in example #1 the exactly same instance of function (method) is used irregarding of how you call it (X::test() or Y::test()), therefore I would expect the same static var to be involved in both calls to test(). Is there anybody who can comment on this matter? Thanks. 6 июля 2011 г. 11:05 пользователь Andrew Williams andrew4willi...@gmail.com написал: I think you are confusing scope visibility level of the variable within method and the class. Variable within the method is going to 1 because it was declare within the test method and there no link to the one declared outside the test method. The second case is referencing the varible of the class. 2011/7/6 Дмитрий Степанов dmit...@stepanov.lv Hello, everybody. While working with static variables inside static class' methods, I have found this very interesting (at least for me) behavior of PHP. Consider the following class definitions (example #1): class X { public final static function test() { static $i; return ++$i; } } class Y extends X { } By executing this code: echo X::test(); echo Y::test(); // note Y class here one would expect to see 12 as output, but apparently I get 11. That's a bit confusing if you logically assume that static vars are tied to the scope they're defined in. Since this static variable is defined in a specific static method test(), that is NOT overloaded by class Y, in my opinion it shoul've preserved it's value across static calls. Let's look at another example (example #2): class X { public static $x =0; public final static function test() { return ++static::$x; // note static keyword here } } class Y extends X { } If you run this code: echo X::test(); echo Y::test(); you get 12 as output - the expected output. Notice that the ++static::$x expr. is taking advantage of late static binding. Now, if you change body of test() to the following code: public final static function test() { return ++self::$x; } then you also get 12 as output. Is this a bug that static context of $i is not preserved in example #1 or do I misunderstand something? I could not find any hints on this in the PHP documentation. Dmitry. -- Dmitry Stepanov E-mail: dmit...@stepanov.lv Home: http://www.stepanov.lv Skype: ninzjoo -- Dmitry Stepanov E-mail: dmit...@stepanov.lv Home: http://www.stepanov.lv Skype: ninzjoo
[PHP] Import symbol table into function' scope.
Hello, everybody. Consider the following code: class DB { public function query( $sql) { // ... some magic of DB querying } } class DBReader { public $DB;// instance of DB public function __call( $methodName, $args) { return call_user_func_array( array( $this, $methodName), $args); } protected function readSomething() { $sql ='SELECT ...'; $result =$this-DB-query( $sql); } protected function readSomethingElse() { // ... very similar to DBReader::readSomething() } // + other methods like DBReader::readSomething() } If you take a look at DBReader::readSomething(), you'll see that I am referencing database object and performing query via $this-DB-query(). If you do a lot of database queries, your code becomes bloated with $this-DB-... and usually gets not so well readable (at least for me). Since I have a lot of methods, that are similar to DBReader::readSomething() (which perform DB queries), I would like to optimize readability of the DB querying code. Right now I would do it in the following way: // 1) reference database object inside the method $DB =$this-DB; // 2) do whatever I need with the DB $DB-query( $sql); $DB-numRows(); // ... or whatever This way the code looks nicer and is, in fact, shorter. So I wonder if there is any way to import scope (symbol table) into the method DBReader::readSomething()? By importing the variables into the function body, I would like to avoid the 1) reference database object inside the method step so that $DB becomes instantly available: protected function readSomething() { $sql ='SELECT ...'; $result =$DB-query( $sql);// like this } AFAIK, there is no such call_user_func* function that would allow importing of symbol table into the called fn. What I would expect to be possible: public function __call( $methodName, $args) { $scope =array( 'DB' =$this-DB); return call_user_func_array( array( $this, $methodName), $args, $scope);// note the $scope array, that is being passed here } The effect of such call to call_user_func_array() I would expect to be equivalent with same as regular call to call_user_func_array(), but with additional call to extract( $scope, EXTR_REFS) right at the top of the function's body. Does anybody have some ideas how I can get this working? If there is no way to get this working with current PHP feature set, then I would like to propose to extend call_user_func_array() to support $scope argument. What do you think about this? P.S.: don't ask why I don't just simply make DBReader::readSomething() to be public method. That's not the case. P.S.: a very similar scope importing technique I am using with the PHP template files I use in my web projects. As you know, include() is, literally, injecting code from the file into the current scope, thus making current symbol available to the included code: index.php: $x =5; $y =10; include(chart.php); chart.php: echo $x .',' .$y; After processing index.php, the output would be 5,10. P.S.: closures are capable of importing scope via use() statement: $x =5; $y =10; $closure =function() use( $x, $y) { echo $x .',' .$y; }; $closure();// would give output 5,10 so I suppose that technically importing scope is not a big deal from the PHP internals perspective. Dmitry.