Error executing methods of a cascading class

5

I have the following code:

1.  $customer = new Customer($apiContext);
2.  $customer->setVat('XYZ0123456')
3.           ->setName('Filipe')
4.           ->setLanguageId(1);
5.  (...)

The following error occurs on line 3:

  

Call to a member function setName () on a non-object

Can not call methods of the same cascading class as shown above?

    
asked by anonymous 30.03.2015 / 12:37

2 answers

6

In order for you to create method chaining , your methods need to return $this , ie

class Customer {
    function setVat() {
      echo "bubu!";
      return $this;
    }

    function setName() {
       echo "Bubu2!";
       return $this;
    }
}

And then you can:

$Customer = new Customer;
$Customer->setVat()->setName();
    
30.03.2015 / 13:23
7

To execute the code in this way ( Method Chaining ), your Customer class must implement a pattern called Fluent Interface en .

In order to do this in PHP it is necessary that the methods of its class to be chained return the instance of itself ( $this ).

Your class will look something like this:

<?php

class Customer {

    public function setVat($vat){
        // ....     
        return $this;
    }

    public function setName($name){
        // ...      
        return $this;
    }

    public function setLanguageId($languageId){
        // ...      
        return $this;
    }

    // ...

}

Another way to do this with PHP is to use the __call() magic method in conjunction with private setters.

<?php

class Customer {

    private function setVat($vat){
        // ....     
    }

    private function setName($name){
        // ...      
    }

    public function __call($name, $arguments){
        if (method_exists($this, $name) && strpos($name, 'set') === 0) 
        {
            $this->$name($arguments[0]);   // Tratar o número de argumentos passados é 
                                           // uma boa ideia

            //$this->$name(...$arguments); // A partir do PHP 5.6
            return $this;
        } 
        else 
        {
            throw new Exception('Invalid setter method');
        }
    }
    // ...
}

The public class methods would be accessed perfectly, only the setters that are private and not exposed outside the classes that would enter __call() . Forcing all setters to pass __call() we do not need to set the $this return on all methods.

strpos($name, 'set') === 0 protects private methods in our class that do not start with set , thus preventing undue access of private methods of the class.

    
30.03.2015 / 13:22