I have a web application that I just updated from 5.3 to 5.5 on my server and i get around 200-300 errors like below. I understand this is a deprecation error and is it possible to solve all in one go and not hide the errors?
Strict standards: Non-static method xyz() should not be called statically.
Calling non-static methods statically generates an E_STRICT level warning.
Function xys is not static, but is clled statically. See difference below.
<?php
// Calling non-static function, first create object by class
$foo = new Foo();
$foo->xyz();
// Calling static function (you are doing this)
Foo::xyz();
?>
You should define your function like this. Find where xyz is defined.
public static function xyz(){}
Then it wont throw strict standard error. Just add static to your function and all errors will be gone.
You don't have to change it in all 200 files. This function is just called in 200 files. That dosen't meen that you have bug in all of them.
NOTE: from docs
Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.
So, if your are using $this in function xyz, you have to use my first example. Then it means fixing all 200 files.
See docs for static keyword.
Just make the function static.
The fix is a simple one , but it has to done in all places where you called a static method that way. I think there is no other way.
Related
I understand that static methods have no access to state of instance objects of their class types and hence referencing $this inside them results in an error.But objects can reference static methods using object to member operator ->
$obj->staticMethod();
and can even pass it their state via paramaters.
$para1 = $obj->para1;
$para2 = $obj->para2;
$obj->staticMethod($para1, $para2);
How is this last example possible when statics are resolved in static context. If someone can explain to me the general behaviour of statics in php code. you can even talk about C related concepts if it will help.
Since you state that you already understand what static means, I'll skip over that.
However, it may still be good to reference PHP's documentation on the static keyword. In particular the following two alerts are important (and hard to glance over, really).
Caution In PHP 5, calling non-static methods statically generates an E_STRICT level warning.
And this one (italic emphasis mine).
Warning In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
So, to cut a long story short: yes, your example will run (for now), because the PHP interpreter will try to fix up your mistake for you. You should however never do this. What the PHP interpreter will do is:
Say your $obj is of type Foo. Then it will read
$obj->staticMethod($para1, $para2);
conclude that staticMethod is static and instead execute
Foo::staticMethod($para1, $para2);
It is of course perfectly fine to pass parameters that are properties of an instance of Foo. It doesn't matter to staticMethod where the parameters come from.
To elaborate a bit more on why this works, while using $this in a static method is not allowed.
You can think of normal methods as static functions that have one extra: they receive an implicit parameter $this. The value of $this is simply the object on which the method is called. Thus, $obj->do($a, $b, $c) is equivalent to calling Foo::do($obj, $a, $b, $c) and naming the first argument of do, $this. This is convenient, because we can now easily define methods that work on an instance of an object without having to explicitly state over and over again that this instance is a parameter of our methods. Great.
Now back to static functions. The only difference with normal methods is that they do not receive this implicit $this parameter. Thus, using $this inside of them is invalid. Not because it is forbidden, but because it does not reference anything. PHP does not (and cannot) have a clue what $this should refer to.
Another way to look at it. Say that our Foo class has two properties: $para1 and $para2, both numbers. Say that you write a method that returns the sum of these numbers. One way is to do this:
public static function sum($para1, $para2) {
return $para1 + $para2;
}
Great. Works. However, it is annoying to have to call it like this
$sum = Foo::sum($obj->para1, $obj->para2);
So, this is what methods are for!
public function sum(/* implicit $this parameter */) {
// write looking up the properties once inside the function, instead
// of having to write it every time we call the function!
return $this->para1 + $this->para2;
}
// ...
$sum = $obj->sum(); // $obj is passed implicitly as $this
Because static functions do not receive an implicit $this parameter, using $this inside of them is like trying to use $undefined when you have never defined it. Thus, invalid.
Static means class members in simple terms , A static data member is accessible within a class regardless object is created or not . The static function are also functions dedicated to whole class . Static function works with static data only bit it can sometimes vary . Though statics are class dedicated, you can access them using object. It is allowed in all languages. Why ? Because of feasibility . If an object is not being able to access static members , that is a limitation.
I was reading a book about PHP when I ran into a strange part of code:
class Employee {
public function show() {
echo "show launched\n";
}
}
Employee::show();
I came from C++ so I was going to bet this code wouldn't work. This is why I tested it.
And it worked, showing "show launched" (omg, am I drunk?)!
It seems to be breaking the concept that method of class can be called without instantiation of class.
What is the point then of static identifier in classes?
Are all public functions static too? Really, what am I missing?
Thanks in advance.
Addition:
Just a notice.
I found that in this book.
Pages 178-179 and it's given as correct example (if I'm right)
Yeah that would work but with a warning. You may have turned off your error reporting on PHP by the way...
Strict standards: Non-static method Employee::show() should not be
called statically
Adding a static keyword before the function definition would make the warning dissappear.
Below code works without a warning..
<?php
class Employee {
public static function show() { //<----- Added the static keyword.
echo "show launched\n";
}
}
Employee::show();
To answer your question...
It seems to be breaking the concept that method of class can be called
without instantiation of class.
Yeah that is correct, that's why you are getting a pretty clear cut warning as I showed you earlier. You know what a warning does right ? ;). Something that should not be done.
From the PHP Docs..
Calling non-static methods statically generates an E_STRICT level
warning.
Source
It has different behavior related on php version. PHP 4 did not have a static keyword (in function declaration context) but still allowed methods to be called statically with ::. This continued in PHP 5 for backwards compatibility purposes.
However with the changes in the object model with PHP 5 - the static keyword has been introduced.
And then since PHP 5.1.3 you get proper strict standard warnings about those like:
Strict Standards: Non-static method Employee::show() should not be called statically in ...
I think it depends on php version you are using. This feature is deprecated in the new php version and will be removed in the future versions.
this will not work and you will get error when using the latest php versions.
I am using PHP 5.5.9-1+sury.org~precise+1 (cli) (built: Feb 13 2014 15:53:53)
and if turn errors on and put your code as it is.
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
class Employee {
public function show() {
echo "show launched\n";
}
}
Employee::show();
?>
This is error message I am getting.
**Strict Standards: Non-static method Employee::show() should not be called statically in /var/www/test/index.php on line 19
show launched**
The Code Works you will get a Warning
Strict standards: Non-static method Employee::show() should not be called statically
Just add the static keyword in the function like public static function show()
Why is the 'self'-call to a non-satic method in this example working?
class A{
protected function aNonStaticMethod(){
return __class__;
}
public function aEcho(){
echo self::aNonStaticMethod();
}
}
Thanks for explanation.
In your simple example $this and self is interchangable. But be aware of the different method resolving when dealing with inheritance (i added static for completeness):
class A {
protected function aNonStaticMethod(){
return __class__;
}
public function selfEcho(){
echo self::aNonStaticMethod();
}
public function staticEcho(){
echo static::aNonStaticMethod();
}
public function thisEcho(){
echo $this->aNonStaticMethod();
}
}
class B extends A {
protected function aNonStaticMethod(){
return __class__;
}
}
$b = new B();
$b->selfEcho(); // A
$b->staticEcho(); // B
$b->thisEcho(); // B
Calling non-static method statically
Theoretically it should not work, but as this comment says:
There was no static keyword in php4 but php4 did allow for static
calls. To maintain backwards compatibility this was left in when the
static keyword was added in php5.
This comment is supported by this official php.net wiki:
This is already deprecated if the call occurs from an instance method.
Not annotating methods as static is an obsolete PHP4-ism.
You really should not call non-static method statically - it does not make sense (if there is a static keyword).
Avoid calling non-static methods statically completely!
...because a) it is a bad approach and b) the PHP docs say:
Caution
In PHP 5, calling non-static methods statically generates an E_STRICT level warning.
AND
Warning
In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
Using :: operator for non-static calls - may be a good approach!
As #Kontrollfreak pointed out and as this docs say the :: operator is not limited to static calls:
the double colon, is a token that allows access to static, constant,
and overridden properties or methods of a class
So it is OK if you reference this way a method or properties from a parent class - which is not limited to a direct parent.
EDIT: do not mistake this for Fascade etc. software patterns!
During writing this answer I forgot to mention that there might be cases, when the call is static, but internally it is calling dynamic method - for more info see patterns like Facade or Singleton.
However do NOT mistake these with issue described above! (issue above is about using direct static call on dynamic thing that should be called dynamically, these patterns are about calling static methods statically, which then may dynamically invoke something dynamic (internally)).
What is the difference between these two pieces of code?
class something {
static function doit() {
echo 'hello world';
}
}
something::doit();
and the same but without the static keyword
class something {
function doit() {
echo 'hello world';
}
}
something::doit();
They both work the same is it better to use the static keywords? Am i right in understanding that it doesn't instantiate the class if you use the static method?
The second example is technically incorrect - if you turn on E_STRICT error reporting you'll see that PHP is actually throwing an error.
PHP Strict Standards: Non-static
method something::doit() should not be
called statically in...
In other words, it's being nice and letting you call the function anyway.
In addition to the other valid answers, the reason for the 2nd example working is also due to a quirk in how PHP handles objects and calls (Besides PHP 4 compatibility). Calling a non-static declared method statically from within another instance will let you access class methods on other classes as if they were local. To understand, let's take an example:
class A {
public function foo() {
echo get_class($this) . "\n";
}
}
class B {
public function bar() {
A::foo();
}
}
$a = new a();
$a->foo(); // "A"
$b = new B();
$b->bar(); // "B"
Did you see what happened there? Because you called the A::foo() method from within another class's instance, PHP treated the call as if it was on the same instance. Note that there is no relationship between A and B other than the fact that B calls A. Within A->foo(), if we did $this instanceof A (or $this instanceof self), it would fail and return false! Quite unusual...
Now, I first thought it was a bug, but after reporting it, it's apparently as designed. It's even in the docs.
Note that this will not work with E_STRICT mode enabled. It also will not work if you declare a method as static.
The difference is that static functions can be used without having to create an instance of the class.
Have a look at this great PHP OOP beginner tutorial here. It explains in more detail with an example under the Static Properties and Methods section.
Second bit shouldn't work as you should call it by
$something = new something();
$something->doit();
Static functions allows you to call a function within a class without consturcting it.
So basically if you have a class to handle users, so a function that logs the user in should be a static function, as in the constructor of that class you will probably gather the user information and you cannot do so without logging him in.
Your second example is wrong. Using a static method does not create an instance of the class. Your second example should look like this:
$x = new something();
$x->doit();
Static methods should be declared static for minimum two reasons:
a) when using E_STRICT error_reporting, calling non static method as static will generate error:
Strict standards: Non-static method something::doit() should not be called statically
b) based on keyword static some IDE's filter method possible to run at auto-complete.
Her is my code:
class MyClass
{
public $prop;
public function method ()
{
echo $this->prop;
}
}
Then somewhere in the code, accidently:
MyClass::method();
I would expect to have an interpretation error about the above line, because the called method is not static. Instead, the method was called, and I received an exception about $prop not existing. So i understand that the method was called as a static method, even though it's not.
Does it work this way? (Why the hell? )
Calling non-static methods statically generates an E_STRICT level warning.
http://php.net/manual/en/language.oop5.static.php
I suppose you have E_STRICT warnings suppressed. It works (likely for legacy reasons), but it's not recommended.
For legacy reasons, any class method could be called statically even if it wasn't declared static, because you previously couldn't declare them as such. In those cases, $this would simply refer to nothing because it's not an object-context variable.
In PHP 5 you get an E_STRICT warning for calling non-static methods statically (as you just did).