CakePHP 2.x:Model :: afterFind()上的$ primary标志实际上有用吗?

eaj*_*eaj 11 cakephp

CakePHP的Model::afterFind()回调如下:

afterFind(array $results, boolean $primary = false)
Run Code Online (Sandbox Code Playgroud)

根据文件:

$primary参数指示当前模型是否是查询源自的模型,或者是否将该模型作为关联查询.如果将模型作为关联查询,则格式$results可以不同.

它们可以有所不同,但实验表明它们并不总是不同.据我所知,$primary参数实际上并没有那么有用.如果它设置为false你可能会或可能不会得到一个扁平的数据结构,所以你可能会或可能不会结束可怕的"不能使用字符串偏移作为数组"错误消息.

虽然我还没有尝试过,但基于文档的想法是$primary完全忽略该标志并只检查数据:

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;
}
Run Code Online (Sandbox Code Playgroud)

这是hackish,我不喜欢它,但它似乎更有用$primary.

明确说明,我的问题是:

  1. 什么是$primary标志实际上有用吗?
  2. 我是否认为它对于确定阵列的结构没有$results,或者我错过了什么?

Cod*_*der 12

实际上,该$primary参数似乎仅用于警告您格式$results不可预测的情况.它在确定格式时没有用$results.

更多信息请访问:https://groups.google.com/forum/?fromgroups =#!topic/cake-php/McCfi67UoFo

提供的解决方案是检查!isset($results[$this->primaryKey])是什么格式$results.这也是一个黑客,但可以说比检查键'0'更好.

我最终提出的解决方案是做这样的事情:

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);
}
Run Code Online (Sandbox Code Playgroud)

这减少了代码重复,因为您不必编写两次字段更改逻辑(一次用于数组,一次用于非数组).

您可以通过$resultsArray在方法结束时返回来完全避免引用内容,但我不确定如果CakePHP(或其他一些父类)$results在传入方式中可能会导致什么问题.这种方式没有复制$results数组的开销.