Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chain methods ability without force to new keyword using php

I'm working on a script that MUST to call like this:

$father = Father::firstName('Esaaro')->lastName('Ozaaraa')->age(42);

Person::firstName("Soobaasaa")->lastName( "Ozaaraa")->age(17)
  ->setFather( $father )-> toArray();

So we have two classes named Person and Father.

firstName method of two classes are static methods and other methods are public.

This is my file structure

<?php

class Person
{
    protected static $name;
    protected $lastName, $age, $father, $result;

    public static function firstName($name = null)
    {
        self::$name = $name;
    }

    public function lastName($lastName = null)
    {
        $this->lastName = $lastName;
    }

    public function age($age = null)
    {
        $this->age = $age;
    }

    public function toArray()
    {

    }

    public function setFather(Father $father)
    {

    }
}


    /*
     * Father Class
     */

class Father
{
    protected static $name;
    protected $family, $age, $result;

    public static function firstName($name = null)
    {
        self::$name = $name;
    }

    public function lastName($lastName = null)
    {
        $this->family = $lastName;
    }

    public function age($age = null)
    {
        $this->age = $age;
    }

    public function toArray()
    {
        ( (isset(static::$name) && static::$name !== null) ? $this->result['firsName'] = self::$name : '' );
        ( (isset($this->family) && $this->family !== null) ? $this->result['lastName'] = $this->family : '' );

        return $this->result;
    }
}

the above code is just structure and I just started to work on script. The file structure could not change because it's a challenge.

How should I manipulate my script that I can call methods like I mentioned before?

Thanks in Advance

like image 646
Kiyarash Avatar asked Oct 05 '18 04:10

Kiyarash


People also ask

How do you chain a method in PHP?

The way to chain method invocations is to return the object from the previous call, using: return $this in the code of the previous method (method_1() ). - Here is an example, a PHP class that can be used to calculate the area and perimeter of rectangle (see the comments in code, and test it yourself).

Can you chain JavaScript methods?

Since the returned value is an instance of an object, it is, therefore, possible to call another method of an object to the returned value, which is its instance. And this makes method chaining possible in JavaScript.

How does JavaScript method chaining work?

Method chaining, or simply chaining, in JavaScript can be defined as when one or more sequential methods get invoked from an object without the introduction of unnecessary variables. The sole purpose of chaining is to make our code more readable and reduce the redundancy within.

What is method chaining in laravel?

The base for chaining methods is returning the instance of the object from the method that you want to chain. Copy Code. public function doSomething() { // Change something to the state of the object return $this; } public function doSomethingElse() { // ... return $this; }


1 Answers

Really all you need is for the static firstName methods to create a new instance of the class and return it.

The other setters just need to return $this to provide what's referred to as a fluent interface.

If the only way to create an instance is via the static firstName method, you'll also want to add a private / protected constructor.

For example

class Person
{
    private $firstName;
    private $lastName;
    private $age;
    private $father;

    private function __construct(string $firstName) {
        $this->firstName = $firstName;
    }

    public static function firstName(string $name) {
        return new Person($name);
    }

    public function lastName(string $lastName) {
        $this->lastName = $lastName;
        return $this;
    }

    public function age(int $age) {
        $this->age = $age;
        return $this;
    }

    public function setFather(Father $father) {
        $this->father = $father;
        return $this;
    }

    public function toArray() {
        // just an example
        return [
            'firstName' => $this->firstName,
            'lastName'  => $this->lastName,
            'age'       => $this->age,
            'father'    => $this->father->toArray(),
        ];
    }
}

I would strongly advise against keeping the $name property as static. You don't want to change one instance's $name and have it change all others. This is why I've changed it to private $firstName in my example above.

like image 153
Phil Avatar answered Oct 19 '22 09:10

Phil