I have an array populated by several class methods such that, I can randomly call some those methods for testing.
The code below is what I'm trying to make work, but, I'm only getting the name of the method, it's not executed.
For example, lets say 1 is returned to $methodIndex, I get back func2() instead of Hello Func2.
Is there a function in PHP to do this or simple workaround?
class A{
public function func1() { echo "Hello Func1"; }
public function func2() { echo "Hello Func2"; }
public function func3() { echo "Hello Func3"; }
private $methods = ['func1', 'func2', 'func3'];
public function get_methods(){ return $methods; }
}
$object = new A();
$methodIndex = mt_rand(0, count($object->get_methods()) - 1);
$object->get_methods()[$methodIndex]."()"; //e.g. $object->func2();
I think you're looking for call_user_func (short array syntax shown)
call_user_func([$object, $object->get_methods()[$methodIndex]]);
It would be something along the lines of
$functionName = get_methods()[$methodIndex];
call_user_func(array($object, $functionName))
That's it :-)
class A{
public function func1() { echo "Hello Func1"; }
public function func2() { echo "Hello Func2"; }
public function func3() { echo "Hello Func3"; }
private $methods = ['func1', 'func2', 'func3'];
public function get_methods(){ return $methods; }
public function random(){
$method = $this->methods[rand(0, (count($this->methods) - 1))];
if(is_callable(array($this, $method))){
return call_user_func_array(array($this, $method), func_get_args());
}
}
}
$object = new A();
$object->random();
Related
How do I make chained objects in PHP5 classes? Examples:
$myclass->foo->bar->baz();
$this->foo->bar->baz();
Not: $myclass->foo()->bar()->baz();
See also:http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html
actually this questions is ambiguous.... for me this #Geo's answer is right one.
What you (#Anti) says could be composition
This is my example for this:
<?php
class Greeting {
private $what;
private $who;
public function say($what) {
$this->what = $what;
return $this;
}
public function to($who) {
$this->who = $who;
return $this;
}
public function __toString() {
return sprintf("%s %s\n", $this->what, $this->who);
}
}
$greeting = new Greeting();
echo $greeting->say('hola')->to('gabriel'); // will print: hola gabriel
?>
As long as your $myclass has a member/property that is an instance itself it will work just like that.
class foo {
public $bar;
}
class bar {
public function hello() {
return "hello world";
}
}
$myclass = new foo();
$myclass->bar = new bar();
print $myclass->bar->hello();
In order to chain function calls like that, usually you return self ( or this ) from the function.
Example:
Class Test {
private function __construct() {}
public static function init() {
$new_test = new Test();
return $new_test->inner_test;
}
public function inner_test() {
print '!!!!';
}
}
$test = Test::init();
$test();
Returns "PHP Fatal error: Function name must be a string"
Is there a way to accomplish this Javascript type behavior in PHP?
Below PHP 5.4
Class Test {
private function __construct() {}
public static function init() {
$new_test = new Test();
return $new_test->inner_test();
}
public function inner_test() {
print '!!!!';
}
}
$test = array('Test','init');
call_user_func($test);
For Phil:
function test(){
echo "Hello";
}
$test = test;
$test();
Run that in the sandbox.
Thanks to Phil for the link. This works:
Class Test {
private function __construct($myString) {
$this->myString = $myString;
}
public static function init($myString) {
$new_test = new Test($myString);
return function() use (&$new_test) {$new_test->inner_test();};
}
public function inner_test() {
print $this->myString;
}
}
$test = Test::init('Lorem Ipsum Dolar');
$test();
I try call Test3 function, but returned this error: "Fatal error: Call to undefined function".
Here is an example:
class Test {
public Test1(){
return $this->Test2();
}
private Test2(){
$a = 0;
return Test3($a);
function Test3($b){
$b++;
return $b;
}
}
}
How to call Test3 function ?
From PHP DOC
All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
Use ClosuresÂ
$test = new Test();
echo $test->Test1();
Modified Class
class Test {
public function Test1() {
return $this->Test2();
}
private function Test2() {
$a = 0;
$Test3 = function ($b) {
$b ++;
return $b;
};
return $Test3($a);
}
}
Not sure if you wanted a closure or if your 'inner' function was a typo.
If it was meant to be a separate method then the below is the correct syntax:
class Test
{
public function Test1()
{
return $this->Test2();
}
private function Test2()
{
$a = 0;
return $this->Test3($a)
}
public function Test3($b)
{
$b++
return $b;
}
}
I'm trying to use call_user_func to call a method from another method of the same object, e.g.
class MyClass
{
public function __construct()
{
$this->foo('bar');
}
public function foo($method)
{
return call_user_func(array($this, $method), 'Hello World');
}
public function bar($message)
{
echo $message;
}
}
new MyClass; Should return 'Hello World'...
Does anyone know the correct way to achieve this?
Many thanks!
The code you posted should work just fine. An alternative would be to use "variable functions" like this:
public function foo($method)
{
//safety first - you might not need this if the $method
//parameter is tightly controlled....
if (method_exists($this, $method))
{
return $this->$method('Hello World');
}
else
{
//oh dear - handle this situation in whatever way
//is appropriate
return null;
}
}
This works for me:
<?php
class MyClass
{
public function __construct()
{
$this->foo('bar');
}
public function foo($method)
{
return call_user_func(array($this, $method), 'Hello World');
}
public function bar($message)
{
echo $message;
}
}
$mc = new MyClass();
?>
This gets printed out:
wraith:Downloads mwilliamson$ php userfunc_test.php
Hello World
new MyClass; Should return 'Hello World'...
A constructor does not return anything.
How do I make chained objects in PHP5 classes? Examples:
$myclass->foo->bar->baz();
$this->foo->bar->baz();
Not: $myclass->foo()->bar()->baz();
See also:http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html
actually this questions is ambiguous.... for me this #Geo's answer is right one.
What you (#Anti) says could be composition
This is my example for this:
<?php
class Greeting {
private $what;
private $who;
public function say($what) {
$this->what = $what;
return $this;
}
public function to($who) {
$this->who = $who;
return $this;
}
public function __toString() {
return sprintf("%s %s\n", $this->what, $this->who);
}
}
$greeting = new Greeting();
echo $greeting->say('hola')->to('gabriel'); // will print: hola gabriel
?>
As long as your $myclass has a member/property that is an instance itself it will work just like that.
class foo {
public $bar;
}
class bar {
public function hello() {
return "hello world";
}
}
$myclass = new foo();
$myclass->bar = new bar();
print $myclass->bar->hello();
In order to chain function calls like that, usually you return self ( or this ) from the function.