PHP 方法 return 数组并且仍然可以链接

PHP methods return array and still be chainable

我很确定这是不可能的,但我真的希望它会成为可能。

例如,我想以这种方式调用我的模型

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

基本上就是

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;
}

目前我必须在其中添加一个变量 $this->return = $return; 然后稍后调用 $getAll = models\company::getInstance()->getAll("ID < 4")->show();

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

这个想法是这样我可以做一个 $getAll = models\company::getInstance()->getAll("ID < 4")->format()->show();

所以问题。有没有办法在最后没有 show() 的情况下做到这一点?

理想情况下,我希望 $getAll = models\company::getInstance()->getAll("ID < 4") 输出数组,如果我执行 $getAll = models\company::getInstance()->getAll("ID < 4")->format(),它会从 getAll() 获取数组并执行操作并输出结果。看起来比必须将 show() 放在所有东西

上更干净

请不要因为我的不良行为而将我钉在十字架上。提前致谢

不知何故你必须 "flag" 最后一个调用,一个快速而肮脏的解决方案

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);

或者创建一个包装器,用于发件箱

function toResult($x) {
  return is_object($x)?$x->show():$x;
}

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

无论如何,被调用的方法永远不会知道链计数是否继续。

底线。这是不可能的。

在我的例子中,除了 ->show() 之外,我将保持我所有的方法可链接,然后 return "result"

所以即使我做了类似 users->get("1")->remove() 的事情,它也不会 return 任何消息,但它会执行操作。 users->get("1")->remove()->show() 将输出 "User successfully removed"

以前我从不为链接事物而烦恼,但它很快就会令人沮丧。链接似乎确实有帮助。开始一个新的大项目并尝试从头开始"better"

这绝对有可能!您需要做的是创建一个代表 ResultSet 的 class,它既可以用作普通数组(通过实现接口 ArrayAccess、Iterator 和 Countable),也可以用作对象。

例子

class ResultSet implements ArrayAccess, Countable, Iterator {

    private $data = array();
    private $position = 0;

    public function __construct(array $data=array())
    {
        $this->data = $data;
    }

    /* * Implement methods of the Countable interface * */

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

    /* * Implement methods of the ArrayAccess interface * */

    public function offsetExists($offset)
    {
        return isset($this->data[$offset]);
    }

    public function offsetGet($offset)
    {
        return $this->data[$offset];
    }

    public function offsetSet($offset, $value)
    {
        $this->data[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        if( $this->offsetExists($offset) )
            unset($this->data[$offset]);
    }

    /* * Implement methods of the Iterator interface * */

    function rewind() 
    {
        $this->position = 0;
    }

    function current() 
    {
        return $this->data[$this->position];
    }

    function key()
    {
        var_dump(__METHOD__);
        return $this->position;
    }

    function next()
    {
        ++$this->position;
    }

    function valid()
    {
        return isset($this->data[$this->position]);
    }

    /* * Implementation of ResultSet specific methods  * */

    public function show()
    {
        //....
    }

    /**
     * @param $in
     * @return ResultSet
     */
    public function format($in)
    {
        // do the stuff
        return $this;
    }

}

此实现将允许调用 ->getAll('...')->format()->show();同时允许程序员将 getAll() 的输出视为一个数组。