Heim  >  Artikel  >  Backend-Entwicklung  >  So erstellen und verwenden Sie ein Modell in Yii

So erstellen und verwenden Sie ein Modell in Yii

高洛峰
高洛峰Original
2017-02-06 17:21:371908Durchsuche

In diesem Artikel wird die Erstellung und Verwendung von Modellen in Yii anhand von Beispielen analysiert. Teilen Sie es wie folgt mit allen als Referenz:

YII implementiert zwei Modelle, das Formularmodell (CFormModel-Klasse) und das Active Record-Modell (CAtiveRecord-Klasse), die beide von der CModel-Klasse erben. Das durch CFormModel dargestellte Datenmodell ist die aus dem HTML-Formular gesammelte Eingabe und kapselt die gesamte Logik (z. B. Formularvalidierung und andere Geschäftslogik, die auf die Formularfelder angewendet wird). Es kann Daten im Speicher oder mithilfe eines Active Record in einer Datenbank speichern.

Datenbankverbindungsvorgang

In config/main.php

'db'=>array(
  'connectionString' => 'mysql:host=localhost;dbname=oss',
  'emulatePrepare' => true,
  'username' => 'root',
  'password' => 'hahaha',
  'charset' => 'utf8',
  //表前缀
  'tablePrefix'=>"oss_"
),

Öffnen Sie Kommentare, PHP muss pdo unterstützen

Ansicht das Betriebsprotokoll

//显示日志信息,包括sql的查询信息
array(
  'class'=>'CWebLogRoute',
),

Kommentare aktivieren

1. Modell basierend auf CActiveRecord

Active Record (AR) ist ein Designmuster, Access Daten abstrakt und objektorientiert verarbeiten. In Yii kann jede Instanz eines AR-Objekts die CActiveRecord-Klasse oder ihre Unterklasse sein. Es umschließt eine Reihe von Datensätzen in einer Datenbanktabelle oder -ansicht und kapselt die gesamte Logik und Details der Datenbank, die den Großteil der Geschäftslogik enthält, die bei Verwendung dieses Modells verwendet werden muss. Der Wert jedes Spaltenfelds in einer Zeile in der Datenbanktabelle entspricht einem Attribut des AR-Objekts. Es ordnet Tabellen Klassen, Zeilen Objekten und Spalten den Objektdaten zu. Das heißt, jede Instanz der Active Record-Klasse repräsentiert eine Zeile der Tabelle in der Datenbank. Eine Active Record-Klasse ist jedoch nicht nur eine Zuordnungsbeziehung zwischen Feldern in der Datenbanktabelle und Attributen in der Klasse. Es muss außerdem einige Geschäftslogiken für diese Daten verarbeiten und alle Lese- und Schreibvorgänge in der Datenbank definieren.

1) Deklarieren Sie ein Modell basierend auf der CActiveRecord-Klasse

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) Verwenden Sie die Methode der übergeordneten Klasse, um Datenbankoperationen abzuschließen

(1) Einfügen:

$post=new Post;
$post->title='sample post';
$post->content='content for the sample post';
$post->create_time=time();
$post->save();

(2) Wählen Sie: Mehrere häufig verwendete Methoden

// 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) Aktualisieren

// 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) Löschen

$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) Transaktion verwenden

$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. Bevor wir den für das Formular erforderlichen HTML-Code basierend auf dem CFormModel-Modell schreiben

, müssen wir entscheiden, welche Daten der Benutzer eingeben soll und welche Regeln er einhalten soll. Eine Modellklasse kann zum Aufzeichnen dieser Informationen verwendet werden. Das Modell ist der Kern für die Verwaltung und Validierung von Benutzereingaben.

Abhängig davon, wie wir die Benutzereingaben verwenden, können wir zwei Arten von Modellen erstellen. Wenn die vom Benutzer eingegebenen Daten gesammelt, verwendet und dann verworfen werden, erstellen wir ein Formularmodell. Wenn die vom Benutzer eingegebenen Daten in der Datenbank gespeichert werden, verwenden wir einen aktiven Datensatz. Beide Modelle erben die gemeinsame Schnittstelle des in ihrer Basisklasse CModel definierten Formulars.

1) Definition der Modellklasse

Im folgenden Beispiel erstellen wir ein LoginForm-Modell, um Benutzereingaben auf der Anmeldeseite zu sammeln. Da die Anmeldeinformationen nur zur Benutzerüberprüfung verwendet werden und nicht gespeichert werden müssen, verwenden wir das Formularmodell zum Erstellen von

class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe=false;
}

LoginForm deklariert insgesamt drei Attribute (Attribute) , $username, $password, $rememberMe

werden verwendet, um den Benutzernamen, das vom Benutzer eingegebene Passwort und die Option, ob die Anmeldung gespeichert werden soll, aufzuzeichnen. Da $rememberMe den Standardwert „false“ hat, ist das entsprechende Kontrollkästchen bei der Anzeige des Formulars nicht aktiviert.

Tipp: Wir verwenden den Namen „Attribute“ statt „Eigenschaften“, um sie von normalen Eigenschaften zu unterscheiden.

2) Deklarieren Sie Validierungsregeln

Sobald die vom Benutzer übermittelten Daten in das Modell eingegeben wurden, müssen wir prüfen, ob sie legal sind, bevor wir sie verwenden. Dies wird erreicht, indem die Eingabe mit einem Regelwerk validiert wird. Wir definieren Überprüfungsregeln, indem wir ein Array in der Rulesers()-Methode konfigurieren

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.');
}
}
}

Der obige Code zeigt an, dass der Benutzername und das Passwort erforderlich sind, das Passwort überprüft werden muss und RememberMe muss sein: Jede in boolescher Form zurückgegebene Regel

rules() muss im folgenden Format vorliegen:

array('AttributeList', 'Validator', 'on'=>'ScenarioList', .. .Zusätzliche Optionen)

AttributeList ist eine durch Kommas getrennte Liste von Attributnamen, die überprüft werden müssen. Der Validator gibt an, welche Validierung durchgeführt werden muss. Der optionale on-Parameter gibt die Liste der Szenarien an, in denen die Regel angewendet wird. (Zusätzliche Optionen) ist der entsprechende Namenswert, der zunächst verwendet wird, um den relevanten Attributen des Validators zu entsprechen.

Es gibt drei Möglichkeiten Geben Sie den Validator in einer Regel an. Zunächst kann der Validator eine Methode dieser Klasse verwenden, wie zum Beispiel „authenticate“ im obigen Beispiel. Die Validator-Methode muss im folgenden Format deklariert werden:

public function ValidatorName($attribute,$params) { ... }

Zweitens kann Validator der Klassenname des Validators sein. Wenn die Regeln anwendbar sind, wird eine Instanz der Validator-Klasse erstellt und die eigentliche Aufgabe ausgeführt Validierung. Zusätzliche Attribute in der Regel, die für verwandte Attribute der ursprünglichen Instanz verwendet werden. Die Validator-Klasse muss von CValidator erben


Tipp: Beim Festlegen von Regeln für das aktive Datensatzmodell können wir den speziellen Parameter „on“ verwenden,

Dies Der Parameter kann „insert“ oder „update“ sein, wodurch die Regel beim Einfügen bzw. Aktualisieren angewendet werden kann. Wenn kein Leben vorhanden ist, gilt diese Regel bei jedem Aufruf von 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中文网!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn