The mysterious behaviour of __callStatic method - php

SO question Weird behaviour with triggering __callStatic() from non-static method is great because it explains the weird behaviour with the __callStatic not being called from within the class itself (Note that I don't see this behaviour in 5.3.3 but in 5.3.8 and 5.3.12). It seems that the __callStatic can only be invoked from outside the class. That's now a fact. But what do I do if I really want the __callStatic to be called from within my class? What syntax should I use to get over the issue?

It does not have to be from outside the class, just not from object context (i.e. where $this is an instance of the class). So you can wrap this call in a static method, for example:
class TestCallStatic
{
public function __call($func, $args)
{
echo "__call($func)";
}
public static function __callStatic($func, $args)
{
echo "__callStatic($func)";
}
public function test()
{
self::_test();
}
protected static function _test()
{
self::i_am_static();
}
}
$test = new TestCallStatic();
$test->test();
Output:
__callStatic(i_am_static)

You could abstract the functionality to another method like Class::magicCall($method, $args) and call that from within __callStatic(). That way you can also access that functionality by simply calling Class::magicCall() directly.

Related

How to hide some fields through a trait in Laravel [duplicate]

I have this method that I want to use $this in but all I get is: Fatal error: Using $this when not in object context.
How can I get this to work?
public static function userNameAvailibility()
{
$result = $this->getsomthin();
}
This is the correct way
public static function userNameAvailibility()
{
$result = self::getsomthin();
}
Use self:: instead of $this-> for static methods.
See: PHP Static Methods Tutorial for more info :)
You can't use $this inside a static function, because static functions are independent of any instantiated object.
Try making the function not static.
Edit:
By definition, static methods can be called without any instantiated object, and thus there is no meaningful use of $this inside a static method.
Only static functions can be called within the static function using self:: if your class contains non static function which you want to use then you can declare the instance of the same class and use it.
<?php
class some_class{
function nonStatic() {
//..... Some code ....
}
Static function isStatic(){
$someClassObject = new some_class;
$someClassObject->nonStatic();
}
}
?>
The accessor this refers to the current instance of the class. As static methods does not run off the instance, using this is barred. So one need to call the method directly here. The static method can not access anything in the scope of the instance, but access everything in the class scope outside instance scope.
It's a pity PHP doesn't show a descriptive enough error. You can not use $this-> inside a static function, but rather use self:: if you have to call a function inside the same class
In the static method,properties are for the class, not the object.
This is why access to static methods or features is possible without creating an object.
$this refers to an object made of a class, but $self only refers to the same class.
Here is an example of what happens when a method of a class is called in a wrong way. You will see some warnings when execute this code but it will work and will print: "I'm A: printing B property". (Executed in php5.6)
class A {
public function aMethod() {
echo "I'm A: ";
echo "printing " . $this->property;
}
}
class B {
public $property = "B property";
public function bMethod() {
A::aMethod();
}
}
$b = new B();
$b->bMethod();
It seams that the variable $this, used in a method which is called as a static method, points to the instance of the "caller" class. In the example above there is $this->property used in the A class which points to a property of the B.
EDIT:
The pseudo-variable $this is available when a method is called from within an object context. $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).
PHP > The Basics

Call a private $var via a static method in php without instanciating any object [duplicate]

I have this method that I want to use $this in but all I get is: Fatal error: Using $this when not in object context.
How can I get this to work?
public static function userNameAvailibility()
{
$result = $this->getsomthin();
}
This is the correct way
public static function userNameAvailibility()
{
$result = self::getsomthin();
}
Use self:: instead of $this-> for static methods.
See: PHP Static Methods Tutorial for more info :)
You can't use $this inside a static function, because static functions are independent of any instantiated object.
Try making the function not static.
Edit:
By definition, static methods can be called without any instantiated object, and thus there is no meaningful use of $this inside a static method.
Only static functions can be called within the static function using self:: if your class contains non static function which you want to use then you can declare the instance of the same class and use it.
<?php
class some_class{
function nonStatic() {
//..... Some code ....
}
Static function isStatic(){
$someClassObject = new some_class;
$someClassObject->nonStatic();
}
}
?>
The accessor this refers to the current instance of the class. As static methods does not run off the instance, using this is barred. So one need to call the method directly here. The static method can not access anything in the scope of the instance, but access everything in the class scope outside instance scope.
It's a pity PHP doesn't show a descriptive enough error. You can not use $this-> inside a static function, but rather use self:: if you have to call a function inside the same class
In the static method,properties are for the class, not the object.
This is why access to static methods or features is possible without creating an object.
$this refers to an object made of a class, but $self only refers to the same class.
Here is an example of what happens when a method of a class is called in a wrong way. You will see some warnings when execute this code but it will work and will print: "I'm A: printing B property". (Executed in php5.6)
class A {
public function aMethod() {
echo "I'm A: ";
echo "printing " . $this->property;
}
}
class B {
public $property = "B property";
public function bMethod() {
A::aMethod();
}
}
$b = new B();
$b->bMethod();
It seams that the variable $this, used in a method which is called as a static method, points to the instance of the "caller" class. In the example above there is $this->property used in the A class which points to a property of the B.
EDIT:
The pseudo-variable $this is available when a method is called from within an object context. $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).
PHP > The Basics

