php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49542 __callStatic() only invoked if instance method does not exist
Submitted: 2009-09-13 14:34 UTC Modified: 2011-06-09 23:44 UTC
Votes:9
Avg. Score:4.8 ± 0.4
Reproduced:8 of 8 (100.0%)
Same Version:4 (50.0%)
Same OS:1 (12.5%)
From: mjs at beebo dot org Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.3.0 OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mjs at beebo dot org
New email:
PHP Version: OS:

 

 [2009-09-13 14:34 UTC] mjs at beebo dot org
Description:
------------
A static call to Foo::bar() does not invoke __callStatic() if an 
instance method bar() exists.

One reason you might want this is to convert static calls to Foo::bar() 
to the equivalent operation on a singleton:

public static function __callStatic($name, $args) {
    $obj = self::getInstance();
    return call_user_func_array(array($obj, $name), $args);
}

In the sample code below, __callStatic() is not invoked even though the 
caller has deliberately initiated a static call.

Reproduce code:
---------------
<?php

class Foo {

    public static function __callStatic($name, $args) {
        echo "In __callStatic()\n";
    }

    public function bar() {
        echo "In bar()\n";
    }

}                                                                                                                                                
                                                                                                                                                 
echo Foo::bar();


Expected result:
----------------
In _callStatic()

Actual result:
--------------
PHP Strict Standards:  Non-static method Foo::bar() should not be called 
statically in /mnt/hgfs/workspace/scratch/wart1.php on line 15

Strict Standards: Non-static method Foo::bar() should not be called 
statically in /mnt/hgfs/workspace/scratch/wart1.php on line 15
In bar()


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-10-15 03:40 UTC] matt dot lubner at gmail dot com
With PHP 5.3.2, if the instance method bar() is *not* public, and __callStatic() 
*is*, __callStatic() will be invoked, because bar() won't be in scope.  
Unfortunately, this seems like a horribly hacked work-around. Ideally, public 
instance methods should not be in scope from a static context, so __callStatic() 
will be called instead.
 [2010-10-15 03:50 UTC] matt dot lubner at gmail dot com
I should have also mentioned that calling an instance method in a static context 
does not generate an error, unless the called method has any references to $this 
(which of course is not in scope), in which case a fatal error occurs.  This can 
be a little tricky to track down, and so would be preferable if instance methods 
were simply not in scope for static contexts.
 [2010-12-20 13:15 UTC] jani@php.net
-Package: Feature/Change Request +Package: Scripting Engine problem
 [2010-12-20 13:16 UTC] jani@php.net
-Package: Scripting Engine problem +Package: Class/Object related
 [2011-06-09 23:44 UTC] felipe@php.net
-Status: Open +Status: Bogus -Type: Feature/Change Request +Type: Bug
 [2011-06-09 23:44 UTC] felipe@php.net
Not a bug, you need to declare the method 'bar' as static.
 [2012-08-14 18:13 UTC] loren at kanjoya dot com
Well, if it is not a bug, then it is a very poor and unfortunate language design 
decision.
 [2012-08-14 20:37 UTC] stan at eproject-inc dot com
Wow. Not a bug? This is a terrible design decision, to say that invoking an 
instance method from a non-instance context is intentional. That this is even a 
question says volumes.

I've been a user and supporter of the language for several years now, and it's 
really sad to see something like this. This is the kind of design philosophy 
that gives PHP a bad rap for being difficult to work in.

It's one thing to say "Yes, we have an octopus in our living room. I know, I 
know, it's utterly stupid and doesn't make sense, but we're otherwise occupied 
right now." It's another thing to say, "Yes, we have an octopus in the living 
room. What? No, you're the idiot."

Absurd.
 [2012-08-14 21:55 UTC] nikic@php.net
Guys, do we need to go through this again? Sure, it feels nice to write a rant about how all PHP devs are stupid and stuff, but it doesn't help anyone.

Also, don't interpret too much into a simple response. "Not a bug" does not mean "you're an idiot". I don't know how you came to that conclusion.

As already pointed out, this behavior is by-design, so yes, it is not a bug - at least for some definitions of "bug" (don't forget that any sufficiently advanced bug is indistinguishable from a feature).

PHP allows calling non-static methods statically. Doing so is considered bad practice nowadays, but this behavior was kept around from PHP 4 times. When considering something, please don't forget that things that made sense a few years ago don't necessarily make sense now. Heck, from a modern point of view static methods shouldn't exist *at all*, because they promote bad design (and use of __callStatic in particular so). But, as already said, the feature is older than today.

On a tangentially related note, there is a proposal for PHP 5.5 to deprecate calls with incompatible context, which has been one of the major WTF moments with calling instance methods statically (see https://wiki.php.net/rfc/incompat_ctx). This would be the first step in the right way.

So, if care about this design issue that much, then the best way to go would be to write an RFC with a detailed assessment of the current situation, how the issue can be resolved, how much it would impact code, what an appropriate migration strategy could be, etc, etc.

Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 16 09:01:28 2024 UTC