php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62393 __callStatic from a derived class object context calls __call instead
Submitted: 2012-06-22 10:04 UTC Modified: 2012-06-23 06:39 UTC
From: andre-desch at t-online dot de Assigned:
Status: Not a bug Package: Reflection related
PHP Version: 5.4.4 OS: Windows 7 Prof.
Private report: No CVE-ID: None
 [2012-06-22 10:04 UTC] andre-desch at t-online dot de
Description:
------------
If You define both the magic function for static and dynamic calls for a class and 
then call a static function from a derivate's method, not the static but the 
dynamic magic function is called.

Test script:
---------------
<?php

class MyBaseClass {

	public static function __callStatic($what, $args)
	{
		return 'static call';
	}
	
	public function __call($what, $args)
	{
		return 'dynamic call';
	}

}

class MyDerivedClass extends MyBaseClass {

	function someAction()
	{
		//here I call a base class' static function
		//it returns "dynamic call" instead of "static call"
		return MyBaseClass::Foo();
	}

}

$bar = new MyDerivedClass();
echo $bar->someAction();

?>

Expected result:
----------------
static call

Actual result:
--------------
dynamic call

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-06-22 11:15 UTC] johannes@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is due to the way calls to parent::foo() and such are handled, these look like static calls but in fact aren't.
 [2012-06-22 11:15 UTC] johannes@php.net
-Status: Open +Status: Not a bug
 [2012-06-22 11:57 UTC] john dot papaioannou at gmail dot com
Excuse me, but how exactly does parent::Foo() come into the discussion?

The test code is calling MyBaseClass::Foo(), which clearly is a static call.
 [2012-06-22 14:46 UTC] cataphract@php.net
> The test code is calling MyBaseClass::Foo(), which clearly is a static call.

You are mistaken. MyBaseClass::Foo() is not necessarily a static call. Namely, if $this is of type MyBaseClass or a subclass thereof and there's no explicit static method MyBaseClass::Foo(), then MyBaseClass::Foo() is an instance call.
 [2012-06-23 06:39 UTC] laruence@php.net
if there is a calling scope, then :: is not a static call.

if there is no calling scope, then :: is a static call.

the key point is the calling scope, not the "::" .

thanks
 [2012-06-23 13:44 UTC] andre-desch at t-online dot de
It is a static call if You use an empty proxy class like below. The only 
difference in scope is, that MyProxyClass is not directly in the hierachy tree 
above the calling method's class. Please explain why this is intended.

class MyProxyClass extends MyBaseClass { //empty }

class MyDerivedClass extends MyBaseClass {
	function someAction()
	{
		return MyProxyClass::Foo();
	}
}
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC