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
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:
PHP method chaining or fluent interface?
(10 answers)
Closed 7 years ago.
I see in codeigniter a sintaxis method->other_method->other_method_again. example:
$this->db->select()->join()->findAll();
When i try
class MyClass{
public function bla(){
echo "bla";
}
public function other(){
echo "other";
}
}
$message = new MyClass();
$message->bla()->other();
Return:
Fatal error: Call to a member function other()
as I can do what codeigniter?
this is called method chaining (popularised by jQuery chaining) and is achieved if you
return $this
from each method
for your example:
class MyClass{
public function bla(){
echo "bla";
return $this; // enable method chaining
}
public function other(){
echo "other";
return $this; // enable method chaining
}
}
The reason this works is the same the following works:
$instance->method1();
$instance->method2();
Here each method is called on an $instance but if each method returns the actual $instance back which is the same as $this, then one can combine the statements like this ("chain" them):
$instance->method1()/* returns $instance and can be used again*/->method2();
That's all there is to it.
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:
how to create a php class which can be casted to boolean (be truthy or falsy)
(7 answers)
Closed 8 years ago.
Is there a way to define the boolean returned value for an if statement issued on my class instances?
I have a class implementing the array access interface and so on, but even if the wrapped array is empty:
if($class)
will always return true, since it is an object and does exists.
I'd rather not have to issue everytime an:
if(count($class))
Is there any way to achieve this?
If I get the point you can implement the countable interface; This requires you define the count() method, which let you know (by using it like count($myArrayAccessInstance)) if your internal array has items or not o whatever logic you want to define.
class MyAy implements ArrayAccess, Countable
{
private $data;
public function offsetExists($key)
{
# code...
}
public function offsetUnset($key)
{
# code...
}
public function offsetGet($key)
{
# code...
}
public function offsetSet($key, $value)
{
$this->data[$key] = $key;
}
public function count()
{
return $this->data > 0;
}
}
$my = new MyAy();
$my['user'] = "Ilpaijin";
if(count($my))
{
var_dump($my);
}
Given that you are implementing a class, maybe you could have a member which counts the elements in the array? Something like:
class MyClass {
public $numElems = 0;
private $elems = array();
...
public function add($elem) {
$elems[] = $elem;
$numElems++;
}
...
}
And then, do the iflike if($class->numElems) ...
Its not possible
In PHP an object when cast to bool always produces true. There is no way of changing that.
Check answers here
It's impossible to cast an object to a boolean related to a property inside the class because it always will return true. but I think you just need to create a function inside your class that allows you to return the boolean you need like this
public function bool()
{
return (count($this->array)>0);
}
when you need to use it, just call the function like this if ($obj->bool()) { ... } and another way to make your statements look like what you wanted to do in the begining is to define a class with a really short name, I usually use _, and this function should return the boolean you need just like this
function _ ($Obj)
{
return $Obj->bool();
}
finally, instead of testing on your class like this if ($class->bool()) which is a bit long, you do it like this
if (_($class))
{ /* do something fun */ }
This question already has answers here:
Calling closure assigned to object property directly
(12 answers)
Closed 9 years ago.
I have php code like:
class Foo {
public $anonFunction;
public function __construct() {
$this->anonFunction = function() {
echo "called";
}
}
}
$foo = new Foo();
//First method
$bar = $foo->anonFunction();
$bar();
//Second method
call_user_func($foo->anonFunction);
//Third method that doesn't work
$foo->anonFunction();
Is there a way in php that I can use the third method to call anonymous functions defined as class properties?
thanks
Not directly. $foo->anonFunction(); does not work because PHP will try to call the method on that object directly. It will not check if there is a property of the name storing a callable. You can intercept the method call though.
Add this to the class definition
public function __call($method, $args) {
if(isset($this->$method) && is_callable($this->$method)) {
return call_user_func_array(
$this->$method,
$args
);
}
}
This technique is also explained in
JavaScript-style object literals