|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
On 10/18/07, Joshua Bacher <bacher@bash-it.de> wrote:
> > Hi all, > > i faced the following problem. > > i am using a API. This API has a class that looks like following: > <snip> > class foo{ > public function bar(){ > static $foobar=false; > if ($foobar === False){ > $foobar='FUBeyondAllR'; > echo "$foobar\n"; > }else{echo "already defined\n";} > } > } > </snip> > if you call the method of this class twice it will first print > FUBeyondAllR and at the second time it will echo 'already defined'. > (examples at the next and the last snippet) > > thats fine but what if you have some processing in the first if case? it > would make sense then to unset this variable, right? No way, you can't > acces it: > > <snip> > $f=new foo(); > $f->bar(); > $f->bar(); > foo::$foobar=false; > $f->bar(); > </snip> > > will lead to the following (called by `php5 fubar.php`): > > <snip> > FUBeyondAllR > already defined > > Fatal error: Access to undeclared static property: foo::$foobar in xxxxx > on line 14 > </snip> > > I need to recall the expressions encapsulated in the if-statement, but > this > fu variable behaves like it is protected, right? Does that make sense? Is > there > any way to unset this variable? > > I can't touch the API. > > Thanks for your suggestions and your time. > > josh > i have never use static variables inside of functions and likely never will. go for static class variables instead ![]() <?php class foo{ public static $foobar = false; public function bar(){ static $foobar=false; if (self::$foobar === False){ self::$foobar='FUBeyondAllR'; echo self::$foobar . "\n"; }else{echo "already defined\n";} } } $f=new foo(); $f->bar(); $f->bar(); foo::$foobar=false; $f->bar(); ?> nathan@devel ~/working/www/siuConference $ php testScript.php FUBeyondAllR already defined FUBeyondAllR -nathan |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Joshua Bacher wrote:
>> nathan@devel ~/working/www/siuConference $ php testScript.php >> FUBeyondAllR >> already defined >> FUBeyondAllR >> >> -nathan > > thats the solution for the wrong problem. it's not up to me to change > the API. the API is designed like i noted and i need a way to get around > this behaviour. > > thanks for your idea any further suggestions? As far as I know you can't change it. The static variable you need to adjust is inside the function, not the class and thus it is fundamentally not accessible outside of the function. Even creating a new foo() class will not allow you to adjust the value of $foobar inside the bar() method. Col |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Joshua Bacher wrote:
>> I can't touch the API. >> >> i have never use static variables inside of functions and likely never will. >> go for static class variables instead ![]() >> >> <?php >> class foo{ >> public static $foobar = false; >> public function bar(){ >> static $foobar=false; >> if (self::$foobar === False){ >> self::$foobar='FUBeyondAllR'; >> echo self::$foobar . "\n"; >> }else{echo "already defined\n";} >> } >> } >> >> $f=new foo(); >> $f->bar(); >> $f->bar(); >> foo::$foobar=false; >> $f->bar(); >> ?> >> >> nathan@devel ~/working/www/siuConference $ php testScript.php >> FUBeyondAllR >> already defined >> FUBeyondAllR >> >> -nathan > > thats the solution for the wrong problem. it's not up to me to change > the API. the API is designed like i noted and i need a way to get around > this behaviour. > > thanks for your idea any further suggestions? In that case you need a new foo. That's the only way you're going to reset the internal static if the API doesn't give you a way to do it. $f=new foo(); $f->bar(); $f->bar(); $g=new foo(); $g->bar(); -Stut -- http://stut.net/ |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On 10/18/07, Joshua Bacher <bacher@bash-it.de> wrote:
> > thats the solution for the wrong problem. it's not up to me to change > the API. the API is designed like i noted and i need a way to get around > this behaviour. > > thanks for your idea any further suggestions? > > josh > unfortunately i dont know of a way to modify the value of that variable from anywhere outside the function in which it is defined. -nathan |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On 10/18/07, Stut <stuttle@gmail.com> wrote:
> > Joshua Bacher wrote: > >> I can't touch the API. > >> > >> i have never use static variables inside of functions and likely never > will. > >> go for static class variables instead ![]() > >> > >> <?php > >> class foo{ > >> public static $foobar = false; > >> public function bar(){ > >> static $foobar=false; > >> if (self::$foobar === False){ > >> self::$foobar='FUBeyondAllR'; > >> echo self::$foobar . "\n"; > >> }else{echo "already defined\n";} > >> } > >> } > >> > >> $f=new foo(); > >> $f->bar(); > >> $f->bar(); > >> foo::$foobar=false; > >> $f->bar(); > >> ?> > >> > >> nathan@devel ~/working/www/siuConference $ php testScript.php > >> FUBeyondAllR > >> already defined > >> FUBeyondAllR > >> > >> -nathan > > > > thats the solution for the wrong problem. it's not up to me to change > > the API. the API is designed like i noted and i need a way to get around > > this behaviour. > > > > thanks for your idea any further suggestions? > > In that case you need a new foo. That's the only way you're going to > reset the internal static if the API doesn't give you a way to do it. > > $f=new foo(); > $f->bar(); > $f->bar(); > $g=new foo(); > $g->bar(); this doesnt work: nathan@devel ~/working/www/siuConference $ php testScript.php FUBeyondAllR already defined already defined already defined -nathan |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On 10/18/07, Nathan Nobbe <quickshiftin@gmail.com> wrote:
> > On 10/18/07, Joshua Bacher <bacher@bash-it.de> wrote: > > > > thats the solution for the wrong problem. it's not up to me to change > > the API. the API is designed like i noted and i need a way to get around > > this behaviour. > > > > thanks for your idea any further suggestions? > > > > josh > > > > unfortunately i dont know of a way to modify the value of that variable > from anywhere outside > the function in which it is defined. > > -nathan > i bet even Robert cant change that one ![]() -nathan |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Stut wrote:
> Joshua Bacher wrote: >>> I can't touch the API. >>> >>> i have never use static variables inside of functions and likely >>> never will. >>> go for static class variables instead ![]() >>> >>> <?php >>> class foo{ >>> public static $foobar = false; >>> public function bar(){ >>> static $foobar=false; >>> if (self::$foobar === False){ >>> self::$foobar='FUBeyondAllR'; >>> echo self::$foobar . "\n"; >>> }else{echo "already defined\n";} >>> } >>> } >>> >>> $f=new foo(); >>> $f->bar(); >>> $f->bar(); >>> foo::$foobar=false; >>> $f->bar(); >>> ?> >>> >>> nathan@devel ~/working/www/siuConference $ php testScript.php >>> FUBeyondAllR >>> already defined >>> FUBeyondAllR >>> >>> -nathan >> >> thats the solution for the wrong problem. it's not up to me to change >> the API. the API is designed like i noted and i need a way to get around >> this behaviour. >> >> thanks for your idea any further suggestions? > > In that case you need a new foo. That's the only way you're going to > reset the internal static if the API doesn't give you a way to do it. > > $f=new foo(); > $f->bar(); > $f->bar(); > $g=new foo(); > $g->bar(); Actually, scratch that, won't work. Not even unsetting $f before creating the new object works. This kinda sucks since it means PHP does not support static function-scoped vars. I think you're out of luck. You need to find a way to override this behaviour. Can you not add a function to the API to reset that static? That wouldn't break the existing contract but would let you do what you need. -Stut -- http://stut.net/ |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
[snip]
to be honest i meanwhile have a workaround. [/snip] How about extending the API class and putting the function within the extended class that you need? |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Hi all,
i faced the following problem. i am using a API. This API has a class that looks like following: <snip> class foo{ public function bar(){ static $foobar=false; if ($foobar === False){ $foobar='FUBeyondAllR'; echo "$foobar\n"; }else{echo "already defined\n";} } } </snip> if you call the method of this class twice it will first print FUBeyondAllR and at the second time it will echo 'already defined'. (examples at the next and the last snippet) thats fine but what if you have some processing in the first if case? it would make sense then to unset this variable, right? No way, you can't acces it: <snip> $f=new foo(); $f->bar(); $f->bar(); foo::$foobar=false; $f->bar(); </snip> will lead to the following (called by `php5 fubar.php`): <snip> FUBeyondAllR already defined Fatal error: Access to undeclared static property: foo::$foobar in xxxxx on line 14 </snip> I need to recall the expressions encapsulated in the if-statement, but this fu variable behaves like it is protected, right? Does that make sense? Is there any way to unset this variable? I can't touch the API. Thanks for your suggestions and your time. josh -- -------------------------------- joshua bacher Max Planck Institute for Evolutionary Anthropology Deutscher Platz 6 04103 LEIPZIG Germany web: http://bacher.bash-it.de -------------------------------- |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
> I can't touch the API.
> > i have never use static variables inside of functions and likely never will. > go for static class variables instead ![]() > > <?php > class foo{ > public static $foobar = false; > public function bar(){ > static $foobar=false; > if (self::$foobar === False){ > self::$foobar='FUBeyondAllR'; > echo self::$foobar . "\n"; > }else{echo "already defined\n";} > } > } > > $f=new foo(); > $f->bar(); > $f->bar(); > foo::$foobar=false; > $f->bar(); > ?> > > nathan@devel ~/working/www/siuConference $ php testScript.php > FUBeyondAllR > already defined > FUBeyondAllR > > -nathan thats the solution for the wrong problem. it's not up to me to change the API. the API is designed like i noted and i need a way to get around this behaviour. thanks for your idea any further suggestions? josh -- -------------------------------- joshua bacher Max Planck Institute for Evolutionary Anthropology Deutscher Platz 6 04103 LEIPZIG Germany web: http://bacher.bash-it.de -------------------------------- |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Stut wrote:
> Stut wrote: >> In that case you need a new foo. That's the only way you're going to >> reset the internal static if the API doesn't give you a way to do it. >> >> $f=new foo(); >> $f->bar(); >> $f->bar(); >> $g=new foo(); >> $g->bar(); > > Actually, scratch that, won't work. Not even unsetting $f before > creating the new object works. This kinda sucks since it means PHP does > not support static function-scoped vars. Yeah I tried that same thing too and then wondered if I had misinterpreted how function-scoped statics worked. I've often used a method like: function Init() { static $bln_inited = false; if (!$bln_inited) { // Do stuff $bln_inited = true; } } I had always assumed that the static definition here was function-scoped... I guess I should have tested more but still it caught me off guard this morning when I played with it. Correct me if I'm wrong but does C++ not do it as both of us initially thought? e.g. static is function scoped rather than globally scoped when used within a class method? Col |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
On 10/18/07, Colin Guthrie <gmane@colin.guthr.ie> wrote:
> > Stut wrote: > > Stut wrote: > >> In that case you need a new foo. That's the only way you're going to > >> reset the internal static if the API doesn't give you a way to do it. > >> > >> $f=new foo(); > >> $f->bar(); > >> $f->bar(); > >> $g=new foo(); > >> $g->bar(); > > > > Actually, scratch that, won't work. Not even unsetting $f before > > creating the new object works. This kinda sucks since it means PHP does > > not support static function-scoped vars. > > Yeah I tried that same thing too and then wondered if I had > misinterpreted how function-scoped statics worked. > > I've often used a method like: > > function Init() > { > static $bln_inited = false; > if (!$bln_inited) > { > // Do stuff > $bln_inited = true; > } > } > > > I had always assumed that the static definition here was > function-scoped... I guess I should have tested more but still it caught > me off guard this morning when I played with it. > > Correct me if I'm wrong but does C++ not do it as both of us initially > thought? e.g. static is function scoped rather than globally scoped when > used within a class method? i didnt see anything in the manual regarding the use of static inside a class member function. i would consider the behavior undefined, for php, unless someone can procure a doc. -nathan |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
> >>> I can't touch the API.
> >>> > >>>i have never use static variables inside of functions and likely > >>>never will. > >>>go for static class variables instead ![]() > >>> > >>><?php > >>>class foo{ > >>> public static $foobar = false; > >>> public function bar(){ > >>> static $foobar=false; > >>> if (self::$foobar === False){ > >>> self::$foobar='FUBeyondAllR'; > >>> echo self::$foobar . "\n"; > >>> }else{echo "already defined\n";} > >>> } > >>>} > >>> > >>>$f=new foo(); > >>>$f->bar(); > >>>$f->bar(); > >>>foo::$foobar=false; > >>>$f->bar(); > >>>?> > >>> > >>>nathan@devel ~/working/www/siuConference $ php testScript.php > >>>FUBeyondAllR > >>>already defined > >>>FUBeyondAllR > >>> > >>>-nathan > >> > >>thats the solution for the wrong problem. it's not up to me to change > >>the API. the API is designed like i noted and i need a way to get around > >>this behaviour. > >> > >>thanks for your idea any further suggestions? > > > >In that case you need a new foo. That's the only way you're going to > >reset the internal static if the API doesn't give you a way to do it. > > > >$f=new foo(); > >$f->bar(); > >$f->bar(); > >$g=new foo(); > >$g->bar(); > > Actually, scratch that, won't work. Not even unsetting $f before > creating the new object works. This kinda sucks since it means PHP does > not support static function-scoped vars. > > I think you're out of luck. You need to find a way to override this > behaviour. Can you not add a function to the API to reset that static? > That wouldn't break the existing contract but would let you do what you > need. > to be honest i meanwhile have a workaround. i could suppress the call of the function for the first time and therefore suppressed the initializing of $foobar. now it is only running at the time i need it, with the parameters that i want it to run with. For me it's just a question of interest. At least, i would say, php behaves somehow uncool in this situation. But on the other hand it can also be a nice feature if you want a variable just to be initialized once and protect it afterwards from arbitrary access. i am unsure how to feel about it. if you want a protected variable why don't you declare it as protected? i thank you very much for all you suggestions. maybe it's a good thing to ask for this as a feature request. thank you all josh -- -------------------------------- joshua bacher Max Planck Institute for Evolutionary Anthropology Deutscher Platz 6 04103 LEIPZIG Germany web: http://bacher.bash-it.de -------------------------------- |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
> [snip]
> to be honest i meanwhile have a workaround. > [/snip] > > How about extending the API class and putting the function within the > extended class that you need? it's only partially a solution since the API will change. therefore the expressions in the if statement maybe will change. if i extend the class i would have to overwrite the function with my version. In fact this will solve my problem, but i will not be able to gain from the updates of newer versions for that function in the API, right? Thats a solution but it will result in many more problems in the end. I could merge all the time, but thats sloppy, i don't want that, i am to lazy for doing that ![]() thanks anyway josh -- -------------------------------- joshua bacher Max Planck Institute for Evolutionary Anthropology Deutscher Platz 6 04103 LEIPZIG Germany web: http://bacher.bash-it.de -------------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFHF45/oQ1PzKVWDx0RAmO0AJ9Drx9sfzdSipkZK6qPIlOOHT8zWgCeMT go ogCGPJtjKjbN7vU/ywIYfL0= =p65J -----END PGP SIGNATURE----- |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
Colin Guthrie wrote:
> Stut wrote: >> Stut wrote: >>> In that case you need a new foo. That's the only way you're going to >>> reset the internal static if the API doesn't give you a way to do it. >>> >>> $f=new foo(); >>> $f->bar(); >>> $f->bar(); >>> $g=new foo(); >>> $g->bar(); >> Actually, scratch that, won't work. Not even unsetting $f before >> creating the new object works. This kinda sucks since it means PHP does >> not support static function-scoped vars. > > Yeah I tried that same thing too and then wondered if I had > misinterpreted how function-scoped statics worked. > > I've often used a method like: > > function Init() > { > static $bln_inited = false; > if (!$bln_inited) > { > // Do stuff > $bln_inited = true; > } > } > > > I had always assumed that the static definition here was > function-scoped... I guess I should have tested more but still it caught > me off guard this morning when I played with it. > > Correct me if I'm wrong but does C++ not do it as both of us initially > thought? e.g. static is function scoped rather than globally scoped when > used within a class method? Yes it does, which is why I assumed PHP would do it like that too. I knew I should have tried it before sending the reply. I've tried various ways of accessing that variable via a derived class but it doesn't seem to be possible. Again I'm just assuming, but my theory is that the line... static $foobar = false; ....actually is static to the function and therefore cannot be accessed from outside it in any way, shape or form. So using function statics as you have above will work fine. And they also work fine when used in a method of a class. This behaviour is correct because if a function-scoped static is to work correctly there should be absolutely no way to get at it from outside the function. -Stut -- http://stut.net/ |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Stut wrote:
> Colin Guthrie wrote: >> Stut wrote: >>> Stut wrote: >>>> In that case you need a new foo. That's the only way you're going to >>>> reset the internal static if the API doesn't give you a way to do it. >>>> >>>> $f=new foo(); >>>> $f->bar(); >>>> $f->bar(); >>>> $g=new foo(); >>>> $g->bar(); >>> Actually, scratch that, won't work. Not even unsetting $f before >>> creating the new object works. This kinda sucks since it means PHP does >>> not support static function-scoped vars. >> >> Yeah I tried that same thing too and then wondered if I had >> misinterpreted how function-scoped statics worked. >> >> I've often used a method like: >> >> function Init() >> { >> static $bln_inited = false; >> if (!$bln_inited) >> { >> // Do stuff >> $bln_inited = true; >> } >> } >> >> >> I had always assumed that the static definition here was >> function-scoped... I guess I should have tested more but still it caught >> me off guard this morning when I played with it. >> >> Correct me if I'm wrong but does C++ not do it as both of us initially >> thought? e.g. static is function scoped rather than globally scoped when >> used within a class method? > > Yes it does, which is why I assumed PHP would do it like that too. I > knew I should have tried it before sending the reply. > > I've tried various ways of accessing that variable via a derived class > but it doesn't seem to be possible. Again I'm just assuming, but my > theory is that the line... > > static $foobar = false; > > ...actually is static to the function and therefore cannot be accessed > from outside it in any way, shape or form. > > So using function statics as you have above will work fine. And they > also work fine when used in a method of a class. This behaviour is > correct because if a function-scoped static is to work correctly there > should be absolutely no way to get at it from outside the function. I completely agree that there should be no way to access it outside the function/method it is defined within. The problem is that in PHP the static keyword seems to be globally unique but function/class scoped. e.g. that if it is used in a class method, regardless of how many instances of that method you create with "new" there is only ever one "instance" of the variable. So the case where it wont work fine is when you have the above function as a method of a class which can have multiple instances, all of which need to be Init()'ed independently. In such cases, I guess you'd have to use a private member variable instead which just isn't quite a neat and tidy. If you only ever have one instance of the class then all is well but still could have unexpected side effects if you later extend the system to have more than one instance. I guess if you use a singltron method with a private constructor then it's safe enough but then you can just do your initialisation in the singletron method in that case so there's little point! Hey ho. /me scuttles of to grep code for "static" :s Col |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Nathan Nobbe wrote:
> On 10/18/07, Nathan Nobbe <quickshiftin@gmail.com> wrote: >> On 10/18/07, Joshua Bacher <bacher@bash-it.de> wrote: >>> thats the solution for the wrong problem. it's not up to me to change >>> the API. the API is designed like i noted and i need a way to get around >>> this behaviour. >>> >>> thanks for your idea any further suggestions? >>> >>> josh >>> >> unfortunately i dont know of a way to modify the value of that variable >> from anywhere outside >> the function in which it is defined. >> >> -nathan >> > > > i bet even Robert cant change that one ![]() Runkit could probably do it, but I wouldn't recommend that to anyone. -Stut -- http://stut.net/ |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Colin Guthrie wrote:
> Stut wrote: >> Colin Guthrie wrote: >>> Stut wrote: >>>> Stut wrote: >>>>> In that case you need a new foo. That's the only way you're going to >>>>> reset the internal static if the API doesn't give you a way to do it. >>>>> >>>>> $f=new foo(); >>>>> $f->bar(); >>>>> $f->bar(); >>>>> $g=new foo(); >>>>> $g->bar(); >>>> Actually, scratch that, won't work. Not even unsetting $f before >>>> creating the new object works. This kinda sucks since it means PHP does >>>> not support static function-scoped vars. >>> Yeah I tried that same thing too and then wondered if I had >>> misinterpreted how function-scoped statics worked. >>> >>> I've often used a method like: >>> >>> function Init() >>> { >>> static $bln_inited = false; >>> if (!$bln_inited) >>> { >>> // Do stuff >>> $bln_inited = true; >>> } >>> } >>> >>> >>> I had always assumed that the static definition here was >>> function-scoped... I guess I should have tested more but still it caught >>> me off guard this morning when I played with it. >>> >>> Correct me if I'm wrong but does C++ not do it as both of us initially >>> thought? e.g. static is function scoped rather than globally scoped when >>> used within a class method? >> Yes it does, which is why I assumed PHP would do it like that too. I >> knew I should have tried it before sending the reply. >> >> I've tried various ways of accessing that variable via a derived class >> but it doesn't seem to be possible. Again I'm just assuming, but my >> theory is that the line... >> >> static $foobar = false; >> >> ...actually is static to the function and therefore cannot be accessed >> from outside it in any way, shape or form. >> >> So using function statics as you have above will work fine. And they >> also work fine when used in a method of a class. This behaviour is >> correct because if a function-scoped static is to work correctly there >> should be absolutely no way to get at it from outside the function. > > I completely agree that there should be no way to access it outside the > function/method it is defined within. The problem is that in PHP the > static keyword seems to be globally unique but function/class scoped. > e.g. that if it is used in a class method, regardless of how many > instances of that method you create with "new" there is only ever one > "instance" of the variable. > > So the case where it wont work fine is when you have the above function > as a method of a class which can have multiple instances, all of which > need to be Init()'ed independently. > > In such cases, I guess you'd have to use a private member variable > instead which just isn't quite a neat and tidy. > > If you only ever have one instance of the class then all is well but > still could have unexpected side effects if you later extend the system > to have more than one instance. I guess if you use a singltron method > with a private constructor then it's safe enough but then you can just > do your initialisation in the singletron method in that case so there's > little point! > > Hey ho. > > /me scuttles of to grep code for "static" :s Nope, not globally unique: http://dev.stut.net/php/funcstatic.php So what you have will be fine. -Stut -- http://stut.net/ |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Stut wrote:
> Colin Guthrie wrote: >> Stut wrote: >>> Colin Guthrie wrote: >>>> Stut wrote: >>>>> Stut wrote: >>>>>> In that case you need a new foo. That's the only way you're going to >>>>>> reset the internal static if the API doesn't give you a way to do it. >>>>>> >>>>>> $f=new foo(); >>>>>> $f->bar(); >>>>>> $f->bar(); >>>>>> $g=new foo(); >>>>>> $g->bar(); >>>>> Actually, scratch that, won't work. Not even unsetting $f before >>>>> creating the new object works. This kinda sucks since it means PHP >>>>> does >>>>> not support static function-scoped vars. >>>> Yeah I tried that same thing too and then wondered if I had >>>> misinterpreted how function-scoped statics worked. >>>> >>>> I've often used a method like: >>>> >>>> function Init() >>>> { >>>> static $bln_inited = false; >>>> if (!$bln_inited) >>>> { >>>> // Do stuff >>>> $bln_inited = true; >>>> } >>>> } >>>> >>>> >>>> I had always assumed that the static definition here was >>>> function-scoped... I guess I should have tested more but still it >>>> caught >>>> me off guard this morning when I played with it. >>>> >>>> Correct me if I'm wrong but does C++ not do it as both of us initially >>>> thought? e.g. static is function scoped rather than globally scoped >>>> when >>>> used within a class method? >>> Yes it does, which is why I assumed PHP would do it like that too. I >>> knew I should have tried it before sending the reply. >>> >>> I've tried various ways of accessing that variable via a derived class >>> but it doesn't seem to be possible. Again I'm just assuming, but my >>> theory is that the line... >>> >>> static $foobar = false; >>> >>> ...actually is static to the function and therefore cannot be accessed >>> from outside it in any way, shape or form. >>> >>> So using function statics as you have above will work fine. And they >>> also work fine when used in a method of a class. This behaviour is >>> correct because if a function-scoped static is to work correctly there >>> should be absolutely no way to get at it from outside the function. >> >> I completely agree that there should be no way to access it outside the >> function/method it is defined within. The problem is that in PHP the >> static keyword seems to be globally unique but function/class scoped. >> e.g. that if it is used in a class method, regardless of how many >> instances of that method you create with "new" there is only ever one >> "instance" of the variable. >> >> So the case where it wont work fine is when you have the above function >> as a method of a class which can have multiple instances, all of which >> need to be Init()'ed independently. >> >> In such cases, I guess you'd have to use a private member variable >> instead which just isn't quite a neat and tidy. >> >> If you only ever have one instance of the class then all is well but >> still could have unexpected side effects if you later extend the system >> to have more than one instance. I guess if you use a singltron method >> with a private constructor then it's safe enough but then you can just >> do your initialisation in the singletron method in that case so there's >> little point! >> >> Hey ho. >> >> /me scuttles of to grep code for "static" :s > > Nope, not globally unique: http://dev.stut.net/php/funcstatic.php > > So what you have will be fine. No it wont work as I *intended* but that is purely due to my own misinterpretation of how statics in a method works. I've satisfied my own understanding now by testing it in C++ and it behaves the same as in PHP here, so I'm completely in the know (now!). I did however think it worked differently! Like I say it's just my own misunderstanding. Here is what I meant for completeness: Try the following code and note especially the last two lines of the output (change the \n to <br /> if you want if for web output.. I tested on cmdline). <?php $GLOBALS['eol'] = "\n"; class c { public function a($nm) { static $var = 0; print $nm.'a: '.$var.$GLOBALS['eol']; $var++; } public function b($nm) { static $var = 0; print $nm.'b: '.$var.$GLOBALS['eol']; $var++; } } $c = new c(); for ($i = 0; $i < 10; $i++) { $c->a('C'); if ($i % 2) $c->b('C'); } $d = new c(); $d->a('D'); $d->b('D'); ?> Ca: 0 Ca: 1 Cb: 0 Ca: 2 Ca: 3 Cb: 1 Ca: 4 Ca: 5 Cb: 2 Ca: 6 Ca: 7 Cb: 3 Ca: 8 Ca: 9 Cb: 4 Da: 10 Db: 5 i.e. the $d object just carries on where $c left off. This is not what I had in my head how things worked. I had originally thought that the static keyword within a class method was only static in the context of that *instance* of the class. This is clearly mince now I look into it and think about it a bit. e.g. consider the following class. <?php $GLOBALS['eol'] = "\n"; class foo { private $mVar = "Uninitialised"; public function Init() { static $bln_initialised = false; if (!$bln_initialised) { $this->mVar = 'Initialised'; $bln_initialised = true; } } public function Display($nm) { echo $nm.': '.$this->mVar.$GLOBALS['eol']; } } $foo = new foo(); $foo->Init(); $foo->Display('Foo'); $bar = new foo(); $bar->Init(); $bar->Display('Bar'); ?> Foo: Initialised Bar: Uninitialised That's not what I *wanted* to happen, even tho' I now understand that's what *should* happen! I confirmed this with C++ to satisfy me that that's what it does too and it does: #include <iostream> #include <string> using namespace std; class foo { public: foo(); void Init(); void Display(string nm); private: string var; }; foo::foo() :var("Uninitialised") { } void foo::Init() { static bool bln_initialised = false; if (!bln_initialised) { var = "Initialised"; bln_initialised = true; } } void foo: isplay(string nm){ cout << nm << ": " << var << endl; } int main() { foo foo, bar; foo.Init(); foo.Display("Foo"); bar.Init(); bar.Display("Bar"); return 0; } Foo: Initialised Bar: Uninitialised So my understanding suitably updated. ![]() Col PS I know the above examples are contrived and that constructors would be more appropriate for the above - but using constructors is not always possible due to how you deal with failed initialisations where exceptions are not desirable. |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
Colin Guthrie wrote:
> PS I know the above examples are contrived and that constructors would > be more appropriate for the above - but using constructors is not always > possible due to how you deal with failed initialisations where > exceptions are not desirable. I see what you mean. You thought that static variables in a member function of a class would be different for each instance of that class. Indeed that's not the case, statics are attached to the class not the object. As for the problem of dealing with failed initialisations there are two ways to deal with that. The first is to us a separate initialisation method - this allows it to return a value. Your constructor would simply fill the object with sensible defaults. The second is to have a member variable that stores whether the object has been successfully initialised. Either of these would be far better than using a static variable since initialisation status is a property of the object not the class. Anyways, glad we both understand some things a bit better now. On to the next problem! -Stut -- http://stut.net/ |
|
![]() |
| Outils de la discussion | |
|
|