Maison > Article > développement back-end > Comment créer et utiliser un modèle dans Yii
Cet article analyse la création et l'utilisation de Model dans Yii à travers des exemples. Partagez-le avec tout le monde pour votre référence, comme suit :
YII implémente deux modèles, le modèle de formulaire (classe CFormModel) et le modèle Active Record (classe CAtiveRecord), qui héritent tous deux de la classe CModel. Le modèle de données représenté par CFormModel est l'entrée collectée à partir du formulaire HTML, encapsulant toute la logique (telle que la validation du formulaire et toute autre logique métier, appliquée aux champs du formulaire). Il peut stocker des données en mémoire ou, à l'aide d'un Active Record, dans une base de données.
Opération de connexion à la base de données
Dans config/main.php
'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=oss', 'emulatePrepare' => true, 'username' => 'root', 'password' => 'hahaha', 'charset' => 'utf8', //表前缀 'tablePrefix'=>"oss_" ),
Ouvrez le commentaire, php doit supporter pdo
Afficher le journal des opérations
//显示日志信息,包括sql的查询信息 array( 'class'=>'CWebLogRoute', ),
Activer les commentaires
1 Le modèle basé sur CActiveRecord
Active Record (AR) est un modèle de conception, Accédez aux données de manière abstraite et orientée objet. Dans Yii, chaque instance d'un objet AR peut être la classe CActiveRecord ou sa sous-classe. Il encapsule une ligne d'enregistrements dans une table ou une vue de base de données et encapsule toute la logique et les détails de la base de données qui possède la plupart de la logique métier qui doit être utilisée à l'aide de ce modèle. La valeur de chaque champ de colonne dans une ligne de la table de base de données correspond à un attribut de l'objet AR. Il mappe les tables aux classes, les lignes aux objets et les colonnes aux données de l'objet. C'est-à-dire que chaque instance de la classe Active Record représente une ligne de la table dans la base de données. Mais une classe Active Record n’est pas simplement une relation de mappage entre les champs de la table de base de données et les attributs de la classe. Il doit également traiter une certaine logique métier sur ces données et définir toutes les opérations de lecture et d'écriture sur la base de données.
1) Déclarer un modèle basé sur la classe CActiveRecord
class Post extends CActiveRecord { public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return '{{post}}'; } public function primaryKey() { return 'id'; // return array('pk1', 'pk2'); } }
2) Utiliser la méthode de la classe parent pour effectuer les opérations de base de données
(1) Insérer :
$post=new Post; $post->title='sample post'; $post->content='content for the sample post'; $post->create_time=time(); $post->save();
(2) Sélectionner : Plusieurs méthodes couramment utilisées
// find the first row satisfying the specified condition $post=Post::model()->find($condition,$params); // find the row with the specified primary key $post=Post::model()->findByPk($postID,$condition,$params); // find the row with the specified attribute values $post=Post::model()->findByAttributes($attributes,$condition,$params); // find the first row using the specified SQL statement $post=Post::model()->findBySql($sql,$params); $criteria=new CDbCriteria; $criteria->select='title'; // only select the 'title' column $criteria->condition='postID=:postID'; $criteria->params=array(':postID'=>10); $post=Post::model()->find($criteria); $post=Post::model()->find(array( 'select'=>'title', 'condition'=>'postID=:postID', 'params'=>array(':postID'=>10), )); // find all rows satisfying the specified condition $posts=Post::model()->findAll($condition,$params); // find all rows with the specified primary keys $posts=Post::model()->findAllByPk($postIDs,$condition,$params); // find all rows with the specified attribute values $posts=Post::model()->findAllByAttributes($attributes,$condition,$params); // find all rows using the specified SQL statement $posts=Post::model()->findAllBySql($sql,$params); // get the number of rows satisfying the specified condition $n=Post::model()->count($condition,$params); // get the number of rows using the specified SQL statement $n=Post::model()->countBySql($sql,$params); // check if there is at least a row satisfying the specified condition $exists=Post::model()->exists($condition,$params);
(3) Mettre à jour
// update the rows matching the specified condition Post::model()->updateAll($attributes,$condition,$params); // update the rows matching the specified condition and primary key(s) Post::model()->updateByPk($pk,$attributes,$condition,$params); // update counter columns in the rows satisfying the specified conditions Post::model()->updateCounters($counters,$condition,$params);
(4) Supprimer
$post=Post::model()->findByPk(10); // assuming there is a post whose ID is 10 $post->delete(); // delete the rows matching the specified condition Post::model()->deleteAll($condition,$params); // delete the rows matching the specified condition and primary key(s) Post::model()->deleteByPk($pk,$condition,$params);
(5) Utiliser la transaction
$model=Post::model(); $transaction=$model->dbConnection->beginTransaction(); try { // find and save are two steps which may be intervened by another request // we therefore use a transaction to ensure consistency and integrity $post=$model->findByPk(10); $post->title='new post title'; $post->save(); $transaction->commit(); } catch(Exception $e) { $transaction->rollBack(); }
2. Avant d'écrire le HTML requis pour le formulaire basé sur le modèle de CFormModel
, nous devons décider quelles données nous voulons que l'utilisateur saisisse et quelles règles il doit respecter. Une classe de modèle peut être utilisée pour enregistrer ces informations. Le modèle est au cœur de la maintenance et de la validation des entrées de l'utilisateur
Selon la manière dont nous utilisons les entrées de l'utilisateur, nous pouvons créer deux types de modèles. Si les données saisies par l'utilisateur sont collectées, utilisées, puis supprimées, nous créerons un modèle de formulaire ; si les données saisies par l'utilisateur sont enregistrées dans la base de données, nous utiliserons un enregistrement actif. Les deux modèles héritent de l'interface commune du formulaire défini dans leur classe de base CModel.
1) Définition de la classe de modèle
Dans l'exemple suivant, nous créons un modèle LoginForm pour collecter les entrées de l'utilisateur sur la page de connexion. Étant donné que les informations de connexion ne sont utilisées que pour la vérification de l'utilisateur et n'ont pas besoin d'être enregistrées, nous utilisons le modèle de formulaire pour créer
class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; }
LoginForm déclare un total de trois attributs (attributs) , $username, $ password, $rememberMe
sont utilisés pour enregistrer le nom d'utilisateur, le mot de passe saisi par l'utilisateur et la possibilité de mémoriser ou non la connexion. Étant donné que $rememberMe a une valeur par défaut de false, la case correspondante n'est pas cochée lorsque le formulaire est affiché.
Conseil : Nous utilisons le nom « attributs » au lieu de « propriétés » pour les distinguer des propriétés normales.
2) Déclarer les règles de validation
Une fois les données soumises par l'utilisateur renseignées dans le modèle, nous devons vérifier si elles sont légales avant de les utiliser. Ceci est réalisé en validant l’entrée avec un ensemble de règles. Nous définissons les règles de vérification en configurant un tableau dans la méthode Rulesers()
class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; private $_identity; public function rules() { return array( array('username, password','required'), array('rememberMe', 'boolean'), array('password', 'authenticate'), ); } public function authenticate($attribute,$params) { if(!$this->hasErrors()) // we only want to authenticate when no input errors { $this->_identity=new UserIdentity($this->username,$this->password); if(!$this->_identity->authenticate()) $this->addError('password','Incorrect password.'); } } }
Le code ci-dessus indique que le nom d'utilisateur et le mot de passe sont requis, le mot de passe doit être vérifié et RememberMe doit être Chaque règle renvoyée en booléen
rules() doit être au format suivant
array('AttributeList', 'Validator', 'on'=>'ScenarioList', .. .Options supplémentaires)
AttributeList est une liste de noms d'attributs séparés par des virgules qui doivent être vérifiés. Le validateur indique quelle validation doit être effectuée. Le paramètre facultatif on indique la liste des scénarios dans lesquels la règle est appliquée, (options supplémentaires) est le nom-valeur correspondant, qui est utilisé pour correspondre initialement aux attributs pertinents du validateur
Il existe trois façons de spécifiez le Validator dans une règle. Tout d'abord, Validator peut utiliser une méthode de cette classe, telle que l'authentification dans l'exemple ci-dessus. La méthode Validator doit être déclarée au format suivant
public function ValidatorName($attribute,$params) { ... }
Deuxièmement, Validator peut être le nom de classe du validateur Lorsque les règles sont applicables, une instance de la classe validateur sera créée et effectuera le véritable. validation. Attributs supplémentaires dans la règle, utilisés pour les attributs associés de l'instance initiale. La classe validateur doit hériter de CValidator
Astuce : lors de la spécification des règles pour le modèle d'enregistrement actif, nous pouvons utiliser le paramètre spécial 'on',
Ce Le paramètre peut être 'insert' ou 'update', ce qui permet d'appliquer la règle lors de l'insertion ou de la mise à jour respectivement. S'il n'y a pas de vie, cette règle s'appliquera à chaque appel à save().
第三、Validator 可以使验证器类预先定义的别名。在上面的例子中,“required”便是CRequiredValidator的别名,用来验证属性不能为空。下面是预定义的验证器类别名的列表
? boolean:CBooleanValidator的别名,验证属性的值是否是CBooleanValidator::trueValue 或者 CBooleanValidator::falseValue
? captcha:CCaptchaValidator的别名,验证属性的值是否和CAPTCHA中显示的验证码的值相等
? compare:CCompareValidator的别名,验证属性的值是否等于另一个属性或者一个常量
? email:CEmailValidator的别名,验证属性的值是否是个合法的email地址
? default:CDefaultValueValidator的别名,为属性指派一个默认值
? exist:CExistValidator的别名,验证属性的值是否能在表的列里面找到
? file: CFileValidator 的别名, 验证属性是否包含上传文件的名字
? filter:CFilterValidator的别名,使用一个过滤器转换属性的形式
? in: CRangeValidator 的别名, 验证属性值是否在一个预订的值列表里面
? length: CStringValidator 的别名, 确保了属性值的长度在指定的范围内.
? match: CRegularExpressionValidator 的别名, 验证属性是否匹配一个正则表达式.
? numerical: CNumberValidator 的别名, 验证属性是否是一个有效的数字.
? required: CRequiredValidator 的别名, 验证属性的值是否为空.
? type: CTypeValidator 的别名, 验证属性是否是指定的数据类型.
? unique: CUniqueValidator 的别名, 验证属性在数据表字段中是否是唯一的.
? url: CUrlValidator 的别名, 验证属性是否是一个有效的URL路径.
下面我们给出一些使用预定义验证器的例子。
// username is required array('username', 'required'), // username must be between 3 and 12 characters array('username', 'length', 'min'=>3, 'max'=>12), // when in register scenario, password must match password2 array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'), // when in login scenario, password must be authenticated array('password', 'authenticate', 'on'=>'login'),
3) 安全属性的设置
当一个模型创建之后,我们往往需要根据用户的输入,为它填充属性。这可以方便的通过下面批量赋值的方式来实现
$model=new LoginForm; if(isset($_POST['LoginForm'])) $model->attributes=$_POST['LoginForm'];
最后那条语句便是批量赋值,把$_POST['LoginForm']中每个属性都赋值到对应的模型属性中,它等价于下面的语句
foreach($_POST['LoginForm'] as $name=>$value) { if($name is a safe attribute) $model->$name=$value; }
声明属性是否是安全属性是个至关重要的工作。例如,如果我把把数据表的主键暴露为安全属性,那么便可以通过修改主键的值,来管理本没有权限管理的数据,进行攻击。
4) 1.1版中的安全属性
在1.1版中,如果属性在适用的规则中指定了验证器,则认为是安全的。例如
array('username, password', 'required', 'on'=>'login, register'), array('email', 'required', 'on'=>'register'),
上面的代码中用户名和密码属性在login的场景下不允许为空。用户名、密码邮箱在register的场景下不允许为空。因此如果在login的场景下 进 行批量赋值,仅仅用户名和密码会被赋值,因为login场景下验证规则里仅出现了这两个属性,但是如果是在register场景下,那么这三个属性都 会被 赋值。
// in login scenario $model=new User('login'); if(isset($_POST['User'])) $model->attributes=$_POST['User']; // in register scenario $model=new User('register'); if(isset($_POST['User'])) $model->attributes=$_POST['User'];
那么为什么我们使用如此的策略来决定一个属性是否是安全属性呢?因为一个属性,已经有了一个或者多个对个进行校验的规则,那么我还需要担心吗?
需要记住的是,验证器是用来检测用户输入的数据,而不是我们用代码产生的数据(例如 时间戳,自增的主键等)。因此不要给那些不需要用户输入的属性添加验证器。
有时候我们想声明一些属性为安全属性,但是又不必给指定一个验证规则。例如文章的正文属性,我们可以允许用户的任何输入。为了实现这个目标,我们可以用safe规则。
array('content', 'safe')
对应的也有一个unsafe规则,来指定哪些属性是不安全的
array('permission', 'unsafe')
unsafe并不常用,对你以前定义的安全属性来说,这是个例外
5) 获取验证错误
当验证结束后,任何可能的错误都存储在模型的实例中。我们可以通过调用CModel::getErrors() 和 CModel::getError()重新获取到。这两个方法的区别在于,第一个可以返回指定模型属性的所有错误,而第二个方法只返回了第一条错误。
6) 属性标签
设计表单的时候,我们需要为用户的输入框显示一个标签,来提示用户输入。尽管我们可以再form中写死,但是如果我们在相应的模型中指定的话会更加方便和灵活
默认情况下,CModel 会简单的返回属性的名字作为标签。这可以通过重写attributeLabels() 方法来自定义。在接下来章节中我们将看到,在模型中指定标签可以让我们更快更强大的创建一个form表单
希望本文所述对大家基于yii框架的php程序设计有所帮助。
更多Yii中Model(模型)的创建及使用方法相关文章请关注PHP中文网!