Hi all.
I want to develop a website using Yii.
I designed the app but i got into trouble when trying to write data in secondary databases;
My app scans certain websites, and extract data/urls from each website, if a data matches a pattern.
I need secondary db’s because i have a limit of 2 GB/ db, and i will erase data from the main db older that 1 month; and the old data will still be available in the secondary db’s;
I will describe now my app structure:
1 main database; 1 model class for my URLs table structure; 1 model class for my WEBSITEs table structure; the urls know to which website they belong using a website_id
a lot of secondary databases, containing 1 model for my website table structure, 1 model for my url table structure, different from the main URL table and WEBSITE table.
I will write the code, and this is the line where i got stuck : self::$master_db=Yii::app()->db1;
db1, may be replaced with db2, db3, db4 …
how to set this dinamycly ?
<?php
class ScannerController extends Controller
{
private $time;
private $urls = 0;
private $slave_urls = 0;
public function actionIndex()
{
//log info
error_reporting(E_ALL);
ini_set('display_errors','on');
$info = array();
$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));
CurlTool::downloadFile($model_website->link, $model_website->id.'.html', array(), true);
$website_file_content = file_get_contents('./files/'.$model_website->id.'.html');
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);
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;
$criteria_url = new CDbCriteria();
$criteria_url->condition = "((website_id=:website_id)and(link=:link))or((website_id=:website_id)and(name=:name))";
$criteria_url->params = array(':website_id'=>$model_website->id,':link'=>$matches_url[1][$key],':name'=>$matches_url[2][$key]);
$find_url = Url::model()->find($criteria_url);
if(($find_url==null)&&($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++;
try
{
$criteria_slave_url = new CDbCriteria();
$criteria_slave_url->condition = "((website_id=:website_id)and(link=:link))or((website_id=:website_id)and(name=:name))";
$criteria_slave_url->params = array(':website_id' => $model_url->website_id,':link'=>$model_url->link,':name'=>$model_url->name);
$find_slave_url = SlaveUrl::model()->find($criteria_slave_url);
if($find_slave_url==null)
{
$model_slave_url = new SlaveUrl();
$model_slave_url->website_id = $model_website->id;
$model_slave_url->link = $matches_url[1][$key];
$model_slave_url->name = $matches_url[2][$key];
$model_slave_url->created = $this->time;
$model_slave_url->status = 0;
if ($model_slave_url->save(false))$this->slave_urls++;
}
}
catch(Exception $e)
{
echo 'catch 2<br/>';
//echo $e2;
}
}
}
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';
//$this->render('index',array('info'=>$info));
//reset/refresh code goes here
}
// Uncomment the following methods and override them if needed
/*
public function filters()
{
// return the filter configuration for this controller, e.g.:
return array(
'inlineFilterName',
array(
'class'=>'path.to.FilterClass',
'propertyName'=>'propertyValue',
),
);
}
public function actions()
{
// return external action classes, e.g.:
return array(
'action1'=>'path.to.ActionClass',
'action2'=>array(
'class'=>'path.to.AnotherActionClass',
'propertyName'=>'propertyValue',
),
);
}
*/
}
<?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 $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('website_id, link, name, created, instance_scanner_id, status', 'required'),
array('website_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, website_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(
'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',
'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('website_id',$this->website_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,
));
}
}
<?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,
));
}
}
<?php
class HActiveRecord extends CActiveRecord
{
public static $master_db;
public function getDbConnection()
{
if(self::$master_db!==null)
return self::$master_db;
else
{
self::$master_db=Yii::app()->db1;//this here needs to be dinamyc
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.'));
}
}
}
?>