yii2 模型

胡勇健發表於2024-03-30

yii2 模型

Yii2的模型(Model)是MVC(Model-View-Controller)設計模式中的一部分,它代表業務資料、規則和邏輯的物件。模型通常用於處理與資料相關的業務邏輯,如資料的驗證、訪問和修改等。

模型示例程式碼

yii2 模型
<?php  
  
namespace app\models;  
  
use Yii;  
use yii\db\ActiveRecord;  
  
/**  
 * User模型  
 *  
 * @property int $id  
 * @property string $username  
 * @property string $email  
 * @property string $password_hash  
 */  
class User extends ActiveRecord  
{  
    /**  
     * 返回與這個類關聯的資料庫表名  
     *  
     * @return string  
     */  
    public static function tableName()  
    {  
        return 'user'; // 對應的資料庫表名  
    }  
  
    /**  
     * 返回此模型的屬性標籤  
     *  
     * @return array  
     */  
    public function attributeLabels()  
    {  
        return [  
            'id' => 'ID',  
            'username' => '使用者名稱',  
            'email' => '郵箱',  
            'password_hash' => '密碼',  
        ];  
    }  
  
    /**  
     * 驗證規則  
     *  
     * @return array  
     */  
    public function rules()  
    {  
        return [  
            [['username', 'email', 'password_hash'], 'required'],  
            ['email', 'email'],  
            ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => '該使用者名稱已存在。'],  
            // 其他驗證規則...  
        ];  
    }  
  
    /**  
     * 在儲存之前,密碼需要被雜湊處理  
     *  
     * @return bool  
     */  
    public function beforeSave($insert)  
    {  
        if (parent::beforeSave($insert)) {  
            if (!$this->isNewRecord) {  
                $this->password_hash = Yii::$app->security->generatePasswordHash($this->password_hash);  
            }  
            return true;  
        }  
        return false;  
    }  
  
    // ... 其他模型方法,如自定義查詢方法、關聯定義等  
}

操作模型

建立記錄

yii2 模型
    // 查詢一個使用者  
    $user = User::findOne($id);  
      
    // 建立一個新使用者  
    $newUser = new User();  
    $newUser->username = 'example';  
    $newUser->email = 'example@example.com';  
    $newUser->password_hash = Yii::$app->security->generatePasswordHash('password123');  
    $newUser->save(); // 儲存使用者到資料庫  
      
    // 驗證模型資料  
    if ($newUser->load(Yii::$app->request->post()) && $newUser->save()) {  
        // 儲存成功  
    } else {  
        // 驗證失敗,顯示錯誤資訊  
    }

讀取記錄

yii2 模型
// 讀取單個記錄  
$user = User::findOne(1); // 透過主鍵ID讀取  
if ($user) {  
    echo $user->name;  
} else {  
    echo 'User not found.';  
}  
  
// 讀取多個記錄  
$users = User::find()->all(); // 讀取所有使用者  
foreach ($users as $user) {  
    echo $user->name . '<br>';  
}  
  
// 根據條件讀取記錄  
$users = User::find()  
    ->where(['status' => 'active'])  
    ->orderBy('created_at DESC')  
    ->limit(10)  
    ->all();

更新記錄

yii2 模型
// 載入要更新的記錄  
$user = User::findOne(1);  
if ($user) {  
    $user->name = 'New Name';  
    $user->email = 'newemail@example.com';  
  
    // 儲存更新到資料庫  
    if ($user->save()) {  
        echo 'User updated successfully!';  
    } else {  
        echo 'Failed to update user.';  
    }  
} else {  
    echo 'User not found.';  
}

刪除記錄

yii2 模型
// 刪除指定ID的使用者  
$user = User::findOne(1);  
if ($user) {  
    if ($user->delete()) {  
        echo 'User deleted successfully!';  
    } else {  
        echo 'Failed to delete user.';  
    }  
} else {  
    echo 'User not found.';  
}  
  
// 根據條件刪除多個記錄  
User::deleteAll(['status' => 'inactive']); // 刪除所有狀態為inactive的使用者

