drew schmaltz
drew schmaltz

Reputation: 1584

PHP Method Chaining: Calling one method before allowing other methods to be chained

Consider the following class

class myClass {

   private $model;

    public function update($input) {
        return $this->model->update($input);
    }

    public function find($id) {
        $this->model = ORMfind($id);
    }
}

How do I prevent

$myClass = new myClass;
$myClass->update($input);

The problem isn't HOW to use the above code but how to make update() a method only callable after find().

EDIT: I changed what my method does so it was more clearly understood that I need to do one method (find()) before another (update())

Upvotes: 1

Views: 140

Answers (4)

Ja͢ck
Ja͢ck

Reputation: 173662

The proper way to make sure ->update() can only be called when the model has been initialized is to turn it into a dependency:

class myClass 
{
    private $model;

    public function __construct($id)
    {
        $this->model = ORMfind($id);
    }

    public function update($input) {
        return $this->model->update($input);
    }
}

$x = new myClass('123');

Alternatively, if you have multiple find operations, you could introduce them as static constructor methods:

class myClass 
{
    private $model;

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

    public function update($input) {
        return $this->model->update($input);
    }

    public static function find($id)
    {
        return new self(ORMfind($id));
    }
}

$x = myClass::find('123');

Update

Tackling your immediate problem can be done by a simple check:

    public function update($input) {
        return $this->model ? $this->model->update($input) : null;
    }

Upvotes: 0

Henrique Barcelos
Henrique Barcelos

Reputation: 7900

Outputting text, returning void, I think all of this is wrong. When you do not expect something to happen, you should throw an exception:

class MyClass {
    private $canUpdate = false;

    public function find($id) {
        // some code...
        $this->canUpdate = true;
    }

    public function canUpdate() {
        return $this->canUpdate;
    }

    private function testCanUpdate() {
        if (!$this->canUpdate()) {
            throw new Exception('You cannot update');
        }
    }

    public function update($inpjut) {
        $this->testCanUpdate();

        // ... some code
    }
}

Now you can do:

$obj = new MyClass();

try {
    $obj->update($input);
} catch (Exception $e) {
    $obj->find($id);
    $obj->update($input);
}

Upvotes: 0

zedfoxus
zedfoxus

Reputation: 37129

You could add a flag to your code like so:

class myClass {

  private $model;
  private $canUpdate = 0;

  public function update($input) {
    if ($canUpdate === 0) return; // or throw an exception here
    return $this->model->update($input);
  }

  public function find($id) {
    $this->model = ORMfind($id);
    $canUpdate = 1;
  }

}

Setting the flag $canUpdate will caution the update() method to react accordingly. If update() is called, you can throw an exception or exit out of the method if the flag is still 0.

Upvotes: 2

Charaf JRA
Charaf JRA

Reputation: 8334

To prevent from returning null value by get :

public function get() {
    if (isset($this->value)) return $this->value;
    else echo "please give me a value ";

 }

You can also create a construct:

 function __construct($val){
    $this->value=$val;  
 } 

and then give a value to your $value without using set() method:

 $myClass=new myClass(10);  

Upvotes: 1

Related Questions