I am working on PHP code.
Here is the sample code to explain my problem:
class Foo {
public function fun1[] {
echo 'non-static';
}
public static function fun2[] {
echo "static" ;
//self::fun1[];
//Foo::fun1[];
}
}
How can I call the non-static method from the static method ?
Note: Both functions are used throughout the site, which is not known. I can't make any changes in the static/non-static nature of them.
asked Jan 13, 2017 at 9:46
RahulRahul
17.9k7 gold badges40 silver badges58 bronze badges
6
You must create a new object inside the static method to access non-static methods inside that class:
class Foo {
public function fun1[]
{
return 'non-static';
}
public static function fun2[]
{
return [new self]->fun1[];
}
}
echo Foo::fun2[];
The result would be non-static
Later edit: As seen an interest in passing variables to the constructor I will post an updated version of the class:
class Foo {
private $foo;
private $bar;
public function __construct[$foo, $bar]
{
$this->foo = $foo;
$this->bar = $bar;
}
public function fun1[]
{
return $this->foo . ' - ' . $this->bar;
}
public static function fun2[$foo, $bar]
{
return [new self[$foo, $bar]]->fun1[];
}
}
echo Foo::fun2['foo', 'bar'];
The result would be foo - bar
answered Jan 13, 2017 at 9:51
Mihai MateiMihai Matei
23.8k5 gold badges33 silver badges50 bronze badges
3
The main difference would be that you can call static methods for a class without having to instantiate an object of that class. So, in your static method try
Foo $objInst = new Foo[];
$objInst->fun1[];
But I don't see how this would make any sense in any context.
answered Jan 13, 2017 at 9:56
1
- PHP.Watch
- Versions
- 8.0
PHP 8.0 no longer allows to call non-static class methods with the static call operator [::
].
Calling non-static methods statically raised a PHP deprecation notice in all PHP 7 versions, and raised a Strict Standards notice in PHP 5 versions.
class Foo {
public function bar[] {}
}
Foo::bar[];
// Deprecated: Non-static method Foo::bar[] should not be called statically in ... on line ...
In PHP 8.0 and later, this results in a fatal error:
class Foo {
public function bar[] {}
}
Foo::bar[];
// Fatal error: Uncaught Error: Call to undefined method Foo::bar[] in ...:...
Note that this only affects calling non-static methods statically. Although discouraged, calling a static method non-statically [
$this->staticMethod[]
] is allowed.
This change is implemented throughout the engine.
Variable Functions
class Foo {
public function bar[] {}
}
['Foo', 'bar'][];
// Fatal error: Uncaught Error: Non-static method Foo::bar[] cannot be called statically in ...:...
Callables
PHP no longer considers an array with class name and a method [['Foo', 'bar']
] as a valid callable, and results in a fatal error. This includes PHP core functions that expect a callable. If such callable is passed to a function that expects a valid callable, a \TypeError
will be thrown instead
of a fatal error at call-time.
class Foo {
public function bar[] {}
}
call_user_func[['Foo', 'bar']];
call_user_func_array[['Foo', 'bar'], []];
// Fatal error: Uncaught TypeError: call_user_func[]: Argument #1 [$function] must be a valid callback, non-static method Foo::bar[] cannot be called statically in ...:...
This affects all functions ranging from call_user_func
and call_user_func_array
to register_shutdown_function
, set_error_handler
, set_error_handler
.
register_shutdown_function
function in PHP 8.0 versions until beta3 raised a PHP warning at the timeregister_shutdown_function
function is called instead of the current behavior of throwing a\TypeError
exception. This was corrected in PHP beta4.
is_callable
is_callable
function returns false
on callable that calls non-static methods statically. It returned true
prior to PHP 8.0.
class Foo {
public function bar[] {}
}
is_callable[['Foo', 'bar']]; // false
static
, self
, and parent
static
, self
, and and parent
pointers can continue to use the static call syntax inside a class.
class Test extends UpperTest{
public function foo[]: {}
public function bar[] {
static::foo[];
self::foo[];
parent::foo[];
}
}
The call above is still allowed because static
, self
, and parent
are used inside the class scope.
static::
and self::
calls are identical to $this->
calls on non-static methods, and improves readability. In the example
above, static::foo[]
and self::foo[]
calls can be safely replaced with $this->foo[]
to improve readability because foo
is not a static method.
Backwards Compatibility Impact
For existing code that get fatal errors in PHP 8.0, the fix can as simple as using the correct syntax if there is a class instance in the same scope.
class Foo {
public function bar[] {}
}
$foo = new Foo[];
- Foo::bar[];
+ $foo->bar[];
If there is no instantiated class object, and if the class can be instantiated without any parameters or side effects, it will be simple replacement as well.
class Foo {
public function bar[] {}
}
- Foo::bar[];
+ [new Foo[]]->bar[];
If the class constructor requires parameters, or tends to make any state changes, the fix can be more complicated. The instance needs to be injected to the scope the static call is made.
Note that functions that expect a callable
parameter no longer accept callables with a non-static method as static method. A \TypeError
exception will be thrown when the callable is passed, as opposed to when the callable is invoked.
class Foo {
public function bar[] {}
}
function takeCallable[callable $func] {}
- takeCallable[['Foo', 'bar']];
+ takeCallable[[new Foo[], 'bar']];
is_callable
function no
longer returns true
for such callables either.
Implementation