CakePHP 2.x:Model :: afterFind()上的$ primary标志实际上有用吗? [英] CakePHP 2.x: Is the $primary flag on Model::afterFind() actually useful?
问题描述
CakePHP的 Model :: afterFind()
回调看起来像:
afterFind(array $ results,boolean $ primary = false)
根据文档:
$ primary
参数指示当前模型是否是查询生成的模型或者是否将此模型作为关联查询。如果模型被查询为关联,则$ results
的格式可能不同。
他们可以不同,但实验表明他们不总是 不同。就我所知, $ primary
参数实际上并不是有用的。如果设置为 false
,你可能会或不会得到一个扁平的数据结构,所以你可能会或可能不会用可怕的不能使用字符串偏移作为数组错误消息。
虽然我还没有尝试过,我基于文档的想法是忽略 $ primary
标志,只需检查数据:
public function afterFind($ results,$ primary = false){
if(array_key_exists(0,$ results){
//操作$ results [0] ['User'] ['fieldname']
} else {
//操作$结果['fieldname']
}
return $ results;
}
这是hackish,我不喜欢它,但它似乎可能比 $ primary
更有用。
明确说明,我的问题是:
-
$ primary
flag实际上有用吗? - 我确定不是用于确定
$ results $ c $ c> $ primary
参数似乎只用于警告您$ results
的格式不可预测的情况。在确定$ results
的格式时无用。
此处的更多信息: https://groups.google.com/forum/?fromgroups=#!topic/cake-php/Mqufi67UoFo
提供的解决方案是检查
!isset($ results [$ this-> primaryKey])
查看$ results
是什么格式。这也是一个黑客,但可以说比检查一个键'0'。
我最终想出的解决方案是做这样的事情:
public function afterFind($ results,$ useless){
//检查primaryKey字段
if(!isset($ results [$ this-> primaryKey])){
//标准格式,直接使用数组
$ resultsArray =& $ results;
} else {
// stupid格式,创建一个虚拟数组
$ resultsArray = array(array());
//并将单个值的引用推送到数组中
$ resultsArray [0] [$ this-> alias] =& $ results;
}
//遍历$ resultsArray
foreach($ resultsArray as& $ result){
//操作$ result [$ this-> alias] ['fieldname']
//两种情况下的一段代码。好极了!
}
//返回$以任何格式导入
//但是引用修改的值
return parent :: afterFind($ results ,$ useless);
}
这样可以减少代码重复,因为您不必编写字段修改逻辑两次(一次用于数组,一次用于非数组)。
您可以通过在方法结束时返回
$ resultsArray
完全避免引用内容,但我不知道如果CakePHP(或一些其他父类)期望$ results
在传递它的方式可能会导致什么问题。加这种方式不有复制$ results
数组的开销。CakePHP's
Model::afterFind()
callback looks like:afterFind(array $results, boolean $primary = false)
According to the documentation:
The
$primary
parameter indicates whether or not the current model was the model that the query originated on or whether or not this model was queried as an association. If a model is queried as an association the format of$results
can differ.They can differ, but experimentation shows that they don't always differ. As far as I can tell, the
$primary
parameter isn't actually all that useful. If it's set tofalse
you may or may not get a flattened data structure, so you may or may not wind up with the dreaded "cannot use string offset as an array" error message.Although I haven't tried it yet, my thought based on the documentation was to ignore the
$primary
flag altogether and just check the data:public function afterFind($results, $primary = false) { if (array_key_exists(0, $results) { // operate on $results[0]['User']['fieldname'] } else { // operate on $results['fieldname'] } return $results; }
This is hackish and I don't like it, but it seems likely to be more useful than
$primary
.Explicitly stated, my questions are:
- What is the
$primary
flag actually useful for? - Am I correct that it is not useful for determining the structure of the
$results
array, or have I missed something there?
解决方案Indeed the
$primary
parameter seems to only be useful in warning you of cases where the format of$results
is unpredictable. It is not useful in determining the format of$results
.More information here: https://groups.google.com/forum/?fromgroups=#!topic/cake-php/Mqufi67UoFo
The solution offered there is to check
!isset($results[$this->primaryKey])
to see what format$results
is. This is also a bit of a hack, but arguably better than checking for a key '0'.The solution I ultimately came up with is to do something like this:
public function afterFind($results, $useless) { // check for the primaryKey field if(!isset($results[$this->primaryKey])) { // standard format, use the array directly $resultsArray =& $results; } else { // stupid format, create a dummy array $resultsArray = array(array()); // and push a reference to the single value into our array $resultsArray[0][$this->alias] =& $results; } // iterate through $resultsArray foreach($resultsArray as &$result) { // operate on $result[$this->alias]['fieldname'] // one piece of code for both cases. yay! } // return $results in whichever format it came in // as but with the values modified by reference return parent::afterFind($results, $useless); }
This reduces code duplication because you don't have to write your field alteration logic twice (once for an array and once for non-array).
You may be able to avoid the references stuff altogether by just returning
$resultsArray
at the end of the method, but I wasn't sure what issues that might cause if CakePHP (or some other parent class) expects$results
in the way it was passed in. Plus this way doesn't have the overhead of copying the$results
array.这篇关于CakePHP 2.x:Model :: afterFind()上的$ primary标志实际上有用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- What is the