驗證規則

yii2 模型
<?php  
  
namespace app\models;  
  
use yii\base\Model;  
  
class MyForm extends Model  
{  
    public $name;  
    public $email;  
    public $password;  
  
    /**  
     * @return array the validation rules.  
     */  
    public function rules()  
    {  
        return [  
            // name欄位是必填項  
            ['name', 'required'],  
            // name欄位的長度應在3到255個字元之間  
            ['name', 'string', 'min' => 3, 'max' => 255],
            // email欄位是必填項,並且必須是有效的電子郵件地址
            ['email', 'required'],
            ['email', 'email'],
            
            // password欄位是必填項,並且長度應在6到255個字元之間
            ['password', 'required'],
            ['password', 'string', 'min' => 6, 'max' => 255],
            
            // 自定義驗證規則
            ['password', 'validatePassword']
        ];
    }
    
    /**
    * 自定義驗證器方法
    *
    * @param string $attribute 屬性名
    * @param mixed $params 驗證引數
    */
    public function validatePassword($attribute, $params)
    {
        if (!$this->hasErrors()) { // 如果之前沒有錯誤,才執行自定義驗證
            // 這裡新增自定義驗證邏輯,例如檢查密碼複雜度等
            if (!preg_match('/[a-z]/', $this->password) || !preg_match('/[A-Z]/', $this->password) || !preg_match('/\d/', $this->password)) {
                $this->addError($attribute, '密碼必須包含至少一個小寫字母、一個大寫字母和一個數字。');
            }
        }
    }
}

呼叫模型驗證

yii2 模型
$model = new MyForm();  
  
// 假設$data是從表單提交中獲取的陣列  
if ($model->load($data) && $model->validate()) {  
    // 資料驗證透過,可以執行儲存或其他操作  
} else {  
    // 資料驗證失敗,可以獲取錯誤資訊並顯示給使用者  
    $errors = $model->getFirstErrors();  
    // 處理$errors...  
}

常用驗證規則

yii2 模型
public function rules()  
{  
    return [  
        [['username', 'email'], 'required'],
        ['email', 'email'],
        ['username', 'string', 'max' => 255],
        ['age', 'number'],
        ['post_count', 'integer'],
        ['password', 'compare', 'compareAttribute' => 'password_repeat'],
        ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'],
        ['status', 'in', 'range' => [0, 1, 2]],
        ['description', 'filter', 'filter' => 'trim'],
        ['custom_field', 'validateCustomField'],
];  
}

public function validateCustomField($attribute, $params)
{
    if (!preg_match('/[a-zA-Z]+/', $this->$attribute)) {
    $this->addError($attribute, 'The custom field must contain at least one letter.');
    }
}

模型關係

  • 一對多
yii2 模型
<?php  
  
namespace app\models;  
  
use yii\db\ActiveRecord;  
  
class User extends ActiveRecord  
{  
    // ... 其他屬性和方法 ...  
  
    /**  
     * @return \yii\db\ActiveQuery  
     */  
    public function getPosts()  
    {  
        return $this->hasMany(Post::class, ['user_id' => 'id']);  
    }  
}
  • 一對一
yii2 模型
<?php  
  
namespace app\models;  
  
use yii\db\ActiveRecord;  
  
class Post extends ActiveRecord  
{  
    // ... 其他屬性和方法 ...  
  
    /**  
     * @return \yii\db\ActiveQuery  
     */  
    public function getUser()  
    {  
        return $this->hasOne(User::class, ['id' => 'user_id']);  
    }  
}
  • 呼叫
yii2 模型
$user = User::findOne(1); // 假設使用者ID為1  
$posts = $user->posts; // 透過getPosts()方法訪問關係  
  
$post = Post::findOne(10); // 假設帖子ID為10  
$user = $post->user; // 透過getUser()方法訪問關係
yii2 模型
$users = User::find()->with('posts')->all();  
  
foreach ($users as $user) {  
    // 這裡可以直接訪問$user->posts,不需要額外的資料庫查詢  
    foreach ($user->posts as $post) {  
        
    }  
}