How to call a variable function in php within a class? - php

I have the following example code
<?php
class Test {
function foo() {
print "foo\n";
}
function bar() {
$func = 'foo';
$func();
}
}
$test = new Test();
$test->bar()
which calls $test-bar(), whiich internally calls a variable php function named foo. This variable contains the string foo and I want the function foo be called like here. Instead of getting the expected output
foo
I get an error:
PHP Fatal error: Call to undefined function foo() ...
How to do this right, when using a string for the function-name? The string 'func' might denote several different functions inside the class scope in the actual code.
According to the doc the above should work like I have coded, more or less...

<?php
class Test {
public function foo() {
print "foo\n";
}
public function bar() {
$func = 'foo';
$this->$func();
}
}
$test = new Test();
$test->bar();
?>
Use this for accessing the current function of this class

What you can do is use the function call_user_func() to invoke the callback.
<?php
class Test {
public function foo() {
print "foo\n";
}
public function bar() {
$func = 'foo';
call_user_func(array($this, $func));
}
}
$test = new Test();
$test->bar();

You use the keyword $this
<?php
class Test {
function foo() {
print "foo\n";
}
function bar() {
$this->foo(); // you can do this
}
}
$test = new Test();
$test->bar()
There are two ways to call a method from a string input:
$methodName = "foo";
$this->$methodName();
Or you can use call_user_func_array()
call_user_func_array("foo",$args); // args is an array of your arguments
or
call_user_func_array(array($this,"foo"),$args); // will call the method in this scope

Related

Can the anonymous function be defined outside of another method in a class just like a class property?

I'm using PHP 7.1.11 on my machine.
Consider below working code :
<?php
class Foo {
public $bar;
public function __construct() {
$this->bar = function() {
return 42;
};
}
}
$obj = new Foo();
// as of PHP 7.0.0:
echo ($obj->bar)(), PHP_EOL;
?>
You can see that the anonymous function has been assigned to the class property bar but this has been done in a constructor.
Can I define the same anonymous function outside the constructor or any other method i.e. at the type of property declaration itself and can call it from within any class method using $this?
I tried below code but I got Fatal Error in output :
<?php
class Foo {
public $bar = function() {
return 42;
};
public function __construct() {
$this->bar();
}
}
$obj = new Foo();
//as of PHP 7.0.0:
echo $obj->bar, PHP_EOL;
?>
Output :
Fatal error: Constant expression contains invalid operations
I want the same output as working code 42

call_user_func() expects parameter 1 to be a valid callback

I'm just playing around with the call_user_func function in PHP and am getting this error when running this simple code:
<?php
class A
{
public $var;
private function printHi()
{
echo "Hello";
}
public function __construct($string)
{
$this->var = $string;
}
public function foo()
{
call_user_func($this->var);
}
}
$a = new A('printHi');
$a->foo();
?>
I know that if I make a function outside the class called printHi, it works fine, but I'm referring to the class's print hi and not sure why the "this" isn't being registered.
$this->var is evaluating to printHi in your example. However, when you are calling a method of a class, you need to pass the callback as an array where the first element is the object instance and the second element is the function name:
call_user_func(array($this, $this->var));
Here is the documentation on valid callbacks: http://www.php.net/manual/en/language.types.callable.php
Alternatively to Omar's answer, you can also make printHi() a class static function, so you then can call it from call_user_func('A::printHi') , like this:
class A
{
public $var;
public static function printHi()
{
echo "Hello";
}
public function __construct($string)
{
$this->var = $string;
}
public function foo()
{
call_user_func($this->var);
}
}
$a = new A('A::printHi');
$a->foo();
See live example

php oop call method from inside the method from the same class

I've got the following issue
class class_name {
function b() {
// do something
}
function c() {
function a() {
// call function b();
}
}
}
When I call function as usual: $this->b(); I get this error: Using $this when not in object context in C:...
function b() is declared as public
any thoughts?
I'll appreciate any help
Thanks
The function a() is declared inside method c().
<?php
class class_name {
function b() {
echo 'test';
}
function c() {
}
function a() {
$this->b();
}
}
$c = new class_name;
$c->a(); // Outputs "test" from the "echo 'test';" call above.
Example using a function inside a method (not recommended)
The reason why your original code wasn't working is because of scope of variables. $this is only available within the instance of the class. The function a() is not longer part of it so the only way to solve the problem is to pass the instance as a variable to the class.
<?php
class class_name {
function b() {
echo 'test';
}
function c() {
// This function belongs inside method "c". It accepts a single parameter which is meant to be an instance of "class_name".
function a($that) {
$that->b();
}
// Call the "a" function and pass an instance of "$this" by reference.
a(&$this);
}
}
$c = new class_name;
$c->c(); // Outputs "test" from the "echo 'test';" call above.

Call to undefined function handler

Is it possible to handle this type of errors? Something like spl_autoload_register, but for functions.
Basically, what I am trying to do:
I have the class:
class Foo {
public function bar() {
echo 1;
}
}
So, when I call a nonexistent function Foo() like this:
Foo()->bar();
The possible handler should create a function Foo(), which looks like that:
function Foo() {
return new Foo();
}
If you never need an actual instance of the object, why not use a static class?
class Foo {
public static function bar() {
echo 1;
}
}
Foo::bar();
Then, you can do this in your app:
$this->fiends = FriendsModel::getUserFriends($userId);

Can I declare something global at the class level in PHP?

Is there a way to set something as global in a class and have all methods of that class to have access to it? Currently if I use global $session; I have to add it into every method that uses it even if all the methods are in the same class.
If I try to add it directly into the class then I get a php error saying it is expecting a function
global $session;
Here is a better example...
class test{
function test1(){
$self->test2($var);
}
function test2($var){
return $var
}
}
in this case I am getting this error below, do I need to use global or what?
Fatal error: Call to a member function test2() on a non-object
I may be misunderstanding the question, but I think what you want is an instance variable:
<?php
class Foo {
var $bar = "blue"
function output() {
echo $this->bar . "\n";
}
function a() {
$this->bar = "green";
}
function b() {
$this->bar = "red";
}
}
?>
In this case, $bar is the instance variable, accessible from each method. The following code, using the Foo class:
$newFoo = new Foo();
$newFoo->output();
$newFoo->a();
$newFoo->output();
$newFoo->b();
$newFoo->output();
Would create the following output:
blue
green
red
There are different ways to do this,
<?php
class test{
private $p_var;
public static $s_var;
function test(){
$this->p_var="RED";
self::$s_var="S_RED";
}
function test1(){
return $this->test2($this->p_var);
}
function test2($var){
return $var;
}
function test3($var){
$this->p_var=$var;
}
function stest1(){
return $this->test2(self::$s_var);
}
function stest2($var){
return $var;
}
function stest3($var){
self::$s_var=$var;
}
}
?>
Heere $objtest is the object of the test() class:
$objtest=new test();
echo $objtest->test1(),"<br/>";
$objtest->test3("GREEN");
echo $objtest->test1(),"<br/>";
echo "<br/>";
echo $objtest->stest1(),"<br/>";
$objtest->stest3("S_GREEN");
echo $objtest->stest1(),"<br/>";
test::$s_var="S_BLUE";
echo $objtest->stest1();
Would create the following output
RED
GREEN
S_RED
S_GREEN
S_BLUE
Using static variable(test::$s_var) you can achieve what you want.
If you have any confusion about self and $this then you can read this document
You're getting an error because you're using self instead of this.
i.e.
$this->test2($var);

Categories