CakePHP 2.x:Model :: afterFind()上的$ primary标志实际上有用吗? [英] CakePHP 2.x: Is the $primary flag on Model::afterFind() actually useful?

查看:117
本文介绍了CakePHP 2.x:Model :: afterFind()上的$ primary标志实际上有用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 更有用。



明确说明,我的问题是:


  1. $ primary flag实际上有用吗?

  2. 我确定不是用于确定 $ results 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 to false 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:

    1. What is the $primary flag actually useful for?
    2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