I came across something like this, and am not sure what to make off it. Is there any good reason to do this, or to avoid it?
class Foo {
static public function bar() {}
}
someMethod() {
$instanceOfFoo->bar();
}
The PHP documentation says:
[...] A property declared as static can not be accessed with an instantiated class object (though a static method can).
[...] Static properties cannot be accessed through the object using the arrow operator ->.
without specifying anything special for static methods being called by ->. You should definitely avoid it though, because it causes confusion to the reader who's expecting $obj->meth() to be a non-static method and Cls::meth() a static method.
Surprisingly this behavior is not triggering any error. The reason for this is that a static method, called by $object->method() is internally translated to className::method() at run time (with the only difference being that $this = NULL is set).
You can call the particular function as below.
Foo::bar();
You don't have to create an object to call a static function. Basically we write static functions to call the function without an instance of the class in which it's defined.
It's okay to call a static function with an object but why do so when you have a simpler and cleaner method.
Related
In an effort to keep my code clean, I am attempting to replace a whole bunch of code in my constructor with a function. I believe I am calling the function correctly but i'm not able to assign values to the variables as intended.
public function __construct($docID) {
self::getDocumentInfo($docID);
self::getTranscriptionInfo($docID);
}
private static function getTranscriptionInfo($docID) {
$this->documentTranscription = 5;
}
Im getting an error "PHP Fatal error: Using $this when not in object context in ...". This is simplified for postings purpose, but would it be better just have a very large constructor and skip the functions all together? Or is their a better way to assign values?
A static method is not a part of the class instance. The static keyword means the method can be called within your class but it won't have any of the instance variables.
Remove the static keyword and change this:
self::getDocumentInfo($docID);
self::getTranscriptionInfo($docID);
to this:
$this->getDocumentInfo($docID);
$this->getTranscriptionInfo($docID);
Using $this means it will be calling it within the right instance context.
Some info the static keyword (added emphasis in italics):
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can).
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.
Source
http://php.net/manual/en/language.oop5.static.php
See the class definition below:
I am currently using 5.3.9 version of PHP
class A{
static function ab(){
echo "static function ab<br>";
}
public function xy(){
echo "public function xy<br>";
}
}
$obj = new A();
$obj->ab();
A::ab();
Both functions call give the same output without any error
static function ab
static function ab
How it is possible that static method can also be called by class object?
Because static method only calls by using class name only?!
Now what is the difference between accessing these two ways to call static method?
Referring to php.net website
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).
A big difference is
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.
Refer to the page php.net/manual/en/language.oop5.static.php for more details
As long as you are just echoing a simple string, there's no difference, if your method will be declared static or public, since static method can also be called with the object instance. As of PHP 5.5 an error will raise if you call your public method with a static way. However, the static method can be called with classname::staticMethod() so the page should only know about the class, but not really needs an instance of it.
The other deal is the method content. As I said, if you just echo a string, you don't need a static method for that. A static method is out of the object context. That means you cannot access properties or methods from the current object via $this
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 am using PHP 5.2
I have the following code:
class MyClass {
public function __construct() {}
public static function stuff() {
echo 'This is static! <br />';
}
}
$myClass = new MyClass();
MyClass::stuff(); // Reference by class.
$myClass->stuff(); // Reference by instance of class.
The output works in both cases here is the output:
This is static!
This is static!
Is there a problem using the 2nd way of referencing versus the 1st?
Since I am not allowed to have a non-static function with the same signature as the static one above that won't be an issue. I want the function to be static because there is also a speed boost when using static functions.
Am I missing anything or is the only issue here regarding the semantics of how the -> dereference syntax does not indicate this is a static function?
The docs explicitly say it's okay:
A property declared as static can not
be accessed with an instantiated class
object (though a static method can).
However, it's clearer to use ::. I also question the idea that the static method is significantly faster, particularly when no instance fields are used. You should do profiling before you start altering the semantics of your application for performance.