Error executing cascade class methods

Asked

Viewed 104 times

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

It is not possible to call cascading methods of the same class as shown above?

  • 4

    The return is $this?

  • 4

    Post the code of setVat that we will see the problem

  • 1

    @Lucas you’re right, "Return $this" is missing from the setName() method. Thank you.

2 answers

7

To execute the code this way (Method Chaining) it is necessary that your class Customer implement a standard called Fluent Interfaceen.

To be able to do this in PHP it is necessary that the methods of your class to be chained return the instance of itself ($this).

Your class will look 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 by using the magic method __call() together 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 methods of the class would be accessed perfectly, only the setters that are private and are not exposed outside the classes that would enter the __call(). Forcing all setters to go through __call() we don’t need to define the return of $this in all methods.

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

  • 1

    This should be the answer accepted, it is more detailed and it was put first!

  • 1

    I put another example, showing a few more things that can be done with PHP :)

  • 1

    +1 for going further... :)

  • @Zuul the answer is more complete yes, but yours is more direct, at least when I look for answers in stackoverflow I try to go the most direct answers. This does not invalidate the reply of the gmsantos, until.

  • @Filipemoraes Grateful for your attention :)

6


So you can create "method chaining", your methods need to resume $this, that is to say:

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

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

And then you can:

$Customer = new Customer;
$Customer->setVat()->setName();
  • 1

    But it is certain that that error is generated by the lack of return $this;?

  • @Jorgeb. Yes, because you are calling a method something that is not an object. By returning the $this already becomes an object and the method is already localized. (Essentially this is what the error itself tells us) :)

  • I just wanted to know if that error can only indicate this behavior. There is no other behavior that can lead to that error?

  • @Jorgeb. That is the error shown when you try to access a variable assuming it is an object. Either by chaining or on a regular basis: $nome = $bubu->getName(); <- It’ll be the same mistake because I didn’t $bubu = new bubu; before. But with that doubt, you can ask a new question and you will see that question better answered ;)

  • It’s just that I thought it was strange to have the answer ready, without seeing the class Customer.

  • @Jorgeb. These are common +/- problems, and those who have been through them have the answer ready ;)

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.