Sorry if the title looks odd, I don't know how to call it. I was inspecting a framework and I wonder how this works?
<?php
//namespace and use
abstract class Model {
//...
public function __call($method,$params){
//some stuff
return static::$$method;
}
}
It's an abstract class, so to what class will static refer to? (considering it's not extending anything) I tried to var_dump method but that method is not in that class. And why does it have a double dollar sign.
EDIT: Oh it will call the __callStatic method. I need pills.
It's called "late static binding" and unlike self, which always refers to the context ("class"), where it is defined, it refers always to the context it is called on.
Related
As of version 5.3, PHP have implemented the Late Static Bindings, which can be used to reference the called class in a context of static inheritance.
In general, the static:: seems to be more useful than self:: in a lot of contexts, mainly if you like to able that your classes and methods be extended. Seems do not make sense you call a method from your class like self::someMethod(), because it can cause a not reliable behaviour if you extended this class and override this method.
For instance (live example):
class ParentClass {
public static function someMethod () { return 'ParentClass::someMethod()'; }
public static function getSomeMethodData() { return self::someMethod(); }
}
class ChildClass extends ParentClass {
public static function someMethod () { return 'ChildClass::someMethod()'; }
}
ChildClass::getSomeMethodData();
// Return -> "ParentClass::getSomeMethodData()"
// Not -> "ChildClass ::getSomeMethodData()"
You can change this behaviour if you replace the self:: with the static::.
Okay, after the blábláblá, my question is: there are some context where we SHOULD use the self:: instead of static:: for methods or properties?
I mean, can I replace all self:: with static:: without it change my code behaviour for all my codebase?
Edit #1: to make it more clear. Which case I MUST use self:: instead of static::? I mean, in which context is inevitable the use of self::? For instance, I can consider self::class, but it can be replaced by __CLASS__ (despite I still prefer the self::class version).
There is a difference between self and static. If you call the method with static, it will be run in the context of the class where the method actually is.
I have a child class that extends a class with only static methods. I would like to make this child class a singleton rather than static because the original developer really wanted a singleton but used static instead (obvious because every method in the static class calls the Init() function (basically a constructor)).
Most of the methods in the parent don't need to be overwritten in the child, but I would like to avoid having to write methods like this:
public function Load($id)
{
return parent::Load($id);
}
when I would prefer not to overwrite the method at all and just use:
$child->Load($id);
Is it possible to call a static method non-statically? Is it possible to extend a static object with an instance object? I know I can try it and it will likely work (PHP is very forgiving), but I don't know if there is anything I should be concerned about.
Can you inherit static methods?
Yes
Can you override static methods?
Yes, but only as of PHP 5.3 do they work as you would expect: http://www.php.net/manual/en/language.oop5.static.php (ie. self binds to the actual class and not the class it's defined in).
Is it possible to call a static method non-statically?
Yes, but will lose $this. You don't get a warning (yet) but there also isn't really a reason to call it the wrong way.
Two part answer.
First, about the titular question: calling a static method non-statically is perfectly fine; #SamDark's comment is correct. It does not produce a warning, nor does it cause any kitten murdering. Try it:
<?php
class test {
public static function staticwarnings(){
echo "YOU ARE (statically) WARNED!\n";
}
}
error_reporting(E_ALL);
$test = new test();
echo "\n\ncalling static non-statically\n";
$test->staticwarnings();
If you had an instance reference, $this, in that static method, then you would get a fatal error. But that is true regardless of how you call it.
Once again, there isn't a warning, nor any kitten killed.
Second part of the answer:
Calling an overridden parent function from an overriding child class requires something called "scope resolution". What the OP is doing in their method is NOT calling a static method. (Or at least, it doesn't have to be; we can't see the parent implementation). The point is, using the parent keyword is not a static call. Using the :: operator on an explicit parent class name is also not a static call, if it is used from an extending class.
Why is that documentation link so strangely named? It's literally Hebrew. If you've ever run into an error related to it, you might have observed the delightfully-named parser error code T_PAAMAYIM_NEKUDOTAYIM.
With learning fuelPHP, I am introduced on calling classes using scope resolution, or :: in sense. Typically, when we call a method in a class we do this ...
$myclass = new myclass();
$myclass->mymethod();
On fuel, methods are usually called in this manner ...
myclass::mymethod();
I was wondering if there are any difference between the two? Is the scope resolution is something of an update on 5.3 as well ... if not, which one is ideal, or when should I use these.
Thanks.
The scope resolution operator is used to access either class constants like ::const, static variables like ::$var or call static methods like ::method().
See http://php.net/manual/en/language.oop5.static.php
Static methods can be called without having an instance of the class they are defined in. They're defined in that class with the static keyword.
For example, one of CakePHP's static methods is defined like this:
class ClassRegistry {
// ...
public static function &getInstance() {
// ...
}
}
... which you can call like ClassRegistry::getInstance().
Without the static keyword, you'd need an instance of the ClassRegistry class to call that function.
You can read more here, especially about why using static methods in your own code can sometimes be a bad idea: http://kore-nordmann.de/blog/0103_static_considered_harmful.html
I am not sure how would myclass::mymethod(); work, since I use such syntax only when I am calling a STATIC class.
MyClass::DoSomething();
would call a static method named DoSomething()
while
$instance = new MyClass();
$instance->DoSomething();
would call the instance method.
I have not tested it but I believe you will run into an error if you do $instance::DoSomething()
I think the best way to understand why there is a static call and what it does behind the scene is to check this FuelPHP blog's entry: http://fuelphp.com/blog/2011/05/why-did-you-do-that
The obvious difference is that the first solution $myObject->myMethod() it's a dynamic call : you need an instance to execute myMethod().
In the second solution, MyClass::myMethod() is a static call. The class acts as a sort of namespace where a function belong. You don't need an instance for that.
I guess my question is would
static class example1{
function example1_function(){};
}
and
class example2{
static function example2_function(){};
}
lead to the same result, which is both example1->example1_function() and example2->example2_function() have the same callabilty. Would both be defined as static and usable as such?
PHP does not allow you to declare a class static.
To call a static method, you must use the :: operator.
You cannot declare a class as a static class, as stated by other members here, but there is a method where you can stop the class from becoming an object, you can use the abstract keyword to specify the object should not be instantiated using the new keyword, this is good for inheritance etc.
abstract class Something
{
}
Doing new Something would trigger an error stating you cannot instantiate the class, you can then declare your static methods like so:
abstract class Something
{
public static function Else()
{
}
}
You still have to declare you methods as static, this is just the way it is.
and then you can use like so:
Something::Else();
Hope this clears up a few thing's
As has already been mentioned in the comments, the static keyword is not used for classes in that way (syntax).
http://php.net/manual/en/language.oop5.static.php
I'm a Java developer who has turned to the dark side over the last couple of weeks as I've been trying to write some code in PHP for the first time ever.
Most stuff seems familiar, methods become functions, . becomes ->, variables have a $ in front and you never have any idea what type they are, I get it, but I'm totally stumped by the $this keyword.
I expect $this to call a function in the current class as in java this.myCoolMethod(), but often as I poke through the open source project I'm going through, $this->myCoolMethod() calls a function in a totally different class!
What is happening here? What does '$this' actually mean?
Thank you for any help.
John
The reason it sometimes calls a method in a totally different class, is because that class probably extended another class with that method.
Here is a quick example:
class bla {
public function __construct() {}
public function whatwhat() {
echo "what....";
}
}
class lala extends bla {
public function __construct() {}
}
$lalaObj = new lala();
$lala->whatwhat();
As you can see, even though whatwhat() isn't in the class, it inherits it from the class it extends.
Hope that helps.
You should take a look at what Inheritance is.
$this, within a method, refers to the object to which the method belongs. If an object belongs to a class that extends another class, then it may inherit methods from the parent class, which may be called using $this->method_name(), just as with any other method.
$this actually refers to the current instance of the class.
$this->myCoolMethod() calls a function
in a totally different class!
Can you provide an example of this? The only circumstance in which the myCoolMethod() might not be defined in the class itself is if it is defined in a parent or inherited class
$this refers to whatever instance you're in. So if I extended Class_A to become Class B, and called methodName within Class_B, that would invoke Class_B::methodName and not Class_A::methodName.
I'm not sure how to explain clearer without knowing what context you're having difficulties, but try echoing __CLASS__ next to where you're using $this to give you the current class's name you're in.