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
Related
I want $foo->display(); to display Hello World
Here is what I tried:
class MyAttribute
{
public function init($var)
{
$this->setString($var);
}
public function display()
{
$this->setString = $var;
}
}
$foo = new MyAttribute("Hello World");
$foo->display();
You need to use the return keyword to pass the variable back, however that is not your issue, consider the following:
class MyAttribute {
private $attr;
public function __construct($attr)
{
$this->attr = $attr;
}
public function get_attr()
{
return $this->attr;
}
}
$attr = new MyAttribute('Hello World');
echo $attr->get_attr();
The constructor executes first when the class is instantiated and we set the property $attr with the variable that is passed to said constructor.
In the get_attr functionm the important part to notice is the return keyword which I have linked you to the documentation for it above.
You don't necessarily need a constructor, you can add another function called set_attr which sets/changes the value of $attr but seeing as you are using the constructor in your original code, I've left it in.
Live Example
Repl
Reading Material
PHP OOP
You Can use __construct because PHP will automatically call the __construct() method/function when you create an object from your class.
we can provide a value for the $par property when we create our MyAttribute objects.
class MyAttribute
{
private $var;
public function __construct($var)
{
$this->var = $var;
}
public function display()
{
return $this->var;
}
}
$foo = new MyAttribute("Hello World");
echo $foo->display();
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
i have seen in some libraries something like this :
$this->getResponse()->setRedirect($returnUrl);
How is this 'multicall' done, or, how should the class be build to do something like this?
I think :
class greeting
{
public function hi()
{
public function howAreYou()
{
echo 'How are you?';
}
}
}
$greet = new greeting;
$greet->hi()->howAreYou();
But i think it's not so good, i would better use something like extends, but i don't know. Thx for your suggestions.
If this is a class instance calling itself, it is called "method chaining".
In PHP, can be done by using return $this; note that this is a very different mechanism than class inheritance - it doesn't really make sense to treat them as interchangeable.
See also: https://stackoverflow.com/search?q=method+chaining+php
getResponse() is returning a class instance which has a setRedirect() method.
Example:
class Foo
{
public function getResponse()
{
$redirect = new Bar();
return $redirect;
}
}
class Bar
{
public function setRedirect($returnUrl)
{
// do something
}
}
$foo = new Foo();
$foo->getResponse()->setRedirect("returnUrl");
No.
All you have to do is return self at very end of each function.
So Your example would be like>
class greeting
{
public function hi()
{
echo "Hi";
return $this;
}
public function howAreYou()
{
echo 'How are you?';
return $this;
}
}
$greet = new greeting;
$greet->hi()->howAreYou();
Or even:
$greet->hi()->howAreYou()->hi()->howAreYou();
class stutter{
public function a(){
echo 'h';
return $this;
}
public function b(){
echo 'hello world!';
}
}
$var=new stutter();
var->a()->b();
Output is:
h hello world
Chaining methods is not the same as declaring functions within a method... in fact the latter will spit an error (not the function declaration, but the way you're calling it). In order to chain a method, just have it return the object itself:
Class chainableObject
{
public $name=null;
public function __construct($name='')
{
$this->name=$name;
return $this;
}
public function setName($name)
{
$this->name = $name;
return $this;//makes chainable
}
public function greet()
{
echo 'Hello, '.$this->name;
return $this;
}
}
$chain = new chainableObject('Frank')->greet();//outputs: Hello, frank
The explanation: All methods return the instance itself, so basically, read the last line of the snippet like this [create object with name:Frank]=>call method greet on the return value of this action. Since the return value is $this, the object that has a greet method, that's what will happen... easy, for more info: just google php method chaining
I'm just starting with Object Oriented PHP and I have the following issue:
I have a class that contains a function that contains a certain script. I need to call a variable located in that script within another function further down the same class.
For example:
class helloWorld {
function sayHello() {
echo "Hello";
$var = "World";
}
function sayWorld() {
echo $var;
}
}
in the above example I want to call $var which is a variable that was defined inside a previous function. This doesn't work though, so how can I do this?
you should create the var in the class, not in the function, because when the function end the variable will be unset (due to function termination)...
class helloWorld {
private $var;
function sayHello() {
echo "Hello";
$this->var = "World";
}
function sayWorld() {
echo $this->var;
}
}
?>
If you declare the Variable as public, it's accessible directly by all the others classes, whereas if you declare the variable as private, it's accessible only in the same class..
<?php
Class First {
private $a;
public $b;
public function create(){
$this->a=1; //no problem
$thia->b=2; //no problem
}
public function geta(){
return $this->a;
}
private function getb(){
return $this->b;
}
}
Class Second{
function test(){
$a=new First; //create object $a that is a First Class.
$a->create(); // call the public function create..
echo $a->b; //ok in the class the var is public and it's accessible by everywhere
echo $a->a; //problem in hte class the var is private
echo $a->geta(); //ok the A value from class is get through the public function, the value $a in the class is not dicrectly accessible
echo $a->getb(); //error the getb function is private and it's accessible only from inside the class
}
}
?>
Make $var a class variable:
class HelloWorld {
var $var;
function sayHello() {
echo "Hello";
$this->var = "World";
}
function sayWorld() {
echo $this->var;
}
}
I would avoid making it a global, unless a lot of other code needs to access it; if it's just something that's to be used within the same class, then that's the perfect candidate for a class member.
If your sayHello() method was subsequently calling sayWorld(), then an alternative would be to pass the argument to that method.
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);