This question already has answers here:
How to call a closure that is a class variable?
(2 answers)
Closed 4 years ago.
$f = function($v) {
return $v + 1;
}
echo $f(4);
// output -> 5
The above works perfectly fine. However, I cannot reproduce this correctly when f is a property of a class.
class MyClass {
public $f;
public function __construct($f) {
$this->f = $f;
}
public function methodA($a) {
echo $this->f($a);
}
}
// When I try to call the property `f`, PHP gets confused
// and thinks I am trying to call a method of the class ...
$myObject = new myClass($f);
$myObject->methodA(4);
The above will result in an error:
Call to undefined method MyClass::f()
I think the problem is that it is trying to make sense of
echo $this->f($a);
And as you've found it wants to call a member function f in the class. If you change it to
echo ($this->f)($a);
It interprets it as you want it to.
PHP 5.6
Thanks to ADyson for the comment, think this works
$f = $this->f;
echo $f($a);
While Nigel Ren's answer (https://stackoverflow.com/a/50117174/5947043) will work in PHP 7, this slightly expanded syntax will work in PHP 5 as well:
class MyClass {
public $f;
public function __construct($f) {
$this->f = $f;
}
public function methodA($a) {
$func = $this->f;
echo $func($a);
}
}
$f = function($v) {
return $v + 1;
};
$myObject = new myClass($f);
$myObject->methodA(4);
See https://eval.in/997686 for a working demo.
Related
This question already has answers here:
How to echo a custom object in PHP?
(4 answers)
Closed 3 years ago.
Please i need to create a functions and call them in one line using -> between them
I have this code but it doesn't run
<?php
class A {
public $a2;
public $b2;
public function mohamed($a){
$this->a2 = $a;
return $this ;
}
public function test($b){
$this->b2 = $b;
return $this ;
}
}
$class = new A();
echo $class->mohamed('name')->test('mohamed');;
?>
Since your class doesn't have a __toString() method, you cannot echo the class object itself.
So you have a few alternatives here, either declare a __toString() method that prints what you want it to, or print the variables separately.
Example using the magic-method __toString() (demo at https://3v4l.org/NPp2L) - you can now echo $class.
public function __tostring() {
return "A2 is '".$this->a2."' and B2 is '".$this->b2."'";
}
Alternative two is to not print the class itself, but get the properties of the class instead. Since they are public, you don't need a getter-method to use them in the public scope.
$class = new A();
$class->mohamed('name')->test('mohamed');;
echo $class->a2." and ".$class->b2;
Demo at https://3v4l.org/nHeP9
If I run your code the error explains the problem :
Object of class A could not be converted to string
Your function test() returns $this, a class A object which can not be echoed.
Try implement a __toString() function, or use a var_dump() instead of your echo to check your object's properties.
No matter what, your code and your chaining is working fine.
Actually, above code is running but you can not echo an object also you can try "var_dump()" instead of "echo".
var_dump($class->mohamed('name')->test('mohamed'));
Try this:
<?php
class A {
public $a2;
public $b2;
public function mohamed($a){
$this->a2 = $a;
return $this ;
}
public function test($b){
$this->b2 = $b;
return $this ;
}
}
$class = new A();
var_dump($class);
?>
This question already has answers here:
Sharing var from one function to the other function in PHP Class
(2 answers)
Closed 4 years ago.
Let's say I have two different functions, and one of them has a defined variable. In the second function, I don't wanna write the same variable again, can I simply use the variable from the first function in the second one WITHOUT redefining it in the second function?
Someting like:
class example{
public function a($foo){
$foo2 = $foo + 1
return $foo2;
}
public function b($foo2){
echo "result: " . $foo2;
}
}
It's simple, you can use a property $foo2 and access it from both methods:
class example{
private $foo2;
public function a($foo){
$this->foo2 = $foo + 1
return $this->foo2;
}
public function b(){
echo "result: " . $this->foo2;
}
}
$obj = new example();
$obj->a(5);
$obj->b(); // result: 6
This question already has answers here:
php call class function by string name
(6 answers)
Closed 8 years ago.
In PHP5, variables can be evaluated as functions1 such as:
function myFunc() {
echo "whatever";
}
$callableFunction = 'myFunc';
$callableFunction(); // executes myFunc()
Is there any syntax for assigning object member functions to a variable such as:
class MyClass {
function someCall() {
echo "yay";
}
}
$class = new MyClass();
// what I would like:
$assignedFunction = $class->someCall; // but I tried and it returns an error
$memberFunc = 'someCall';
$class->$memberFunc(); // I know this is valid, but I want a single variable to be able to be used to call different functions - I don't want to have to know whether it is part of a class or not.
// my current implementation because I don't know how to do it with anonymous functions:
$assignedFunction = function() { return $class->someCall(); } // <- seems lengthy; would be more efficient if I can just assign $class->someCall to the variable somehow?
$assignedFunction(); // I would like this to execute $class->someCall()
There is a way, but for php 5.4 and above...
class MyClass {
function someCall() {
echo "yay";
}
}
$obj = new Myclass();
$ref = array($obj, 'someCall');
$ref();
Hm.. actually it works for static too, just use the reference by name..
class MyClass {
static function someCall2() {
echo "yay2";
}
}
$ref = array('MyClass', 'someCall2');
$ref();
And for nonstatic this notation works as well. It creates a temporary instance of the class. So, this is what you need, only you need php 5.4 and above )
The PHP 5.4 solution above is good. If you need PHP 5.3, I don't think you can do much better than the anonymous function approach, but you could wrap that into a function that acts very similar to the PHP 5.4 method:
function buildCallable($obj, $function)
{
return function () use ($obj, $function) {
$args = func_get_args();
return call_user_func_array(array($obj, $function), $args);
};
}
//example
class MyClass
{
public function add($x, $y)
{
return $x + $y;
}
public static function multiply($x, $y)
{
return $x * $y;
}
}
//non-static methods
$callable = buildCallable(new MyClass(), 'add');
echo $callable(32, 10);
//static methods
$callable = buildCallable('MyClass', 'multiply');
echo $callable(21, 2);
This should work for any number of arguments to any (publicly visible) method.
This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 8 years ago.
This is an outline of a problem which I'm struggling to solve in my code. I guess my knowledge of scope isn't that great.. I don't understand why the function getGreeting is giving a parse error.
<?php
class Class_1 {
public $t;
public function __construct() {
$this->t = "hello world";
}
public function helloWorld() {
return $this->t;
}
}
$x = new Class_1();
function getGreeting() {
return $x->helloWorld();;
}
echo getGreeting();
?>
the error I get is:
Fatal error: Call to a member function helloWorld() on a non-object.
Because you need to initialize object in the function to access it's methods from it :
function getGreeting() {
$x = new Class_1();
return $x->helloWorld();;
}
Example
This question already has answers here:
PHP method chaining or fluent interface?
(10 answers)
Closed 7 years ago.
jQuery lets me chain methods. I also remember seeing the same in PHP so I wrote this:
class cat {
function meow() {
echo "meow!";
}
function purr() {
echo "purr!";
}
}
$kitty = new cat;
$kitty->meow()->purr();
I cannot get the chain to work. It generates a fatal error right after the meow.
To answer your cat example, your cat's methods need to return $this, which is the current object instance. Then you can chain your methods:
class cat {
function meow() {
echo "meow!";
return $this;
}
function purr() {
echo "purr!";
return $this;
}
}
Now you can do:
$kitty = new cat;
$kitty->meow()->purr();
For a really helpful article on the topic, see here: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html
Place the following at the end of each method you wish to make "chainable":
return $this;
Just return $this from your method, i.e. (a reference to) the object itself:
class Foo()
{
function f()
{
// ...
return $this;
}
}
Now you can chain at heart's content:
$x = new Foo;
$x->f()->f()->f();
yes using php 5 you can return object from a method. So by returning $this (which points to the current object), you can achieve method chaining