I'm dinamically instantiating a class, but I want to know if there's a way to call a method from this instance, thanks
Code:
if(class_exists($class_name)){
$class = new $class_name;
$class.method();
}
class foo implements bar {
public function method(): void {
echo "method called";
}
}
Expected Result:
Call the method from the object
Actual Result:
Error: Call to undefined function method()
In php use the arrow to call the class's function.
$class.method();
should be
$class->method();
alternatively if your method is declared as static you can use it like so
foo::method();
Related
I have a class with the structure below. And Im trying to call a method of the class with "$this->getTopProds($prodsInfo)" however Im getting an error:
"Cannot use '$this' in non-object context.intelephense(1030)"
And on the page the error is "Non-static method App\JsonResponse\Prod\ProdRender:: getTopProds() cannot be called statically".
Do you know what can be the issue?
class ProdRender
{
public static function hotel(array $prodsInfo): array
{
dd($this->getTopProds($prodsInfo));
}
private function getTopProds(array $prodsInfo)
{
//
}
}
No, we can't use this keyword inside a static method. “this” refers to the current instance of the class. But if we define a method as static, the class instance will not have access to it
To keep using the other method call inside the static method you need to change the second method getTopProds to be static too, and call it with self
self::getTopProds($prodsInfo)
In case you need it try this:
<?php
class ProdRender
{
public function hotel(array $prodsInfo)
{
return $this->getTopProds($prodsInfo);
}
private function getTopProds(array $prodsInfo)
{
return $prodsInfo;
}
}
$ho = new ProdRender();
$response = $ho->hotel(["fadf","ceec"]);
var_dump($response);
class MyClass {
var $lambda;
function __construct() {
$this->lambda = function() {echo 'hello world';};
// no errors here, so I assume that this is legal
}
}
$myInstance = new MyClass();
$myInstance->lambda();
//Fatal error: Call to undefined method MyClass::lambda()
So what is the correct syntax for reaching class variables ?
In PHP, methods and properties are in a separate namespace (you can have a method and a property with the same name), and whether you are accessing a property or a method depends of the syntax you are using to do so.
$expr->something() is a method call, so PHP will search something in the class' list of methods.
$expr->something is a property fetch, so PHP will search something in the class' list of properties.
$myInstance->lambda(); is parsed as a method call, so PHP searches for a method named lambda in your class, but there is no such method (hence the Call to undefined method error).
So you have to use the fetch property syntax to fetch the lambda, and then call it.
Since PHP 7.0, you can do this with ($obj->lambda)():
($obj->lambda)();
The parentheses make sure that PHP parses ($obj->lambda) as fetch the property named lambda. Then, () calls the result of fetching the property.
or you can do this with ->lambda->__invoke():
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke is one of PHP's magic methods. When an object implements this method, it becomes invokable: it can be called using the $var() syntax. Anonymous functions are instances of Closure, which implements __invoke.
Or assign it to a local variable:
$lambda = $myInstance->lambda;
$lambda();
Or call it using call_user_func:
call_user_func($myInstance->lambda);
call_user_func can call any callable, including anonymous functions.
Alternatively, if this is a common pattern in your code, you can setup a __call method to forward calls to your lambda:
class MyClass
{
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello world!\n";
};
}
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
Now this works:
$myInstance = new MyClass();
$myInstance->lambda();
Since PHP 5.4 you can even do that in a trait:
trait LambdasAsMethods
{
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
class MyClass
{
use LambdasAsMethods;
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello World!\n";
};
}
}
$myInstance = new MyClass();
$myInstance->lambda();
You can also call your lambda function without change something in your class, using ReflectionFunction.
$myInstance = new MyClass();
$lambda = new ReflectionFunction($myInstance->lambda);
$lambda->invoke();
or if you have to pass arguments then
$args = array('arg'=>'value');
$lambda->invokeArgs($args);
I have a class setup like this:
class myClass {
public function __construct() {
echo 'foo bar';
}
}
To run it, I can simply do:
$object = new myClass;
Is there any way to run the class so __construct initiates without creating a new variable with the class object.
For example, a basic function can be run with:
functionname();
Don't call __construct directly. If you need something in the constructor to occur but you don't want an object created as a result, then use a static method.
class Thing{
public static function talk(){echo "I talk";}
}
Thing::talk(); // 'I talk'
Static methods can be called without the need for an object instance of the class.
__construct is part of a special group of methods in PHP, called Magic Methods. You don't call these directly, but PHP will call them when some event occurs. For instance when you call new on a class, __construct is executed.
Another example: if you try to get a property that doesn't exist, __get will be executed (if found):
Class Thing{
public property $name = 'Berry';
public function __get($propertyName){
return "$propertyName does not exist!";
}
}
$t = new Thing();
echo $t->name; // 'Berry'
echo $t->weight; // 'weight does not exist!';
You can try something like this if you want to avoid static:
(new MyClass)->myFunction();
I have no idea why you need this but you don't need to create a variable. You can just create object without store it anywhere.
class myClass {
public function __construct() {
echo 'foo bar';
}
}
new myClass();
In this case only the constructor will be call.
I have a woocommerce plugin that has a class Foo:
function wc_foo_init(){
class WC_Foo extends WC_Shipping_Method{
$var=get_option(); //gets an option for this session
function sayHello(){
echo $var;
}
new WC_Foo();
}
I want to call sayHello() out of the Foo class:
function bar(){
WC_Foo->sayHello();
}
But I get this error:
Fatal error: Call to a member function `sayHello` on a non-object.
You must instantiate class before make call of its methods:
$foo = new WC_Foo();
$foo->sayHello();
or if your php version is greater than 5.4 you can do:
(new WC_Foo())->sayHello();
Use $this selector if you are calling the method within the class
function bar(){
$this->sayHello();
}
If you want to call the method from other place,
you need to instantiate the class like this:
$object = new WC_Foo();
$object->sayHello();
Or make the method static like this:
public static function sayHello(){
echo "Hello";
}
And call it like this:
WC_Foo::sayHello();
// this way you dont need $object = new WC_Foo();
This might not be the full code, so it's pretty weird what you have there, but let's go.
Since you have a function to init your object, you would probably want to at least return that instance. This code might help you understand:
function init_foo(){
class foo{
function say(){
echo 'hello';
}
}
$foo1 = new Foo();
return $foo1;
}
function bar($foo3){
$foo3->say();
}
$foo2 = init_foo();
bar($foo2);
So, first we create the object and return it. Then we inject it in the bar function, just needing to call the method after that. (I used different var names so it's easier to understand scope)
<?php
class jokz {
static public $val='123';
static public function xxx() {
jokz2(self);
}
}
function jokz2($obj) {
echo $obj::$val;
}
jokz::xxx();
?>
it returns fatal error, cause the class "self" couldn't be found...
so.. how can i make that work?
passing a parameter by reference in function also don't work
function jokz2(&$obj) {
echo $obj::$val;
}
There is no object to pass (self refers to static class). You can pass the name of the class and call it that way (using call_user_func) or instantiate an object and pass $this
You would have to use $this to use the current object.