4
<?php
class A {
  public function instanceFunc() {
    echo "instance";
  }

  public static function staticFunc() {
    echo "static";
  }
}

A::instanceFunc(); // instance
$a = new A();
$a->staticFunc(); // static

This means in PHP static method and instance method have no different at all. Zend doesn't even complain about it(WITHOUT WARNING).

In Zend Engine. both static method and instance method all saved in zend_class_entry.function_table.

Why PHP behave like this? It's a bug or feature?

3

3 Answers 3

3

This is a potential duplicate of Does static method in PHP have any difference with non-static method?.

You will get an error message if you have E_STRICT warnings enabled, otherwise, you are able to silently call a nonstatic method as if it were static. As mentioned in answers here and at the other question, a real-world static/nonstatic method would not get far without having access to $this or self as it was written to expect.

Refer to the docs: http://www.php.net/manual/en/language.oop5.static.php

Here's something to play with:

http://codepad.org/Gbu9T6Zv

Sign up to request clarification or add additional context in comments.

2 Comments

call a static method instancely nothing would happen
@reeze, I'm unsure of the meaning of your comment, but there is absolutely nothing wrong with invoking a static method via an instance object, and everything happens exactly as if it were invoked via a class literal.
2

If you try running the code below and look at the backtrace output you will see that PHP converts instanceFunc() to a static method when called in a static context. However, in an instance context it will treat it as a instance call.

If you introduce instance variables in to the mix (remove commented out lines) then a fatal error is encountered when called instanceFunc() from a static call.

This implies that PHP allows all methods that are static in nature (no instance variables are worked with) to be called from a static context, as soon as this contract is broken however an error will be produced. Therefore the use of static functions seems to be only good practice in keeping with other Object Orientated languages.

With regards to staticFunc() both calls show that PHP interprets these as static calls, which is to be expected.

class A {
  private $x = 5;
  private $y = 6;
  private $z;
  public function instanceFunc() {
    //$this->z = $this->y * $this->x;
    //echo $this->z;
    var_dump(reset(debug_backtrace()));
  }

  public static function staticFunc() {
    var_dump(reset(debug_backtrace()));
  }
}
$a = new A();
A::instanceFunc(); // static call of intended instance method
$a->instanceFunc(); // instance call of instance method
A::staticFunc();
$a->staticFunc();

Example output (code running with comments):

array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(19) ["function"]=>  string(12) "instanceFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=>  array(0) { } } 
array(7) { ["file"]=> string(59) "test.php" ["line"]=> int(22) ["function"]=> string(12) "instanceFunc" ["class"]=> string(1) "A" ["object"]=> object(A)#8 (3) { ["x:private"]=> int(5) ["y:private"]=> int(6) ["z:private"]=> NULL } ["type"]=> string(2) "->" ["args"]=> array(0) { } } 
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(24) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } } 
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(26) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } }

2 Comments

Interesting stuff on the backtrace, +1. In light of the fact the doing this will throw an E_STRICT error only, I am assuming this is maintained for some legacy/backwards compatibility reasons - with an intent to eventually eliminate it. Otherwise, the "convert this method to static" behavior is nonsense - you're totally correct about it, but it is nonsense all the same!
I agree, it is nonsensical, but PHP was not born an OO language and so I imagine your suspicions of this 'bug' existing for legacy reasons is correct.
1

I am not sure why it would not throw a warning or at least an error. However, there are some major differences in the static and instance. A static method cannot use class variables that are non-static. Which is easily tested by adding a public / private variable that is non-static and trying to echo it in the staticFunc that will throw an error.

I think the main goal is to understand the differences between the two and how to properly use them. As far as why PHP does not at least raise a Notice, I do not know, perhaps it is due to its laid back nature. I am interested in the response someone who has more knowledge on it can give, this is kind of just a bit of extra information.

I did test it with full error reporting on, and sure enough it really does not throw a notice or warning.


UPDATE

Doing some testing, it seems as though when you call a non marked static function as a static function, you still cannot use the private/public variables. Which, for normal functions, will most likely error them out. Which could be why the error or notice was never thrown. However, it would be nice for it to throw something about it, as using a non-marked static function in such a way is surely not good to do.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.