Jump to content

Interesting Behavior In Php's Handling Of $This


ManiacDan

Recommended Posts

Consider the following code:

 

<?php 
error_reporting( E_ALL | E_STRICT ); 
class staticClass 
{ 
 function staticMethod() 
 { 
   //when called statically from the global scope, this throws a fatal error due to $this 
   echo $this->echoMe . "\n"; 
 } 
} 

class dynamicClass 
{ 
 public $echoMe; 

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

 public function thisShouldNotWork() 
 { 
   //calling the staticClass method statically does NOT throw a fatal error as expected, the $this reference inside 
   //staticClass is assumed to be a reference to the current instance of dynamicClass instead 
   staticClass::staticMethod(); 
 } 
} 

$a = new dynamicClass( "Hello, World!" ); 
$a->thisShouldNotWork(); 

/* The above throws a strict warning BUT STILL PRINTS "Hello, World!" 
Strict Standards: Non-static method staticClass::staticMethod() should not be called statically, assuming $this from incompatible context in test.php on line 22 
Hello, World! 
*/

 

The aptly named function thisShouldNotWork calls a method statically when that method was not defined as static. Even though the function is called statically, $this exists inside that function and can be manipulated and accessed. However, $this inside of staticClass points to a different class. No inheritance is given by the code, but one class is able to access another's variables using $this. PHP "falls back" to the last valid instance of $this since it's a super-global. Only a strict warning level will tell you that something wacky is going on.

Link to comment
Share on other sites

Calling a not-declared-static method statically not causing an error is a backward compatibility thing I know (for older php4 code). Why they chose to import $this from a different context thought I don't know. Maybe php4 behaved like that, I've never tried it.

 

Someone certainly might be confused by the behavior if they are not running with full error reporting.

 

At least it handles the context right w/ respect to private/protected members and disallows access.

Edited by kicken
Link to comment
Share on other sites

I didn't really want to say this because I don't like giving people bad ideas, but this is a way to fake multiple inheritance or a sort of fake-y interface that doesn't require additional coding on the interfaced objects.

 

It's still definitely weird and you shouldn't ever do it, but it's interesting, especially since it respects the invalid context and doesn't allow private/protected access. It knows that $this is another object, but uses it anyway. Such an odd choice.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.