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() 的输出视为一个数组。
我很确定这是不可能的,但我真的希望它会成为可能。
例如,我想以这种方式调用我的模型
$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() 的输出视为一个数组。