CakePHP的模型saveAssociated错误 - 无法使用字符串作为数组offset [英] cakephp model saveAssociated error - Cannot use string offset as an array

查看:207
本文介绍了CakePHP的模型saveAssociated错误 - 无法使用字符串作为数组offset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个梨形一个在这里。它驱使我坚果和花就可以了一天的很大一部分。我希望有人可以通过这个有一个快速脱脂,并指出明显。

我已经几乎完成了一个CakePHP的升级,从1.3.14到2.4.2。其中一个我有遗留的问题是一个白水回收模式的呼叫......它实际上是插入数据的第一阵列正确,但与其余抛出异常。

我得到的错误是:

 错误:无法使用字符串作为数组offset
文件:/srv/www/test/public_html/app/Lib/cakephp/lib/Cake/Model/Model.php
行:2453

如果我看Model.php,问题就出现在这里:

 案的hasMany:
            的foreach($值$ I => $值){                如果(使用isset($值[$ i] [$协会)){
                    $值[$ i] [$公会] [$关键] = $这个 - > ID;
                }其他{
                    $值[$ i] = array_merge(数组($关键=> $这个 - > ID),$值,数组($关键=> $这个 - > ID));
                }
            }

$值[$ i] [$公会] [$关键] = $这个 - > ID;

我在这里倾倒的输出,这种情况下,$值[$ i] [$协会] = 3,这是不是一个数组。

现在,看着贴的数据我也看不出什么毛病。它在cake1.3.14是工作一样吧。

后数据的后续代码var_dump:

 阵列(3){
  [客户] =>
  阵列(20),{
    [NAME] =>
    串(6)ZZTEST
    [PHONE] =>
    串(0)
    [X_PHONE2] =>
    串(0)
    [传真] =>
    串(0)
    [电子邮件] =>
    串(0)
    [X_REQUIRE_PO] =>
    串(1)的N
    [TAXREG] =​​>
    串(0)
    [CREDLIMIT] =>
    串(5)10000
    [X_QCHECKAPP] =>
    串(1)Y型
    [X_PUBLIC_LIABILITY_EXPIRY] =>
    串(10)19-03-2014
    [ADDRESS1] =>
    串(0)
    [ADDRESS2] =>
    串(0)
    [POST_ code] =>
    串(0)
    [DELADDR1] =>
    串(0)
    [DELADDR2] =>
    串(0)
    [DELADDR6] =>
    串(0)
    [说明] =>
    串(0)
    [HEAD_ACCNO] =>
    INT(-1)
    [CURRENCYNO] =>
    INT(0)
    [AVE_DAYS_TO_PAY] =>
    INT(-1)
  }
  [ClientRateGroup] =>
  阵列(1){
    [rate_group_id] =>
    串(1)3
  }
  [ClientExtra] =>
  阵列(2){
    [client_type_id] =>
    串(1)为1
    [client_salesperson_id] =>
    字符串(2)十一五
  }
}

在控制器的一个片段:

 类ClientsController扩展的AppController
{
公共$名字='客户';
公共$使用=阵列('ExonetClient','引用');//该白水回收呼叫引起的问题
函数add()
{    如果(空($这个 - >!请求 - >数据)){
        $这个 - >请求 - >数据['ExonetClient'] ['HEAD_ACCNO'] = -1;
        $这 - >请求 - >数据['ExonetClient'] ['CURRENCYNO'] = 0;
        $这个 - >请求 - >数据['ExonetClient'] ['AVE_DAYS_TO_PAY'] = -1;
        $这个 - >客户端 - >创建();
        未设置($这个 - > ExonetClient-> ClientRateGroup->验证['的client_id']);
        未设置($这个 - > ExonetClient-> ClientExtra->验证['的client_id']);        //允许clients_rate_groups表中的条目如果速率组
        //选择用于客户端
        如果(空($这个 - >!请求 - >数据['ClientRateGroup'] ['rate_group_id'])
            || !空($这个 - >请求 - >数据['ClientExtra'] ['client_type_id'])
        ){            如果($这个 - > ExonetClient->白水回收($这个 - >请求 - >数据阵列('验证'=>真))===真){
                //
                //如果一个AJAX请求,然后回显该项目的ID。
                如果(这 - $> RequestHandler-> isAjax()){
                    回声$这个 - > ExonetClient-> getLastInsertId();
                    出口;
                }
                其他{
                    $这个 - >会话级> setFlash(
                        __(客户端已经成功保存),
                        '默认',
                        阵列(类= GT;'成功')
                    );                    $这个 - >重定向(阵列('行动'=>'指数'));
                }
            }
            其他{
                $错误= __('客户端无法保存请再试一次。);
                如果(这 - $> RequestHandler-> isAjax()){
                    $这个 - >设置('ERROR_MESSAGE',$错误);
                }
                其他{
                    $这个 - >会话级> setFlash($错误);
                }
            }
        }}

下面是相关车型的问题:

客户:

 应用::使用('AppModel','示范');类ExonetClient扩展AppModel
{
    公共$ NAME ='ExonetClient';
    公共$ actsAs =阵列(
        CakephpAssets.Logable'=>阵列('变'=>'连载','的usermodel'=>'用户','USERKEY'=>'USER_ID),
        LocationStorage'=>阵列(),
    );
    公共$ useDbConfig ='exonet';
    公共$ useTable ='DR_ACCS';
    公共$的PrimaryKey ='ACCNO';
    公共$ displayField ='NAME';    公共$ =的hasMany阵列(
        CONTACTLINK'=>阵列(
            '的className => ExonetClientContact',
            FOREIGNKEY'=> ACCNO',
            '依赖'=>真正,
        )
        SubcontractorIncompatibility'=>阵列(
            '的className => ClientsSubcontractor',
            FOREIGNKEY'=> CLIENT_ID,
            '依赖'=>真正,
        )
        '案'= GT;阵列(
            '的className => 文案,
            FOREIGNKEY'=> CLIENT_ID,
            '依赖'=>假,
        )
        作者:preadsheetQueue'=>阵列(
            '的className =>作者:preadsheetQueue',
            FOREIGNKEY'=> CLIENT_ID,
            '依赖'=>假,
        )
        作者:preadsheet'=>阵列(
            '的className =>作者:preadsheet',
            FOREIGNKEY'=> CLIENT_ID,
            '依赖'=>假,
        )
        ClientRateGroup'=>阵列(
            '的className => ClientRateGroup',
            //'joinTable'=> clients_rate_groups',
            FOREIGNKEY'=> CLIENT_ID,
            //'associationForeignKey'=> CLIENT_ID,
            //'独特'=>真正,
            '依赖'=>真正,
            '条件'=> '',
            //'域'=> '',
            秩序= GT;阵列('EFFECTIVE_DATE'=>'DESC','EXPIRY_DATE'=>'DESC'),
            '限制'=> '',
            '抵消'=> '',
            finderQuery'=> ''
            //'deleteQuery'=> '',
            //'insertQuery'=> ''
        )
    );

