PHP static function being called in dynamic environment - php

Since when PHP allows to call static function like a dynamic function?
I am using php 5.3.2
class weird{
public static function iamstatic($calledFrom){
echo "I am a static function called with a $calledFrom operator\n";
}
public function test(){
self::iamstatic("static");
$this->iamstatic("dynamic");
}
}
$c = new weird();
$c->test();
weird::iamstatic("Static outside class");
$c->iamstatic("Dynamic outside class");
This outputs :
I am a static function called with a static operator
I am a static function called with a dynamic operator
I am a static function called with a Static outside class operator
I am a static function called with a Dynamic outside class operator

It was always possible for php5.0 and above.
http://3v4l.org/14PYp#v500
Also, it's mentioned in documentation (static)
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).
And this not a bug (static methods assigned to instances)

I wasn't aware this was possible, although it probably doesn't matter. Your static method won't let you reference $this, so you won't get very far using it in a non static context. If you don't need to refer to $this, then it won't matter either way, which is what your code is proving.

Related

using functions inside constructors php

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

Accessing static methods using newly created $obj or using class Name

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

Accessing the variables from a PHP Anonymous Function

I have the following class with static variables. How can I access the static functions of a class from within an anonymous PHP function?
class MyClass {
public static function MyFunction(mylocalparam){
MyStaticClass:MyStaticMethod(function(myparam) use(mylocalparam){
MyClass::MyFunction2(mylocalparam);
});
}
private static function MyFunction2(someobject){
}
}
I am having trouble accessing the function "MyFunction2" from within the anonymous class. Could you please advice on how to rectify this?
Not going to happen. You need to make the static function public. The anonymous function doesn't run inside the scope of MyClass, and therefore doesn't have access to private methods contained within it.
Statically is not possible, but if you want you can pass the method you want to call via parameter as of type callback.
If you change the entire class to be an instance class (deleting all the static keywords) then you can use $this inside the anonymous function to call any method of the class you are in.
From the PHP manual:
Closures may also inherit variables from the parent scope.
As specified:
In version 5.4.0 $this can be used in anonymous functions.
class MyClass {
public function MyFunction($mylocalparam){
MyStaticClass:MyStaticMethod(function($myparam) use($mylocalparam){
$this->MyFunction2($mylocalparam);
});
}
private function MyFunction2($someobject){
}
}

Static methods in PHP

Why in PHP you can access static method via instance of some class but not only via type name?
UPDATE: I'm .net developer but i work with php developers too. Recently i've found this moment about static methods called from instance and can't understand why it can be usefull.
EXAMPLE:
class Foo
{
public static Bar()
{
}
}
We can accept method like this:
var $foo = new Foo();
$foo.Bar(); // ??????
In PHP
the class is instantiated using the new keyword for example;
$MyClass = new MyClass();
and the static method or properties can be accessed by using either scope resolution operator or object reference operator. For example, if the class MyClass contains the static method Foo() then you can access it by either way.
$MyClass->Foo();
Or
MyClass::Foo()
The only rule is that static methods or properties are out of object context. For example, you cannot use $this inside of a static method.
Class Do {
static public function test() {
return 0;
}
}
use like this :
echo Do::test();
Why in PHP you can access static method via instance of some class but not only via type name?
Unlike what you are probably used to with .NET, PHP has dynamic types. Consider:
class Foo
{
static public function staticMethod() { }
}
class Bar
{
static public function staticMethod() { }
}
function doSomething($obj)
{
// What type is $obj? We don't care.
$obj->staticMethod();
}
doSomething(new Foo());
doSomething(new Bar());
So by allowing access to static methods via the object instance, you can more easily call a static function of the same name across different types.
Now I don't know if there is a good reason why accessing the static method via -> is allowed. PHP (5.3?) also supports:
$obj::staticMethod();
which is perhaps less confusing. When using ::, it must be a static function to avoid warnings (unlike ->, which permits either).
In PHP, while you're allowed to access the static method by referencing an instance of the class, you don't necessarily need to do so.
For example, here is a class with a static function:
class MyClass{
public static function MyFunction($param){
$mynumber=param*2;
return $mynumber;
}
You can access the static method just by the type name like this, but in this case you have to use the double colon (::), instead of "->".
$result= MyClass::MyFunction(2);
(Please note you can also access the static method via an instance of the class as well using "-->"). For more information: http://php.net/manual/en/language.oop5.static.php
In PHP 7 it seems to be absolutely necessary for you to be able to do $this->staticFunction(). Because, if this code is written within an abstract class and staticFunction() is also abstract in your abstract class, $this-> and self:: deliver different results!
When executing $this->staticFunction() from a (non-abstract) child of the abstract class, you end up in child::staticFunction(). All is well.
However, executing self::staticFunction() from a (non-abstract) child of the abstract class, you end up in parent::staticFunction(), which is abstract, and thusly throws an exception.
I guess this is just another example of badly designed PHP.
Or myself needing more coffee...

PHP and Static Variables in Object Member Functions

Up until today, I thought I had a fairly good grasp of how the static modifier worked. I know that (in laymans terms) a static variable in a function does not 'reset' across calls to that function, and I know that static variables and functions on a class are accessible by calling upon them through the class itself (not an instantiation of the class).
My problem is this: today I found that if I declare a static variable inside of a non-static function on a class, all instantiations of that class share that static variable in separate calls to the member function.
For example:
class A {
public function GetValue() {
static $value = 0;
$value++;
return $value;
}
}
$instance_1 = new A();
$instance_2 = new A();
echo $instance_1->GetValue();
echo $instance_1->GetValue();
echo $instance_2->GetValue();
echo $instance_2->GetValue();
echo $instance_1->GetValue();
echo $instance_1->GetValue();
Notice that the GetValue function is neither declared as static or used in a static way (as in, called on the class itself).
Now, I always assumed that this would output: 121234
Instead, I find that it will output: 123456
Like I say, I would understand this if the static variable $value was inside of a static function. However, with it being inside a non-static function I just assumed that it would only be 'tied' to the function 'within' each individual instantiation.
I guess my question is twofold, then... 1) is this a bug or expected behaviour? 2) do other languages treat these 'static inside non-static' variables the same way, or is this unique to PHP?
This is expected.
This is also the case in C++ (and probably others as well).
You should think of non-static class member functions as if they were just like ordinary functions, but with an implicit $this argument that is automatically provided by the interpreter. (That's exactly how they're implemented in most languages.)
I've copied the following information from this article by Josh Duck: http://joshduck.com/blog/2010/03/19/exploring-phps-static-scoping/
Static variables have been available since PHP 4 and allow you to define a persistent variable that is only accessible from the current function. This allows you to encapsulate state into a function or method and can eliminate the need for classes where a single function will suffice.
When a static variable is defined inside a class method they will always refer to the class on which the method was called. In doing this they act almost like properties referenced through static, though there are subtle differences.
Static variables can’t preserve the calling class scope. This can be potentially problematic if you have an inherited method containing a static variable that is called from both inside and outside its class.
As far as I know, all languages with static variables treat them this way. Think of static variables as global variables that can only be accessed from a certain scope.

Categories