作为我不断努力简化CodeIgniter3应用程序遗留代码库的一部分,我目前遇到了一个问题。简而言之,我之前已经处理过一个错误语句,指出:
can't use method return value in write context
这可能会给一些读者敲响警钟。尽管如此,我还没有看到这个错误,但我怀疑仍然出了问题。简而言之,我正在尝试将一个关联数组推送到另一个关联多维数组中,该数组是返回引用的方法的结果。
我已经设置了一个系统来轻松更改 JSON 的内容,通过此方法通过引用返回:
/**
* Function : items
* Target : Retrieves a reference to the items, decoded
*
* @author : Angev
* @since : 2.0
* @version : 1.0
*
* @return Referenced link to index 'items'.
*/
public function & items()
{
$list = (is_array($this->data)) ? $this->data : json_decode($this->data, true);
return $list['items'];
}
简而言之,方法$this->items()
是名为"清单"的模型的一部分。清单对应于我的数据库中的数据表,其中包括一个"数据"列,该列表示属于某个清单的数据:我正在尝试更改的 JSON,您可以看到该方法返回。查看$this->items()
输出的另一种方法是它应该返回对$this->data['items']
的引用。
这很好,我在开发过程中多次使用此方法 - 作为访问['list']
的简写 - 它总是准确地返回我需要它返回的内容:一个多维数组,填充有唯一索引(字符串),其中包含属于清单每个项目的数据。
但是,问题出现在名为update_checklist()
的方法中,特别是以下部分:
$this->items()[$uid] = [
'parent_id' => $parent['id'],
... ,
];
我希望该方法向 $this->items() 返回的数组添加索引,但事实并非如此。 我不太确定在这种情况下出了什么问题,因为我之前已经看到了写在这个问题顶部的错误消息,但此后就没有看到过。
但是,没有索引添加到数组中,每当我之后立即执行var_dump($this->items())时。它只是显示数组在执行update_checklist()
之前的状态。
为了寻找答案,我也尝试将回调括在括号中,但无济于事:
( $this->items() )[$uid] = . . .
为了暂时解决这个问题,我通过执行以下操作对 ['items'] 数组进行了更直接的更改:
$this->data = json_decode($this->data, true);
$this->data['items'][$uid] = [
'parent_id' => $parent['id'],
... ,
];
尽管如此,即使上面的代码有效,我仍然想知道我的逻辑中关于$this->items()
的方法引用返回有什么缺陷,以及为什么我在推送到引用数组时不能使用此方法。
如何编写所需的更改以使$this->items()[]
按预期运行?或者我有兴趣更清楚地了解这种结构背后的理论以及为什么它不起作用。
和往常一样,一旦你开始提出一个问题,你就会偶然发现你的逻辑缺陷。我和一位同事一起阅读了这个问题,在讨论解决方案时,我神奇地出现了。我将包括答案,以供将来有相同问题的任何人参考。
/**
* Function : items
* Target : Retrieves a reference to the items, decoded
*
* @author : Angev
* @since : 2.0
* @version : 1.0
*
* @return Referenced link to index 'items'.
*/
public function & items()
{
$list = (is_array($this->data)) ? $this->data : json_decode($this->data, true);
return $list['items'];
}
问题出在items()
方法上。此方法肯定返回一个引用,但是引用的是初步变量$list
,而初步变量又没有直接引用$this->data
。因此,该方法不是引用$this->data['items']
,而是返回对$list
的引用,这本质上是$this->data
的副本,没有真正的引用。
为了解决此问题,使用了以下代码:
public function & items()
{
if(!is_array($this->data) ) $this->data = json_decode($this->data, true);
return $this->data['items'];
}
正如预期的那样,该方法现在返回对实际数据对象的引用。
简而言之,我学到的是,如果你让一个方法返回一个引用,你需要确保该方法返回的任何内容实际上都是一个引用,而不是你尝试引用的数据的副本。
我将暂时搁置这个问题,以便其他人分享有关此事的任何见解。