PHP Class and Function from variable - php

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.

Related

PHP - how to call a function that is part of an object where one part is a variable?

I need to call an function that is part of an object. The following call works as one would expect:
$someobject = getobject();
$result = $someobject->somefunction->value();
However, I need the "somefunction" component to be a variable.
I have tried to do it like this:
$var = 'somefunction';
$result = '$someobject->' . $var '->value'();
This does not work, but I hope it conveys what I am looking for. I've also tried a lot of variations based upon call_user_func() – without finding a syntax that works.
I am running: PHP 7.2.24-0ubuntu0.18.04.3. Vanilla version for Ubuntu 18.04 LTS.
To access a property or method dynamically based on its name, you simply use one more $ sign than you would normally.
For example, if we have this object:
class Foo {
public $someproperty = 'Hello!';
public function somefunction() {
return 'Hello World';
}
}
$someobject = new Foo;
Then we can access the property normally:
echo $someobject->someproperty;
Or dynamically by name:
$var = 'someproperty';
echo $someobject->$var;
Similarly, we can access the method normally:
echo $someobject->somefunction();
Or dynamically by name:
$var = 'somefunction';
$result = $someobject->$var();
Note that your example is a bit confusing, because you talk about "accessing a function where one part is a variable", but all you're actually trying to do is access a property dynamically, and you then happen to be calling a method on the object stored in that property. So the part you've called somefunction is actually the name of a property.
Here's an example that looks a bit like yours, but with the names changed:
class A {
public $foo;
}
class B {
public function value() {
return 'Hello World';
}
}
$a = new A;
$a->foo = new B;
$propertyname = 'foo';
echo $a->$propertyname->value();
class Blueprint
{
public function method()
{
return 'placeholder';
}
}
$object = new Blueprint;
$method = 'method';
// this will output `placeholder`
echo $object->{$method}();
Hooray!
The following (two alternative valid syntaxes are produced for the second line) works as expected without producing any errors:
$foobar = 'somefunction';
$result = $someobject->$foobar->value();
$result = $someobject->{$foobar}->value();
The following:
$foobar = 'somefunction';
$result = $someobject->${foobar}->value();
also works (i.e. it produces the expected result), but it also produces this warning:
Warning: Use of undefined constant foobar - assumed 'foobar' (this will throw an Error in a future version of PHP) …
Many thanks to all that commented. In particular Duc Nguyen and Swetank Poddar. I think it was the comment by Duc Nguyen in combination with the following comment by Swetank Poddar that finally cracked it.

PHP calling class function dynamically by variables caughts exception

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;

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;

how to call anonymous functions stored in a static array?

I'm trying to store anonymous functions in a static array property of my class. These functions should be invoked later by their index, but calling
self::$arr['index']()
just doesn't work, while
$a = self::$arr['index'];
$a();
does!
This doesn't work:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
self::$func['a']($str); // Call the function directly
}
}
$a = new A();
$a->go("hooray"); // Outputs "Undefined variable: func"
But this does:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
$a = self::$func['a']; // Pass the function name to a variable
$a($str); // Call the function via the variable
}
}
$a = new A();
$a->go("hooray"); // Outputs "hooray"
Why?
I'm using PHP Version 5.4.3
this is the behavior of php's parser
$functionName['a'] = "hello";
self::$functionName['a']();
calls
self::hello();
... the very sad thing is that in php you can't do this:
(self::$functionName['a'])(); // doesn't work in php :(
as you can do in javascript, for example
what you can do is... use a temporary variable like you said
$a = self::$func['a'];
$a($parameter);
or
call_user_func(self::$func['a'], $parameter);
hope this helps...
in latest phps these features were added
$a['sss'] = function(){ echo 'bla'; };
$a['sss']();
class Bla
{
private $a;
function test()
{
$this->a['sss'] = function(){ echo 'bla2'; };
$this->a['sss']();
}
}
$c = new Bla();
$c->test();
and they work properly... so for some reason, this syntax doesn't work only when using the scope resolution operator ( ClassName:: self:: etc)
Well, in php you simply can not do that, it is a php feature. But you can use call_user_func or its relatives:
return call_user_func(self::$func['$a'], $str);
This is a consequence of how the PHP parser currently works. Since the function call () is evaluated before the static operator ::, you end up with the parser attempting to reference the local variable $func instead, and then giving you the error about $func being undefined (which it is, since there is no variable named $func in the method).
As you've discovered, you can solve this by doing two separate statements.

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