A class with both normal and static interfaces

I need a class that would let the user take advantage of both normal (non-static) methods and static methods. The actual implementation would reside in the static methods, which would be called by virtual non-static methods of the same name via the magic __call method. The problem however is that, when calling a non-static method in this way, PHP thinks that the programmer made a mistake and the static method was actually meant to be called:
class AClass
{
public static function method ()
{
// implementation
}
public function __call ($name, $arguments)
{
var_dump("Hello");
call_user_func_array("AClass::$name", $arguments);
}
}
$obj = new AClass;
$obj->method();
So "Hello" is no being output when invoking method method on the object but is being output if trying to invoke a method with any other name. Any way to achieve the correct behavior while preserving method naming?
I don't really see why you would try to do that but this seems to work :
class AClass
{
protected static function method ()
{
echo "method()\n";
}
public function __call ($name, $arguments)
{
echo("Hello normal\n");
call_user_func_array("self::$name", $arguments);
}
public static function __callStatic($name, $arguments)
{
echo("Hello static\n");
call_user_func_array("self::$name", $arguments);
}
}
$obj = new AClass;
// Normal call
$obj->method();
// Static call
AClass::method();
Output :
Hello normal
method()
Hello static
method()
The thing is, accordingly to its documentation, the __call method is only used if a function is inaccessible from the context you called it from.
So since in your case the function was public, there was no need to use it (even if with some settings it displays a warning).
If you make it "protected" or "private", it can't be called from the outside and then __call is used.
Because __call doesn't care about static calls, you also have to use __callStatic (available in PHP >=5.3) if you still need to call AClass::method from outside your class.

Weird behaviour with triggering __callStatic() from non-static method

I found this weird behaviour with PHP classes (v5.3.8).
You have:
class foo {
function __call($func, $args) {
if ($func == 'bar')
echo "non-static __call";
}
static function __callStatic($func, $args) {
if ($func == 'bar')
echo "__callStatic";
}
function callMe() {
self::bar();
}
}
Then you do:
foo::bar() // outputs '__callStatic' as expected.
$f = new foo;
$f->callMe(); // outputs 'non-static __call', as I did not expect.
You see, a non-existent static method called from a non-static function triggers __call() instead of __callStatic(). I was wondering if this is supposed to work like this or is this some kind of bug?
[EDIT]
I forgot to try static::bar(); on callMe() but no, it didn't work either.
I (think I) understand inhan's comment but still... if I'm calling the class itself, not the instance or object, immediate logic for me says it should trigger __callStatic(). Oh well.
Thank you for your answers/comments.
You might be confused by what these things mean from within the context of a class method:
class B extends A {
public function test() {
A::foo();
self::foo();
static::foo();
}
}
None of those mean "call the static method named foo." It simply means "call the method named foo" at the place in the inheritance tree as specified by what is left of the colons.
Normally, without magic, you only have one function named foo, so the meaning is straightforward. However, when you overload with both magic methods, the call is ambiguous. PHP defaults to using __call() before __callStatic().
Static methods, variables belongs to classes not to objects so i think this is supposed to work like this.

Using $this inside a static function fails

I have this method that I want to use $this in but all I get is: Fatal error: Using $this when not in object context.
How can I get this to work?
public static function userNameAvailibility()
{
$result = $this->getsomthin();
}
This is the correct way
public static function userNameAvailibility()
{
$result = self::getsomthin();
}
Use self:: instead of $this-> for static methods.
See: PHP Static Methods Tutorial for more info :)
You can't use $this inside a static function, because static functions are independent of any instantiated object.
Try making the function not static.
Edit:
By definition, static methods can be called without any instantiated object, and thus there is no meaningful use of $this inside a static method.
Only static functions can be called within the static function using self:: if your class contains non static function which you want to use then you can declare the instance of the same class and use it.
<?php
class some_class{
function nonStatic() {
//..... Some code ....
}
Static function isStatic(){
$someClassObject = new some_class;
$someClassObject->nonStatic();
}
}
?>
The accessor this refers to the current instance of the class. As static methods does not run off the instance, using this is barred. So one need to call the method directly here. The static method can not access anything in the scope of the instance, but access everything in the class scope outside instance scope.
It's a pity PHP doesn't show a descriptive enough error. You can not use $this-> inside a static function, but rather use self:: if you have to call a function inside the same class
In the static method,properties are for the class, not the object.
This is why access to static methods or features is possible without creating an object.
$this refers to an object made of a class, but $self only refers to the same class.
Here is an example of what happens when a method of a class is called in a wrong way. You will see some warnings when execute this code but it will work and will print: "I'm A: printing B property". (Executed in php5.6)
class A {
public function aMethod() {
echo "I'm A: ";
echo "printing " . $this->property;
}
}
class B {
public $property = "B property";
public function bMethod() {
A::aMethod();
}
}
$b = new B();
$b->bMethod();
It seams that the variable $this, used in a method which is called as a static method, points to the instance of the "caller" class. In the example above there is $this->property used in the A class which points to a property of the B.
EDIT:
The pseudo-variable $this is available when a method is called from within an object context. $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).
PHP > The Basics

Categories