ClientExtra:

 应用::使用('AppModel','示范');
类ClientExtra扩展AppModel
{
    公共$ NAME ='ClientExtra';
    公共$验证=阵列(
        client_type_id'=>阵列(
            '数字'=>阵列(
                规则= GT;阵列('数字'),
                'allowEmpty'=>真正,
            )
        )
        CLIENT_ID'=>阵列(
            '数字'=>阵列(
                规则= GT;阵列('数字'),
            )
        )
    );
    //该协会下面已与不需要的可以删除所有可能的密钥,那些创建    公共$ =的belongsTo阵列(
        ClientType =>阵列(
            '的className => ClientType',
            FOREIGNKEY'=> client_type_id',
            '条件'=> '',
            '域'=> '',
            秩序= GT; ''
        )
        '客户'=>阵列(
            '的className => ExonetClient',
            FOREIGNKEY'=> CLIENT_ID,
            '条件'=> '',
            '域'=> '',
            秩序= GT; ''
        )
        销售员=>阵列(
            '的className => 销售员,
            FOREIGNKEY'=> client_salesperson_id',
            '条件'=> '',
            '域'=> '',
            秩序= GT; ''
        )
    );
}

ClientRateGroup:

 应用::使用('AppModel','示范');类ClientRateGroup扩展AppModel
{
    公共$ useTable ='clients_rate_groups';
    公共$ NAME ='ClientRateGroup';
    公共$验证=阵列(
        rate_group_id'=>阵列(
            '数字'=>阵列(
                规则= GT;阵列('数字'),
                'allowEmpty'=>真正,
            )
        )
        CLIENT_ID'=>阵列(
            '数字'=>阵列(
                规则= GT;阵列('数字'),
            )
        )
        EFFECTIVE_DATE'=>阵列(
            '日期'=>阵列(
                规则= GT;阵列('约会'),
            )
        )
    );    公共$ =的belongsTo阵列(
        RateGroup'=>阵列(
            '的className => RateGroup',
            FOREIGNKEY'=> rate_group_id',
            '条件'=> '',
            '域'=> '',
            秩序= GT; ''
        )
        '客户'=>阵列(
            '的className => ExonetClient',
            FOREIGNKEY'=> CLIENT_ID,
            '条件'=> '',
            '域'=> '',
            秩序= GT; ''
        )
    );


解决方案

您的数据没有正确保存的hasMany 相关联的数据格式。检查<一个href=\"http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array\"相对=nofollow> 型号:: saveAssociated()


  

