为什么使用多个数据库时缺少Yii MVC findBySQL()方法或闭包?

时间:2012-10-29 19:47:05

标签: php yii

我的应用程序有一个主数据库和许多辅助数据库。我有每个数据库2 GB的限制,所以我必须有多个数据库。

数据必须保存在主数据库和许多辅助数据库之一中。从主数据库中,我知道要保存数据的辅助数据库。

我的数据库不完全相同,存在细微差别。我为主数据库创建了一个模型,为辅助数据库创建了另一个模型。

这是错误:

CException

SlaveUrl and its behaviors do not have a method or closure named "findByUrl".

这是我再次战斗的路线:

$record = SlaveUrl::model()->findByUrl($query);

,它在此代码中找到:

<?php


class ScannerCommand extends CConsoleCommand {

    private $time;
    private $urls = 0;

    /**
     * Executes the command.
     * @param array command line parameters for this command.
     */
    public function run($args) {
        // $args gives an array of the command-line arguments for this command
        $this->time = time();
        $instance_scanner = new InstanceScanner();
        $instance_scanner->create = $this->time;
        $instance_scanner->urls = 0;
        if ($instance_scanner->save()) {
            echo 'scanner start' . PHP_EOL;
            $criteria = new CDbCriteria();
            $criteria->condition = 'status=:status';
            $criteria->order = '`update` asc';
            $criteria->limit = 1;
            $criteria->params = array(':status' => 1);
            $model_website = Website::model()->find($criteria);
            $model_website->update = $this->time;
            $model_website->save();
            echo 'scanning ' . $model_website->name . ' ... ' . PHP_EOL;
            $model_pattern_url = PatternUrl::model()->findByAttributes(array('website_id' => $model_website->id));
            //$website_file_content = file_get_contents($model_website->link);
            $website_file_content = CurlTool::fetchContent($model_website->link,array(),true);
            preg_match_all('/<a href=[\'"](.*?)[\'"].*?>([^<]+)<\/a>/ims', $website_file_content, $matches_url);
            if ((is_array($matches_url[0])) && (count($matches_url[0]) > 0))
                foreach ($matches_url[0] as $key => $value) {
                    $ok = false;
                    preg_match_all($model_pattern_url->pattern, $matches_url[1][$key], $matches_pattern_url);
                    //print_r($matches_pattern_url);
                    if ((is_array($matches_pattern_url)) && (count($matches_pattern_url[0]) > 0))
                        if (strpos($matches_url[1][$key], $matches_pattern_url[0][0]) !== false)
                            $ok = true;

                    SlaveUrl::$server_id = $model_website->server_id;

                    echo $query = "select * from `url` where  ( ( `website_id`='".($model_website->id)."' ) and ( `link`='".($matches_url[1][$key])."' ) ) or (  ( `website_id`='".($model_website->id)."' ) and ( `name` = '".(addslashes($matches_url[2][$key]))."' ) );";

                    $record = SlaveUrl::model()->findByUrl($query);

                    if( $record == null )
                    {

                    $model_slave_url = new SlaveUrl();
                    $model_slave_url->website_id = $model_website->server_id;
                    $model_slave_url->link = $matches_url[1][$key];
                    $model_slave_url->name = $matches_url[2][$key];
                    $model_slave_url->created = time();
                    $model_slave_url->status = 1;

                    if( $model_slave_url->save() )
                    {

                    //$data = Url::model()->findByAttributes(array('website_id' => $model_website->id, 'link' => $matches_url[1][$key], 'name' => $matches_url[2][$key]));
                    $query = "select * from `url` where  ( ( `website_id`='".($model_website->id)."' ) and ( `link`='".($matches_url[1][$key])."' ) ) or (  ( `website_id`='".($model_website->id)."' ) and ( `name` = '".(addslashes($matches_url[2][$key]))."' ) );";
                    echo $query.'<br>';
                    //$command_slave = ;
                    $command = Yii::app()->db->createCommand($query);
                    $data = $command->queryAll();
                    if((count($data)==0) && ($ok === true)) {
                        $model_url = new Url();
                        $model_url->website_id = $model_website->id;
                        $model_url->link = $matches_url[1][$key];
                        $model_url->name = $matches_url[2][$key];
                        $model_url->created = $this->time;
                        $model_url->instance_scanner_id = $instance_scanner->id;
                        $model_url->status = 0;
                        if ($model_url->save())
                            $this->urls++;
                        $command = "INSERT INTO `url` (`id` ,`website_id` ,`link` ,`name` ,`created` ,`instance_scanner_id` ,`status`)VALUES (NULL ,  '".($model_url->website_id)."',  '".($model_url->link)."',  '".(addslashes($model_url->name))."',  '".($model_url->created)."',  '".($model_url->instance_scanner_id)."',  '".($model_url->status)."');";
                    }

                    }

                    }

                }
            echo $this->urls . ' new urls found' . PHP_EOL;
            $instance_scanner->urls = $this->urls;
            $instance_scanner->save();
            echo 'scanner stop';
        }
        else echo 'something went wrong while trying to start the scanning process';
    }

