phparraysoopchainable

PHP methods return array and still be chainable


I'm quite sure this isn't possible but I'm really hoping its gonna be possible.

i want to call my models in this way for instance

$getAll = models\company::getInstance()->getAll("ID < 4")

which is basicaly just

class company extends _ {
private static $instance;
function __construct() {
    parent::__construct();
}
public static function getInstance(){
    if ( is_null( self::$instance ) ) {
        self::$instance = new self();
    }
    return self::$instance;
}
function getAll($where = "") {
    // yada yada
    $this->return = $return;
    return $this;
}

at the moment i have to add a variable $this->return = $return; inside there and then later on call $getAll = models\company::getInstance()->getAll("ID < 4")->show();

function show(){
    return $this->return;
}

the idea is so that i can for instance do a $getAll = models\company::getInstance()->getAll("ID < 4")->format()->show();

so the question. is there a way to do it without show() on the end?

Ideally i want $getAll = models\company::getInstance()->getAll("ID < 4") to output the array and if i do $getAll = models\company::getInstance()->getAll("ID < 4")->format() for it to take the array from getAll() and do stuff and output the result. just seems cleaner than having to put show() on everything

please don't crucify me for bad practices. thanks in advance


Solution

  • Somehow you must "flag" the last call, a quick and dirty solution

    class confusing {
    private static $instance;
    
    function __construct() {
        $this->return = 'nothing';
    }
    
    public static function getInstance() {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    function getAll($where = "") {
        $this->return = 'getAll'.$where;
        return $this;
    }
    
    function format() {
        $this->return = strtoupper($this->return);
        return $this;
    }
    
    function __call($name,$args) {
        $rthis = true;
        if ( 'last_'==substr($name,0,5) ) {
            $toCall = substr($name,5);
            $rthis = false;
        }
        else {
            $toCall = $name;
        }
        call_user_func_array([$this,$toCall],$args);
        return $rthis?$this:$this->return;
    }
    }
    
    $x = confusing::getInstance()->getAll('x')->last_format();
    $y = confusing::getInstance()->last_getAll('y');
    $z = confusing::getInstance()->getAll('z');
    
    var_export($x);
    var_export($y);
    var_export($z);
    

    Or create a wrapper which outboxes

    function toResult($x) {
      return is_object($x)?$x->show():$x;
    }
    
    $getAll = toResult(models\company::getInstance()->getAll("ID <4")->format());
    

    Anyhow the called method never will know about the chain countinues or not.