PHP, return class as object - php

I am testing the way writing PHP like js, and I wonder if this will be possible.
If say I have A, B function in Class C.
Class C{
function A(){
}
function B(){
}
}
$D = new C;
$D->A()->B(); // <- Is this possible and how??
In Js, we can simple write like D.A().B();
I tried return $this inside of function A(), didnt work.
Thank you very much for your advice.

What you are looking for is called fluent interface. You can implement it by making your class methods return themselves:
Class C{
function A(){
return $this;
}
function B(){
return $this;
}
}

Returning $this inside the method A() is actually the way to go.
Please show us the code that supposedly didn't work (there probably was another error in that code).

Its rather simple really, you have a series of mutator methods that all returns the original (or other) objects, that way you can keep calling functions.
<?php
class fakeString
{
private $str;
function __construct()
{
$this->str = "";
}
function addA()
{
$this->str .= "a";
return $this;
}
function addB()
{
$this->str .= "b";
return $this;
}
function getStr()
{
return $this->str;
}
}
$a = new fakeString();
echo $a->addA()->addB()->getStr();
This outputs "ab"
Returning $this inside the function allows you to call the other function with the same object just like jQuery does.

I tried it and it worked
<?php
class C
{
public function a() { return $this; }
public function b(){ }
}
$c = new C();
$c->a()->b();
?>

Related

PHP - Call function from after call to another function in the class

I have this class:
class myClass
{
function A() {
$x = "Something ";
return $x;
}
function B() {
return "Strange";
}
}
But I want to call the function like this:
myClass()->A()->B();
How can i do that without return the class itself(return $this)?
In order to achieve method chaining, your methods from the chain (except the last one) must return an object (in many cases and also in yours $this).
If you would want to build a string with method chaining, you should use a property to store it. Quick example:
class myClass
{
private $s = "";
function A() {
$this->s .= "Something ";
return $this;
}
function B() {
$this->s .= "Strange";
return $this;
}
function getS() {
return $this->s;
}
}
// How to use it:
new myClass()->A()->B()->getS();

PHP OOP about class

Hi I want to make a code like this... Can you give me an example on how to implement this?
$theclassvariable = new Myclass();
$theclassvariable->firstMethod()->secondMethod($param,$param);
Thank you so much.
It is called chainable methods. In order to apply a method on $theclassvariable it needs to be an instance of a class. Let's define it:
class myClass {
public function __construct()
{
echo 'a new instance has been created!<br />';
}
public function firstMethod()
{
echo 'hey there that\'s the first method!<br />';
return $this;
}
public function secondMethod($first, $second)
{
echo $first + $second;
return $this;
}
}
$theclassvariable = new myClass();
If you want to apply a method on another method $theclassvariable->firstMethod->secondMethod(), $theclassvariable->->firstMethod needs to be an object too. In order to do that you need to return $this (the object) in each method. That's how you create chainable methods in PHP (and other languages...).
$theclassvariable->firstMethod()->secondMethod(1, 1);
The above will echo:
a new instance has been created!
hey there that's the first method!
2
Have the functions inside the class return the instance of the class
class Foo{
public function a(){
// Do Stuff
return $this;
}
public function b(){
// Do Stuff
return $this;
}
}
$foo = new Foo();
$foo->a()->b();

php class call function within function

Could someone help me understand how I can make functions within class methods, that would allow me to do things like this:
$class->send->activation_email()
I've seen many APIs do this, so I've tried:
class MyClass
{
public function send()
{
function activation_email()
{
echo "success!";
}
}
}
Undefined property: MyClass::$send
Consider:
class emailSender()
{
function activation_email()
{
if (mail($this->to, $this->subj, $this->body)) {
print $this->msg;
}
}
class MyClass
{
var $send;
function __construct()
{
$this->send=new emailSender();
$this->send->msg="success!";
}
}
$obj=new MyClass();
$obj->send->activation_email();
You probably want to an instance of another class within your class. Make a variable inside your class like this:
$this->otherclass = new Otherclass();
In this case, you can call functions from your other class the following way:
$myClass->otherclass->otherClassFunction()
Someone had answered but deleted the post. This is along the lines of what I was hoping for, and it works as expected:
class MyClass {
public function send(){
echo "Sending: ";
return $this;
}
public function activation_email(){
echo "activation email.";
}
}
$myClass = new MyClass();
$myClass->send()->activation_email();
What you are referring to (shame on no one for noticing this, for shame) is called "method chaining". A lot of big frameworks do this. Consider this example of use:
echo $obj->setName('Mike')->convertMtoN()->getName();
// Echoes "Nike"
Cool.
But here is how it works:
class Example {
private $name = '';
public function setName($name) {
$this->name = $name;
// We return the object, so you can call it again.
return $this;
}
public function convertMtoN() {
// Let's do Caps first
$this->name = str_replace("M", "N", $this->name);
// Then lowercase
$this->name = str_replace("m", "n", $this->name);
// We return the object, keep working
return $this;
}
public function getName() {
return $this->name;
}
}
$name = new Example;
echo $name->setName('Mike')->convertMtoN()->getName();
Essentially, for each method that does not implicitly return a value, you simply return the object, allowing you to continue chaining.
Awesome, right?
PHP rocks (now, I know it has its faults, but with HHVM and process forking, it basically rocks [dude, you will get there]).
You can play with this here:
https://ideone.com/fMcQ9u

PHP OOP Multicall

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

Chaining a new object instance in PHP

We have the following chaining:
$obj = new obj();
$obj->setname($params1)->setcolor($params2);
Is there a way to do the same chaining on one line, without creating a dummy function?
P.S: I want to skip the part where the constructor itself is on a new line. I want to construct the object and start the chaining on the same line. Something like this:
$obj = new obj()->setname($params1)->setcolor($params2);
Since PHP 5.4, class member access on instantiation has been added so you can do it like this:
$obj = (new obj())->setname($params1)->setcolor($params2);
In previous versions, like you I hate that you have to instantiate the object on one line and then start using it on another, so I have a global function _i() which looks like this:
function _i($i) { return $i; }
I use it like this:
_i(new Obj)->doThis($param)->doThat($param2);
Some people will find it ugly but PHP lacks language expression power, so it works for me :)
I use static functions of class for it.
class a{
static public function gets($args){
return new self($args);
}
public function do_other(){
}
}
a::gets()->do_other();
Usually there are more then I static method to different usages
Should be possible if you allways return the object itself in the function.
function setname($param) {
// set the name etc..
return $this;
}
You can also use PHP type hinting to make sure only the correct object is used as an argument
function instance(sdtClass $instance) { return $instance }
or as the static method using the class name
class CustomClass{
static public function gets(CustomClass $obj){
return $obj;
}
}
You can also use this technique from Singleton pattern (without using singleton pattern):
<?php
class test
{
public function __construct() {
}
public static function getInstance() {
return new test();
}
public function chain() {
echo 'ok';
}
}
// outputs 'ok'
$test = test::getInstance()->chain();
Sure is. Simplt return this at the end of each function, to return the object so your next chained function can use it.
<?php
class A
{
public __constructor()
{ .... }
public function B($params)
{
//Processing
return this;
}
public function C($params)
{
//Processing
return this;
}
public function D($params)
{
//Processing
}
}
$O = new A();
$O->B($params)->C($params)->D($params); //Will work because B and C return this
$O->B($params)->D($params)->C($params); //WILL NOT work because D doesn't return this
?>

Categories