In PHP there is instance methods and static methods (just these two types)? Then we can call either of these statically or non-statically (is the name "dynamically"?)?
So we can:
- Call an instance method statically;
- Call an instance method non-statically;
- Call a static method statically;
- Call a static method non-statically (all four correct?)
How would the code for these four look? Are there any good websites explaining this? I am currently reading the following url:
http://php.net/manual/en/language.oop5.basic.php
...and I am not understanding this:
"$this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object)."
How would the code look for calling a method statically from a secondary object? I mean, staticall calling vs. non-statical calling, what this is?
You are not supposed to call non static methods statically.
Some examples
Tests
The idea behind calling static non-statically is that its permissible to use static properties inside non static methods. For example:
So this is fine, now the flip side is calling non-static methods inside of a static methods.
A few other things to point out
Now if you want exact answers:
We can show this by example using the above class
Result (PHP7+)
AS you can see we get a Fatal error when trying to access
$this
Result (PHP5 something)
Now we don't get the Fatal error in pr PHP7 (something), and at first glance this may seem ok. Like its saying it's fine to run this way. However if you look closer
Undefined variable: this
this is actually worse then the Fatal error, because now you class can produce unexpected results.If we had called this normal:
Result
So I want to give you one quick example on
self
vsstatic
, it can be really confusing.Result
When you use
static
it's called late static binding. What this means is that the static value is bound late. So what doe that really mean? It means the value is resolved at run time, not when the class is parsed by PHP.bar
is a child offoo
.foo
, all our calls go throughfoo
.boo
only exists in the parent, ie. it's not overwritten by a child method.For the fist one, we get the value of
foo
because we are using self, so it only knows about itself.For the second one, we get the value of
bar
because we are using static, it's bound late and can use the child's value which is set in it's declaration of the property$test
. So even though the parent doesn't know anything about the child (typical) it can use it's value because it's resolved at run time.for the third one, we get the value of
bar
because it knows about itself, and the method is defined in itself.foo
knows nothing about this method even if it did it would be overwritten by the deceleration of it in the child.for the fourth one, again we get the value of
bar
this is because even with late static binding we pull the same data, the value ofbar
becausebar
is the class we instantiated, so at run time the value defined in's property is the value.So in the last 2 the value is the same, it's because self and static resolve the same information regardless of when they are called.
This can be very confusing so hopefully it makes sense. Also as I have shown don't be afraid to make some simple classes like this and test the values you get. That's how I learned.
UPDATE
You mentioned using static calls was considered bad.
I think most of that comes from Dependency issues. This is tight coupling between the name of the class and your code. When using an instance, you assign it to variable and use the name 1 time when calling new. When calling static you use the class name every time. The problem this causes is if you decide to rename the class. With instance calls you only need to replace the name where you call new, with static you have to replace it everywhere.
For example consider this.
And compare it to this.
Now say you change the class name. For the first one you have to replace it in one place. For the second one you have to replace it evey where you used it. You can get around this somewhat by using a string variable.
But with this you can get into a lot of trouble too, because most IDE's wont be able to resolve the class and do auto-completion.
Also if you do type hinting on inputs to other classes
This doesn't work very well on static classes, because you are passing in a string then (the class name).
Namespaces can be an issue. With instantiation, you only need to put the use statement in the file you instantiate the class in. With static, you have to put it everywhere, or include it in every call.
I am sure there are other reasons, but these are the main ones for me.
Let's look the following code:
It will display
class A property B
You are accessing a property from
B
, inA
class, with$this
. This will not work on PHP 7+, and you will get the following warning on PHP 5.6:It "works", but you are not supposed to call non-static methods from static context.