I love Laravel, and you? Overall, the Facades feature! When you use a facade like some Eloquent model, you have noticed the following case:

MyModel::where( 'id', $id )->where( 'name', $name )->first();

Here, we have two feature very important and useful:

  • the chain
  • the call to the static method where, and the call to the instance method where

Now, the chain is clear. It is very easy to implement. In fact, you need only return the $this pointer in your methods. Let me show an example:

class MyChainClass {

  public function methodOne()
  {
    // do something
    return $this;
  }

  public function methodTwo()
  {
    // do something
    return $this;
  }

}

Then, you may use this class in this way:

$instance = new MyChainClass;

$result = $instance->methodOne()->methodTwo();

The hardest part is the implementation of static and instance method. In PHP you can’t use the same name for a static and instance method. This code below will issue an exception:

class MyClass {
  
  public static function where( $value ) {
    
  }
  
  public function where ($value )
  {
    
  }
}

PHP will respond by an exception Fatal error: Cannot redeclare MyClass::where(). This is easily achieved by using the __call() and __callStatic() magic methods.

class MyFacadeClass {

  protected $where = [];

  public function __call( $name, $arguments )
  {
    $method = 'set' . ucfirst( $name ) . 'Attribute';

    if ( method_exists( $this, $method ) ) {
      return call_user_func_array( [ $this, $method ], $arguments );
    }
  }

  public static function __callStatic( $name, $arguments )
  {
    $instance = new static();

    $method = 'set' . ucfirst( $name ) . 'Attribute';

    if ( method_exists( $instance, $method ) ) {
      return call_user_func_array( [ $instance, $method ], $arguments );
    }
  }

  public function setWhereAttribute( $value )
  { 
    $this->where[] = $value;
    return $this;
  }
}

Finally, we can use the method where both as static and as instance, along with the “chain”:

$result = MyFacadeClass::where( "hello" )->where( "world" );

var_dump( $result );

class MyFacadeClass#1 (1) {
  protected $where =>
  array(2) {
    [0] =>
    string(5) "hello"
    [1] =>
    string(5) "world"
  }
}

Of course, you may add other methods to this class as needed. For example, if you need to implement the turnOn method, just add the following:

public function setTurnOnAttribute()
{
  // do something
  return $this;
}

That’s all!