使用AR event-like方法处理model fields

Yii中实现的Active Record非常强大,并有很多特性。其中一个特性就是event-like方法,你可以在将存入数据库之前或者从数据库中取出来时,利用它预处理模型字段,也可以删除和模型相关的数据等等。

在本节中,我们将会链接post文本中所有的URL,并列出所有存在的Active Record event-like方法。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. 设置数据库连接并创建一个名叫post的表:
  1. DROP TABLE IF EXISTS 'post';
  2. CREATE TABLE IF NOT EXISTS 'post' (
  3. 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  4. 'title' VARCHAR(255) NOT NULL,
  5. 'text' TEXT NOT NULL,
  6. PRIMARY KEY ('id')
  7. );
  1. 使用Gii生成Post模型。

如何做…

  1. 添加如下方法到models/Post.php
  1. /**
  2. * @param bool $insert
  3. *
  4. * @return bool
  5. */
  6. public function beforeSave($insert)
  7. {
  8. $this->text = preg_replace(
  9. '~((?:https?|ftps?)://.*?)(|$)~iu',
  10. '<a href="\1">\1</a>\2',
  11. $this->text
  12. );
  13. return parent::beforeSave($insert);
  14. }
  1. 现在尝试保存一个包含链接的帖子,创建controllers/TestController.php
  1. <?php
  2. namespace app\controllers;
  3. use app\models\Post;
  4. use yii\helpers\Html;
  5. use yii\helpers\VarDumper;
  6. use yii\web\Controller;
  7. /**
  8. * Class TestController.
  9. * @package app\controllers
  10. */
  11. class TestController extends Controller
  12. {
  13. public function actionIndex()
  14. {
  15. $post = new Post();
  16. $post->title = 'links test';
  17. $post->text = 'before http://www.yiiframework.com/
  18. after';
  19. $post->save();
  20. return $this->renderContent(Html::tag('pre',
  21. VarDumper::dumpAsString(
  22. $post->attributes
  23. )));
  24. }
  25. }
  1. 现在,运行test/index。你会得到如下结果:

使用AR event-like方法处理model fields - 图1

工作原理…

ActiveRecord类中实现的方法beforeSave是在保存之前执行的。使用一个正则表达式,我们将所有的URL替换成链接。为了防止保存,你可以返回false。

参考