Edit report at https://bugs.php.net/bug.php?id=40837&edit=1

 ID:                 40837
 Comment by:         ni...@php.net
 Reported by:        nick dot telford at gmail dot com
 Summary:            static and non-static functions can't have the same
                     name
 Status:             Not a bug
 Type:               Bug
 Package:            Class/Object related
 Operating System:   Irrelevant
 PHP Version:        5.2.1
 Block user comment: N
 Private report:     N

 New Comment:

We *can not* have static and non-static methods with the same name. This is 
*not* just a backwards compatibility concern.

I think the issue here is that you got the meaning of the :: operator wrong. :: 
is not a "static access operator", it's a "scope resolution operator". It calls 
a method (or accesses a property) in a certain scope.

E.g. Foo::bar() calls the method bar() in the scope of class Foo. bar() here 
can be any method.

A "static" method just means that the method does not need $this. The 
Foo::bar() call will only work if
 a) the method is static or
 b) the method is non-static and we have a $this.

The distinction between "static access operator" and "scope resolution 
operator" is important and helps you understand why some things are as they 
are. For example, if you want to access a parent method, then what do you write?
parent::foo(). This means that you call foo() in the parent scope.

I get that people might argue whether "calling non-static methods with ::" is 
useful in the general case, but calling parent methods is something everybody 
should understand and find useful. And using that example it's also easy to see 
why you couldn't have the same static and non-static method. Consider this 
small example:

    class A {
        public function foo() { echo 'non-static'; }
        public static function foo() { echo 'static'; }
    }
    class B {
        public function bar() { echo parent::foo(); }
    }
    (new B)->bar(); // What do you get?

Allowing static and non-static methods of the same name would require us to 
completely change the concept of scope-resolution and find a different way to 
call parent methods etc.

So, just to say it again: Removing "::"-calls to non-static methods is *not* 
just a backwards compatibility issue, it would also cause problems with other, 
currently used and encouraged language features.

Another thing that might help the understanding (apart from interpreting :: as 
scope-resolution) is not seeing static and non-static methods as distinct 
method types. Rather they are the same and "static" is just another method 
modifier like "public" or "final":

You probably wouldn't ask to have "an abstract method and a final method of the 
same name", right? Asking for a non-static and static method of the same name 
makes similarly little sense. "static" just means "doesn't need $this" and 
nothing more.

On a related note, this "static" modifier is also available for closures (i.e. 
you can write "$foo = static function() { ... }") and also means the same 
there, that the closure does not need $this. Prefixing a closure with "static" 
does not make it some kind of wholly different function type, it's just a 
modifier. Same for the static methods ;)

I hope things are a bit clearer now.


Previous Comments:
------------------------------------------------------------------------
[2013-04-21 05:30:23] dmittner at llnw dot com

I've got to add my vote to this feature.

My use case consists of data validation methods. If called statically the 
validation tests are limited to things like string length, contents, etc. If 
called on an object it would include those tests (probably calling the static 
form of itself) and also comparative tests to other object conditions.

I sympathize with backwards compatibility but sometimes you have to push 
forward. Case and point, some people I know are working with a Java-based 
system 
that doesn't support Java 7, so when building new servers they have to 
explicitly install an older version. Cutting a line between major PHP versions 
seems similarly viable.

I'd also cite Magic Quotes which are completely removed in 5.4, which could 
similarly break older PHP4 compatibility. The precedent is set.

Failing all that, how about a configuration option?

------------------------------------------------------------------------
[2012-11-20 02:13:10] capitaine dot gloumi at gmail dot com

The "backward compatibility" should set to deprecated any static call of object 
method, and use it IF NO static method with the same name exist.

I use static method and object method with same name in lot of paterns, it's 
useful in lot of case.

------------------------------------------------------------------------
[2012-11-19 03:27:35] ahar...@php.net

If a class is namespaced, by definition it isn't PHP 4 compatible.

------------------------------------------------------------------------
[2012-11-15 23:23:31] jpmarois at hotmail dot com

ahar...@php.net:

Sure, go Microsoft's way and move forward by staying behind for the sake of 
"compatibility".

Please explain why, "As of PHP 5.3.3, methods with the same name as the last 
element of a namespaced class name will no longer be treated as constructor.". 
If 
PHP wont even initialize a "compatible" PHP 4 class anymore, how is it relevant 
to 
preserve instance methods being called statically?

------------------------------------------------------------------------
[2012-09-11 01:59:54] ahar...@php.net

It breaks compatibility with any PHP 4 compatible code that uses static method 
calls. That's (obviously) less important than it once was, but there's still 
plenty of legacy code out there.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=40837


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=40837&edit=1

Reply via email to