有关节能具有的hasMany关联的相关记录一起记录,数据阵列应该是这样的:

  $数据=阵列(
    第'=&GT;阵列('标题'=&GT;我的第一篇文章),
    '注释'=&GT;阵列(
        阵列('身体'=&GT;'注释1','USER_ID =&GT; 1)
        阵列('身体'=&GT;'注释2','USER_ID =&GT; 12)
        阵列('身体'=&GT;'点评三','USER_ID =→40)
    )
);


所以你的 ClientRateGroup 键应该包含数据数组的数组,是这样的:

 'ClientRateGroup'=&GT;阵列(
    阵列('rate_group_id'=→3)

也许你的 ClientExtra 数据也应该被格式化这样的,不知道因为有对客户端没有正确的关联模式,很可能是,这实际上应该是一个客户端hasOne ClientExtra 的关联,很难说。

I have a pear shaped one here. It's driven me nuts and have spent a good part of a day on it. I am hoping someone can have a quick skim through this and point out the obvious.

I've almost completed a cakephp upgrade from 1.3.14 to 2.4.2. One of the remaining issues I am having is with a saveAll model call... it's actually inserting the data for the first array correctly, but throwing an exception with the rest.

The error I'm getting is:

Error: Cannot use string offset as an array 
File: /srv/www/test/public_html/app/Lib/cakephp/lib/Cake/Model/Model.php    
Line: 2453

If I look at Model.php, the issue arises here:

        case 'hasMany':
            foreach ($values as $i => $value) {

                if (isset($values[$i][$association])) {
                    $values[$i][$association][$key] = $this->id;
                } else {                        
                    $values[$i] = array_merge(array($key => $this->id), $value, array($key => $this->id));
                }
            }

$values[$i][$association][$key] = $this->id;

I've dumped the output here, and this case $values[$i][$association] = 3, which isn't an array.

Now, looking at the data posted I can't see anything wrong with it. It is the same as it was working in cake1.3.14.

A var_dump of the post data:

array(3) {
  ["Client"]=>
  array(20) {
    ["NAME"]=>
    string(6) "ZZTEST"
    ["PHONE"]=>
    string(0) ""
    ["X_PHONE2"]=>
    string(0) ""
    ["FAX"]=>
    string(0) ""
    ["EMAIL"]=>
    string(0) ""
    ["X_REQUIRE_PO"]=>
    string(1) "N"
    ["TAXREG"]=>
    string(0) ""
    ["CREDLIMIT"]=>
    string(5) "10000"
    ["X_QCHECKAPP"]=>
    string(1) "Y"
    ["X_PUBLIC_LIABILITY_EXPIRY"]=>
    string(10) "19-03-2014"
    ["ADDRESS1"]=>
    string(0) ""
    ["ADDRESS2"]=>
    string(0) ""
    ["POST_CODE"]=>
    string(0) ""
    ["DELADDR1"]=>
    string(0) ""
    ["DELADDR2"]=>
    string(0) ""
    ["DELADDR6"]=>
    string(0) ""
    ["NOTES"]=>
    string(0) ""
    ["HEAD_ACCNO"]=>
    int(-1)
    ["CURRENCYNO"]=>
    int(0)
    ["AVE_DAYS_TO_PAY"]=>
    int(-1)
  }
  ["ClientRateGroup"]=>
  array(1) {
    ["rate_group_id"]=>
    string(1) "3"
  }
  ["ClientExtra"]=>
  array(2) {
    ["client_type_id"]=>
    string(1) "1"
    ["client_salesperson_id"]=>
    string(2) "25"
  }
}

A snippet of the controller:

class ClientsController extends AppController
{
public $name = 'Clients';
public $uses = array('ExonetClient', 'Quote');

// The saveAll call is causing the problem
function add()
{

    if (!empty($this->request->data)) {
        $this->request->data['ExonetClient']['HEAD_ACCNO']      = -1;
        $this->request->data['ExonetClient']['CURRENCYNO']      = 0;
        $this->request->data['ExonetClient']['AVE_DAYS_TO_PAY'] = -1;
        $this->Client->create();
        unset($this->ExonetClient->ClientRateGroup->validate['client_id']);
        unset($this->ExonetClient->ClientExtra->validate['client_id']);

        // Allow an entry to clients_rate_groups table if the rate group is
        //selected for a client
        if (!empty($this->request->data['ClientRateGroup']['rate_group_id'])
            || !empty($this->request->data['ClientExtra']['client_type_id'])
        ) {

            if ($this->ExonetClient->saveAll($this->request->data, array('validate' => true)) === true) {
                //
                // If an AJAX request, then echo the ID of the item.
                if ($this->RequestHandler->isAjax()) {
                    echo $this->ExonetClient->getLastInsertId();
                    exit;
                }
                else {
                    $this->Session->setFlash(
                        __('The client has been saved successfully'),
                        'default',
                        array('class' => 'success')
                    );

                    $this->redirect(array('action' => 'index'));
                }
            }
            else {
                $error = __('The client could not be saved. Please, try again.');
                if ($this->RequestHandler->isAjax()) {
                    $this->set('error_message', $error);
                }
                else {
                    $this->Session->setFlash($error);
                }
            }
        }

}

Here are the associated models in question:

Client:

App::uses('AppModel', 'Model');

class ExonetClient extends AppModel
{
    public $name         = 'ExonetClient';
    public $actsAs       = array(
        'CakephpAssets.Logable' => array('change' => 'serialize', 'userModel' => 'User', 'userKey' => 'user_id'),
        'LocationStorage' => array(),
    );
    public $useDbConfig  = 'exonet';
    public $useTable     = 'DR_ACCS';
    public $primaryKey   = 'ACCNO';
    public $displayField = 'NAME';

    public $hasMany      = array(
        'ContactLink' => array(
            'className'  => 'ExonetClientContact',
            'foreignKey' => 'ACCNO',
            'dependent'  => true,
        ),
        'SubcontractorIncompatibility' => array(
            'className'  => 'ClientsSubcontractor',
            'foreignKey' => 'client_id',
            'dependent'  => true,
        ),
        'Docket' => array(
            'className' => 'Docket',
            'foreignKey' => 'client_id',
            'dependent' => false,
        ),
        'SpreadsheetQueue' => array(
            'className' => 'SpreadsheetQueue',
            'foreignKey' => 'client_id',
            'dependent' => false,
        ),
        'Spreadsheet' => array(
            'className' => 'Spreadsheet',
            'foreignKey' => 'client_id',
            'dependent' => false,
        ),
        'ClientRateGroup' => array(
            'className' => 'ClientRateGroup',
            //'joinTable' => 'clients_rate_groups',
            'foreignKey' => 'client_id',
            //'associationForeignKey' => 'client_id',
            //'unique' => true,
            'dependent' => true,
            'conditions' => '',
            //'fields' => '',
            'order' => array('effective_date' => 'DESC', 'expiry_date' => 'DESC'),
            'limit' => '',
            'offset' => '',
            'finderQuery' => ''
            //'deleteQuery' => '',
            //'insertQuery' => ''
        ),


    );

ClientExtra:

App::uses('AppModel', 'Model');
class ClientExtra extends AppModel
{
    public $name = 'ClientExtra';
    public $validate = array(
        'client_type_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
                'allowEmpty' => true,
            ),
        ),
        'client_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
    );
    //The Associations below have been created with all possible keys, those that are not needed can be removed

    public $belongsTo = array(
        'ClientType' => array(
            'className' => 'ClientType',
            'foreignKey' => 'client_type_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Client' => array(
            'className'  => 'ExonetClient',
            'foreignKey' => 'client_id',
            'conditions' => '',
            'fields'     => '',
            'order'      => ''
        ),
        'Salesperson' => array(
            'className' => 'Salesperson',
            'foreignKey' => 'client_salesperson_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
}

ClientRateGroup:

App::uses('AppModel', 'Model');

class ClientRateGroup extends AppModel
{
    public $useTable = 'clients_rate_groups';
    public $name = 'ClientRateGroup';
    public $validate = array(
        'rate_group_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
                'allowEmpty' => true,
            ),
        ),
        'client_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
        'effective_date' => array(
            'date' => array(
                'rule' => array('date'),
            ),
        ),
    );

    public $belongsTo = array(
        'RateGroup' => array(
            'className' => 'RateGroup',
            'foreignKey' => 'rate_group_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Client' => array(
            'className'  => 'ExonetClient',
            'foreignKey' => 'client_id',
            'conditions' => '',
            'fields'     => '',
            'order'      => ''
        )
    );

解决方案

Your data is not formatted correctly for saving hasMany associated data. Check the docs for Model::saveAssociated():

For saving a record along with its related records having hasMany association, the data array should be like this:

$data = array(
    'Article' => array('title' => 'My first article'),
    'Comment' => array(
        array('body' => 'Comment 1', 'user_id' => 1),
        array('body' => 'Comment 2', 'user_id' => 12),
        array('body' => 'Comment 3', 'user_id' => 40),
    ),
);

So your ClientRateGroup key should contain an array of data arrays, something like:

'ClientRateGroup' => array(
    array('rate_group_id' => 3)
)

Maybe your ClientExtra data should also be formatted like that, not sure as there is no proper association on the Client model, could very well be that this should actually be a Client hasOne ClientExtra association, hard to tell.

这篇关于CakePHP的模型saveAssociated错误 - 无法使用字符串作为数组offset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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