问题描述:

I have the following code and the when I call my find method it shows me this: "Invalid argument supplied for foreach()" in CActiveFinder at line 784:

$pk=array();

784 foreach($this->_pkAlias as $name=>$alias)

785 {

786 if(isset($row[$alias]))

787 $pk[$name]=$row[$alias];

788 else // no matching related objects

789 return null;

790 }

791 $pk=serialize($pk);

It fails when it reaches this code:

$objCampanie = $modelCampanii->with('stocs')->findAll();

Relations from class Campanii:

 * @property Stoc[] $stocs

* @property Vanzari[] $vanzaris

public function relations()

{

return array(

'stocs' => array(self::HAS_MANY, 'Stoc', 'id_campanie'),

'vanzaris' => array(self::HAS_MANY, 'Vanzari', 'id_campanie'),

);

}

Relations from class Stoc

* @property Produse $codProdus

* @property Campanii $idCampanie

* @property Vanzari[] $vanzaris

public function relations()

{

return array(

'codProdus' => array(self::BELONGS_TO, 'Produse', 'cod_produs'),

'idCampanie' => array(self::BELONGS_TO, 'Campanii', 'id_campanie'),

'vanzaris' => array(self::HAS_MANY, 'Vanzari', 'cod_produs'),

);

}

Where is the problem? Why does it not retrieves my code?

Table structure:

Campanii:

CREATE TABLE IF NOT EXISTS `campanii` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`nume` varchar(255) NOT NULL,

`data_comanda` date NOT NULL,

`data_scadenta` date NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

Stoc:

CREATE TABLE IF NOT EXISTS `stoc` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`id_campanie` int(11) NOT NULL,

`cod_produs` varchar(10) NOT NULL,

`cantitate` int(11) NOT NULL,

`pret` double NOT NULL DEFAULT '0',

PRIMARY KEY (`id`),

KEY `id_campanie` (`id_campanie`),

KEY `cod_produs` (`cod_produs`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

--

-- Constraints for table `stoc`

--

ALTER TABLE `stoc`

ADD CONSTRAINT `stoc_ibfk_1` FOREIGN KEY (`id_campanie`) REFERENCES `campanii` (`id`),

ADD CONSTRAINT `stoc_ibfk_2` FOREIGN KEY (`cod_produs`) REFERENCES `produse` (`cod`);

网友答案:

The problem was due to a missing primary key in the stoc table. The reason why follows:

private function populateRecord($query,$row)
{
    // determine the primary key value
    if(is_string($this->_pkAlias))  // single key
    {
        if(isset($row[$this->_pkAlias]))
            $pk=$row[$this->_pkAlias];
        else    // no matching related objects
            return null;
    }
    else // is_array, composite key
    {
        $pk=array();
        foreach($this->_pkAlias as $name=>$alias)
        {
            if(isset($row[$alias]))
                $pk[$name]=$row[$alias];
            else    // no matching related objects
                return null;
        }
        $pk=serialize($pk);
    }
...

The above code is from CActiveFinder. As you can see, if the _pkAlias of a table is not a string, then it assumes it's an array, without checking to see if any primary key exists at all.

Therefore, when you call with('stocs'), CActiveFinder tries to populate the related records (meaning, populateRecord is called), which tries to figure out the PK as part of its normal process, and so fails due to the lack of a PK.

Ultimately, it is the result of an incorrect assumption in the framework code. It can be worked around (as you found) by simply creating a PK.

You can look at CActiveFinder, starting on line 385, to see how the value of _pkAlias is set.

https://github.com/yiisoft/yii/blob/1.1.13/framework/db/ar/CActiveFinder.php

网友答案:

I get same error in CActiveFinder(834) after Yii framework update from 1.1.11 to 1.1.14. All was worked before update, all primary keys was setted.

After some struggling I found that errors is gone when I cleaned my YiiCache (I have CDbCache enabled in my config).

TRUNCATE YiiCache or DELETE FROM YiiCache

相关阅读:
Top