PHP calling class function dynamically by variables caughts exception - php

I'am trying to call a public funtion of a class with variables(php7). Therfore I do:
$module = 'frontend\\modules\\rest\\models\\Member';
$action = 'view_profile'
$response = new $module();
$response = $response1->$action;
By calling $response1->$action I get the following error:
Undefined property: frontend\modules\rest\models\Member::$view_profile
I see that the systems try to call ...Member\$view_profile and this will not work. But why is the '$' before view_profile. I've tried several variantes, but the error with the $view_profile is always there. What is wrong with this approach?

Check out this other reply: OOP in PHP: Class-function from a variable? (cannot comment, sorry...)
Anyway, this is what you are after: http://php.net/manual/en/functions.variable-functions.php
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
?>
So I guess the only thing missing is the "()" after
$response1->$action;

Related

PHP Class and Function from variable

I am working on a simple router program in PHP.
Here is my function
private function dispatch($dest)
{
$goto = explode("#", $dest);
$controller = $goto[0];
$action = $goto[1];
$clocation = require_once("../app/controllers/$controller.php");
$c = new $controller;
}
Everything works to that point. But, I want to return the results of the action (a method within the class that is instantiated as $c.
I tried :
return $c->$action
but that doesn't work.
Is there a way to do this, or do I need to try a different approach all together?
thanks
Try this
return $c->$action();
With the () for a method/function call. Otherwise PHP thinks it's a dynamic property of $c
You can test this like so:
class foo{
public $bar = 'bar';
function test(){ return 'test'; }
}
$foo = new foo();
$bar = 'bar';
$test = 'test';
echo $foo->$bar . PHP_EOL;
echo $foo->$test() . PHP_EOL;
Outputs
bar
test
Try it online
And $foo->$test would give you this notice
<br />
<b>Notice</b>: Undefined property: foo::$test in <b>[...][...]</b> on line <b>16</b><br />
Which means you either didn't mention it, don't have error reporting on, or your class has a property with the same name as that method.

how to keep php Class method in a variable

1.here's my wrong code
class classname{
function __construct(){};
public function test(){return 0;};
}
$c = new classname();
$test = $c->test;
var_dump($test); //out put NULL, I want the method $c->test
I didn't want to execute the function and store the result
there is something wrong with my code.
howto write it!
here's the code what I wanted(by Bobot):
$test = function() use ($c) { return $c->test(); };
devmyb's answer was helpful,and he/she told me why my codes not works
Bobot 、JezEmery 、devmyb ... etc
thanks for your help
You're not calling the function, you're trying to access a property (which isn't found).
$test = $c->test();
That should work.
Your question is unclear, but I guess you want to do this :
$test = function() use ($c) { return $c->test(); };
Then when you need to run your method, just run the function : $test();
I guess that some documentation about anonymous functions can help you to understand the code.
Its because you didn't have your error_reporting on else you'll get the notice, warning and fatal error too
You have typographical errors, check the updated code
class classname{
function __construct(){} // removed ;
public function test(){return 0;} // removed ;
}
$c = new classname();
$test = $c->test; // You were calling variable of your class
$test1 = $c->test(); // You were calling method of your class i.e. public function test()
var_dump($test);
var_dump($test1);
Output:
Notice: Undefined property: classname::$test in /in/HBNf9 on line 9
NULL
int(0)
This is the correct code. After a function is no ;
class classname {
function __construct(){
}
public function test() {
return 0;
}
}
$c = new classname();
$test = $c->test;

PHP: assign function to class method

How can I assign a function to a method in a class in PHP? I tried the following:
class Something{
public function __construct(){
$functionNames = array('foo', 'bar')
$variable = 'blablabla';
foreach($functionNames as $functionName){
if(method_exists($this, $functionName))
continue;
$this->{$functionName}() = function($params){ //should create the methods "foo" and "bar"
echo $variable; //should echo 'blablabla' (I know that the variable was declared outside this function, but how can I access it anyway?)
}; //the error points to here
}
}
}
But this code gives me this error:
Fatal error: Can't use method return value in write context
Does anyone know how I can assign the anonymous function to the class method, while also still being able to access variables outside that function?
You are doing foreach($functionNames as $functionName){ which means that $functionName is a string, not an array. So, don't use $functionName[0].
method_exists takes 2 parameters. One is the object and the other is the method name. It should be:
method_exists($this, $functionName)
As for creating the function, you don't need () on the left side of the =. It should be:
$this->$functionName = function($params) use($variable){
echo $variable;
};
The use($variable) is needed to tell PHP to use that variable inside the function. That's how closures work in PHP, it's different than other languages.
So, your class should look like:
class Something{
public function __construct(){
$functionNames = array('foo', 'bar');
$variable = 'blablabla';
foreach($functionNames as $functionName){
if(method_exists($this, $functionName)){
continue;
}
$this->$functionName = function($params) use($variable){
echo $variable;
};
}
}
}
Problem here is that in this way of making functions, you are not actually creating a class method, but instead creating a class variable that contains a function.
So, you need to call it like so:
$test = new Something;
$foo = $test->foo;
$foo('abc');
You can't just do $test->foo('abc');.
EDIT: Another thing you can do is use PHP's __call "magic method". This will be ran whenever you do ->funcName(), regardless of whether the method exists or not. Using that method, you can just check to see if the method called was 'foo' or 'bar'. See this example:
class Something{
private $variable;
public function __construct(){
$this->variable = 'blablabla';
}
public function __call($name, $params=array()){
if(method_exists($this, $name)){
// This makes sure methods that *do* exist continue to work
return call_user_func(array($this, $name), $params);
}
else{
$functionNames = array('foo', 'bar');
if(in_array($name, $functionNames)){
// You called ->foo() or ->bar(), so do something
// If you'd like you can call another method in the class
echo $this->variable;
}
}
}
}
With this, now you can do the following:
$test = new Something;
$test->foo('abc'); // Will echo "blablabla"

PHP invoke method using string for method name

I would like to have an array of methods in my php class, indexed with method names, so that I can do something like this:
public function executeMethod($methodName){
$method=$this->methodArray[$methodName];
$this->$method();
// or some other way to call a method whose name is stored in variable $methodName
}
I've found this for __call:
The overloading methods are invoked when interacting with properties
or methods that have not been declared or are not visible in the
current scope
However, methods I'd like to use in executeMethod are visible.
What is proper way to do that? Is it possible?
EDIT: I wanted to get a method name in the executeMethod, and then call the method of the given name, and had an idea of methods array.
you can call object methods and properties by using string with syntax
$method = 'your_method_name_as_string';
$this->$method();
from php doc
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
?>
Maybe you are looking for something like this:
public function executeMethod($methodName) {
if (isset($this->methodArray[$methodName])) {
$method = $this->methodArray[$methodName];
return call_user_func(array($this, $method));
}
throw new Exception("There is no such method!");
}
anonymous functions are available in php 5.3
i think you're trying to do something like
$tmp['doo'] = function() { echo "DOO"; };
$tmp['foo'] = function() { echo "FOO"; };
$tmp['goo'] = function() { echo "GOO"; };
$tmp['doo']();

PHP analog to C++ member pointers?

Does PHP have something similar to C++ member pointers? I want to use a member of a PHP object, whose name (the member's, not the object's) I only know at runtime. For example:
$object = new stdClass();
$object->NewMember = "value";
$member = 'NewMember';
// I don't know whether this is valid PHP,
// but you get what I'm trying to do.
echo $object->$member;
<?php
class Test
{
public $foo = 'bar';
}
$var = 'foo';
$test = new Test();
echo $test->$var;
Edit: after your update, yes, that will work.
You can use variables in member calls.
$methodName = 'some_method';
$myObj->$methodName($param);
Not sure if this will work for what you want.
In the following code I'm setting the $memberToGet at runtime:
class Person
{
public $foo = 'default-foo';
public $bar = 'default-bar';
}
$p = new Person();
$memberToGet = 'foo';
print "The Person's $memberToGet is [" . $p->$memberToGet . "]\n";
$memberToGet = 'bar';
print "The Person's $memberToGet is [" . $p->$memberToGet . "]\n";
No, PHP doesn't support (member) pointers. However you could use Reflection API.
class MyClass {
public function doSth($arg1, $arg2) { ... }
public static function doSthElse($arg1) { ... }
}
$ref = new ReflectionMethod('MyClass', 'doSth');
$ref->invokeArgs(new MyClass(), array('arg1', 'arg2'));
$ref = new ReflectionMethod('MyClass', 'doSthElse');
$ref->invokeArgs(null, array('arg1'));
As you can see in other answers you could also write:
class MyClass { ... }
$method = 'doSth';
$obj = new MyClass();
$obj->$method('arg1', 'arg2');
But I really don't recommend that way. It's tricky, obscure and much harder to debug and maintain.
By passing $this as a variable by reference, you can access members of that class.

Categories