    /**
     * Provides the command description.
     * This method may be overridden to return the actual command description.
     * @return string the command description. Defaults to 'Usage: php entry-script.php command-name'.
     */
    public function getHelp() {
        return 'Usage: how to use this command';
    }

}

这是主要模式:

<?php

/**
 * This is the model class for table "url".
 *
 * The followings are the available columns in table 'url':
 * @property string $id
 * @property integer $server_id
 * @property integer $website_id
 * @property integer $slave_url_id
 * @property string $link
 * @property string $name
 * @property integer $created
 * @property integer $instance_scanner_id
 * @property integer $status
 */
class Url extends CActiveRecord
{
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Url the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'url';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('server_id, website_id, slave_url_id, link, name, created, instance_scanner_id, status', 'required'),
            array('server_id, website_id, slave_url_id, created, instance_scanner_id, status', 'numerical', 'integerOnly'=>true),
            array('link, name', 'length', 'max'=>255),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, server_id, website_id, slave_url_id, link, name, created, instance_scanner_id, status', 'safe', 'on'=>'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'server_id' => 'Server',
            'website_id' => 'Website',
            'slave_url_id' => 'Slave Url',
            'link' => 'Link',
            'name' => 'Name',
            'created' => 'Created',
            'instance_scanner_id' => 'Instance Scanner',
            'status' => 'Status',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id,true);
        $criteria->compare('server_id',$this->server_id);
        $criteria->compare('website_id',$this->website_id);
        $criteria->compare('slave_url_id',$this->slave_url_id);
        $criteria->compare('link',$this->link,true);
        $criteria->compare('name',$this->name,true);
        $criteria->compare('created',$this->created);
        $criteria->compare('instance_scanner_id',$this->instance_scanner_id);
        $criteria->compare('status',$this->status);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }
}

这是Slave模型:

<?php

/**
 * This is the model class for table "url".
 *
 * The followings are the available columns in table 'url':
 * @property string $id
 * @property integer $website_id
 * @property string $link
 * @property string $name
 * @property integer $created
 * @property integer $status
 */
class SlaveUrl extends HActiveRecord
{
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Url the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'url';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('website_id, link, name, created, status', 'required'),
            array('website_id, created, status', 'numerical', 'integerOnly'=>true),
            array('link, name', 'length', 'max'=>255),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, website_id, link, name, created, status', 'safe', 'on'=>'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        'relation_website'=>array(self::BELONGS_TO,'Website','website_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'website_id' => 'Website',
            'link' => 'Link',
            'name' => 'Name',
            'created' => 'Created',
            'status' => 'Status',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id,true);
        $criteria->compare('website_id',$this->website_id);
        $criteria->compare('link',$this->link,true);
        $criteria->compare('name',$this->name,true);
        $criteria->compare('created',$this->created);
        $criteria->compare('status',$this->status);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }
}

以及分配正确的从属DB连接的特殊类:

<?php

class HActiveRecord extends CActiveRecord

{

public static $server_id=1;
   public static $master_db;

   public function getDbConnection()

   {



         self::$master_db=Yii::app()->{"db".self::$server_id};      

         if(self::$master_db instanceof CDbConnection)

         {

            self::$master_db->setActive(true);

            return self::$master_db;

         }

         else

            throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));



   }

   public function getDbConnection2()

   {

      if(self::$master_db!==null)

         return self::$master_db;

      else

      {

         self::$master_db=Yii::app()->db1;

                 echo self::$master_db->connectionString;



         if(self::$master_db instanceof CDbConnection)

         {

            self::$master_db->setActive(true);

            return self::$master_db;

         }

         else

            throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));

      }

   }

}

?>

1 个答案:

答案 0 :(得分:2)

类SlaveUrl或HActiveRecord或CActiveRecord中没有名为findByUrl()的方法 导致错误的原因是什么。

但是有findBySql。 http://www.yiiframework.com/doc/api/1.1/CActiveRecord#findBySql-detail