Yii 2.0 权威指南 认证

认证

认证是鉴定用户身份的过程。它通常使用一个标识符 (如用户名或电子邮件地址)和一个加密令牌(比如密码或者存取令牌)来 鉴别用户身份。认证是登录功能的基础。

Yii提供了一个认证框架,它连接了不同的组件以支持登录。欲使用这个框架, 你主要需要做以下工作:

  • 设置用户组件 yii\web\User ;
  • 创建一个类实现 yii\web\IdentityInterface 接口。

配置 yii\web\User

用户组件 yii\web\User 用来管理用户的认证状态。这需要你 指定一个含有实际认证逻辑的认证类 yii\web\User::identityClass。 在以下web应用的配置项中,将用户用户组件 yii\web\User 的 认证类 yii\web\User::identityClass 配置成 模型类 app\models\User, 它的实现将在下一节中讲述。

return [    'components' => [        'user' => [            'identityClass' => 'app\models\User',
        ],
    ],
];

认证接口 yii\web\IdentityInterface 的实现

认证类 yii\web\User::identityClass 必须实现包含以下方法的 认证接口 yii\web\IdentityInterface:

  • yii\web\IdentityInterface::findIdentity():根据指定的用户ID查找 认证模型类的实例,当你需要使用session来维持登录状态的时候会用到这个方法。
  • yii\web\IdentityInterface::findIdentityByAccessToken():根据指定的存取令牌查找 认证模型类的实例,该方法用于 通过单个加密令牌认证用户的时候(比如无状态的RESTful应用)。
  • yii\web\IdentityInterface::getId():获取该认证实例表示的用户的ID。
  • yii\web\IdentityInterface::getAuthKey():获取基于 cookie 登录时使用的认证密钥。 认证密钥储存在 cookie 里并且将来会与服务端的版本进行比较以确保 cookie的有效性。
  • yii\web\IdentityInterface::validateAuthKey() :是基于 cookie 登录密钥的 验证的逻辑的实现。

用不到的方法可以空着,例如,你的项目只是一个 无状态的 RESTful 应用,只需实现 yii\web\IdentityInterface::findIdentityByAccessToken() 和 yii\web\IdentityInterface::getId() ,其他的方法的函数体留空即可。

下面的例子是一个通过结合了 user 数据表的 AR 模型 Active Record 实现的一个认证类 yii\web\User::identityClass。

<?phpuse yii\db\ActiveRecord;use yii\web\IdentityInterface;class User extends ActiveRecord implements IdentityInterface{    public static function tableName()
    {        return 'user';
    }    /**
     * 根据给到的ID查询身份。
     *
     * @param string|integer $id 被查询的ID
     * @return IdentityInterface|null 通过ID匹配到的身份对象
     */
    public static function findIdentity($id)
    {        return static::findOne($id);
    }    /**
     * 根据 token 查询身份。
     *
     * @param string $token 被查询的 token
     * @return IdentityInterface|null 通过 token 得到的身份对象
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {        return static::findOne(['access_token' => $token]);
    }    /**
     * @return int|string 当前用户ID
     */
    public function getId()
    {        return $this->id;
    }    /**
     * @return string 当前用户的(cookie)认证密钥
     */
    public function getAuthKey()
    {        return $this->auth_key;
    }    /**
     * @param string $authKey
     * @return boolean if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {        return $this->getAuthKey() === $authKey;
    }
}

如上所述,如果你的应用利用 cookie 登录, 你只需要实现 getAuthKey() 和 validateAuthKey() 方法。这样的话,你可以使用下面的代码在 user 表中生成和存储每个用户的认证密钥。

class User extends ActiveRecord implements IdentityInterface{
    ......    
    public function beforeSave($insert)
    {        if (parent::beforeSave($insert)) {            if ($this->isNewRecord) {                $this->auth_key = \Yii::$app->security->generateRandomString();
            }            return true;
        }        return false;
    }
}

注意:不要混淆 user 认证类和用户组件 yii\web\User。前者是实现 认证逻辑的类,通常用关联了 持久性存储的用户信息的AR模型Active Record 实现。后者是负责管理用户认证状态的 应用组件。

使用用户组件 yii\web\User

在 user 应用组件方面,你主要用到 yii\web\User 。

你可以使用表达式 Yii::$app->user->identity 检测当前用户身份。它返回 一个表示当前登录用户的认证类 yii\web\User::identityClass 的实例, 未认证用户(游客)则返回 null。下面的代码展示了如何从 yii\web\User 获取其他认证相关信息:

// 当前用户的身份实例。未认证用户则为 Null 。$identity = Yii::$app->user->identity;// 当前用户的ID。 未认证用户则为 Null 。$id = Yii::$app->user->id;// 判断当前用户是否是游客(未认证的)$isGuest = Yii::$app->user->isGuest;

你可以使用下面的代码登录用户:

// 使用指定用户名获取用户身份实例。// 请注意,如果需要的话您可能要检验密码$identity = User::findOne(['username' => $username]);// 登录用户Yii::$app->user->login($identity);

yii\web\User::login() 方法将当前用户的身份登记到 yii\web\User。如果 session 设置为 yii\web\User::enableSession,则使用 session 记录用户身份,用户的 认证状态将在整个会话中得以维持。如果开启自动登录 yii\web\User::enableAutoLogin 则基于 cookie 登录(如:记住登录状态),它将使用 cookie 保存用户身份,这样 只要 cookie 有效就可以恢复登录状态。

为了使用 cookie 登录,你需要在应用配置文件中将 yii\web\User::enableAutoLogin 设为 true。你还需要在 yii\web\User::login() 方法中 传递有效期(记住登录状态的时长)参数。

注销用户:

Yii::$app->user->logout();

请注意,启用 session 时注销用户才有意义。该方法将从内存和 session 中 同时清理用户认证状态。默认情况下,它还会注销所有的 用户会话数据。如果你希望保留这些会话数据,可以换成 Yii::$app->user->logout(false) 。

认证事件

yii\web\User 类在登录和注销流程引发一些事件。

  • yii\web\User::EVENT_BEFORE_LOGIN:在登录 yii\web\User::login() 时引发。 如果事件句柄将事件对象的 yii\web\UserEvent::isValid 属性设为 false, 登录流程将会被取消。
  • yii\web\User::EVENT_AFTER_LOGIN:登录成功后引发。
  • yii\web\User::EVENT_BEFORE_LOGOUT:注销 yii\web\User::logout() 前引发。 如果事件句柄将事件对象的 yii\web\UserEvent::isValid 属性设为 false, 注销流程将会被取消。
  • yii\web\User::EVENT_AFTER_LOGOUT:成功注销后引发。

你可以通过响应这些事件来实现一些类似登录统计、在线人数统计的功能。例如, 在登录后 yii\web\User::EVENT_AFTER_LOGIN 的处理程序,你可以将用户的登录时间和IP记录到 user 表中。

Yii2-页面缓存

页面缓存指的是在服务器端缓存整个页面的内容。随后当同一个页面被请求时,内容将从缓存中取出,而不是重新生成。

页面缓存由 [[yii\filters\PageCache]] 类提供支持,该类是一个过滤器。它可以像这样在控制器类中使用:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\PageCache',
            'only' => ['index'],
            'duration' => 60,
            'variations' => [
                \Yii::$app->language,
            ],
            'dependency' => [
                'class' => 'yii\caching\DbDependency',
                'sql' => 'SELECT COUNT(*) FROM post',
            ],
        ],
    ];
}

上述代码表示页面缓存只在 index 操作时启用,页面内容最多被缓存 60 秒,会随着当前应用的语言更改而变化。如果文章总数发生变化则缓存的页面会失效。

如你所见,页面缓存和片段缓存极其相似。它们都支持 durationdependenciesvariationsenabled 配置选项。它们的主要区别是页面缓存是由过滤器实现,而片段缓存则是一个小部件。

你可以在使用页面缓存的同时,使用片段缓存和动态内容。

yii2.0 引入Ueditor

1、在入口文件【index.php】目录下新建public目录和uploads目录,下载ueditor,解压到public目录下;
2、在ueditor/php/config.json中自定义上传目录;将编辑器上传目录指定到/uploads/ueditor;

如"imagePathFormat": "/uploads/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}",   "scrawlPathFormat": "/uploads/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}"

3、在视图中引入ueditor相关js文件,指定要渲染的textarea;

<?phpuse yii\helpers\Html;use yii\bootstrap\ActiveForm;//引入百度编辑器$this->registerJsFile('@web/public/ueditor/ueditor.config.js');//注册自定义js$this->registerJsFile('@web/public/ueditor/ueditor.all.min.js');$this->registerJsFile('@web/public/ueditor/lang/zh-cn/zh-cn.js');?><script>
 $(function(){ 	var ue = UE.getEditor('editor');
 })</script><style>
	.inline .radio,.inline .checkbox{display: inline-block;margin: 0 5px;}
	#editor{margin-top: 20px;padding:0;margin:20px 0;width:100%;height:auto;border: none;}
	</style><?php $form=ActiveForm::begin([		'id'=>'upload',		'enableAjaxValidation' => false,		'options'=>['enctype'=>'multipart/form-data']
	]);?>
	<?= $form->field($model,'title')->textInput();?>
	<?= $form->field($model, 'image')->fileInput();?>
	<?= $form->field($model,'content')->textarea(['rows'=>6,'id'=>'editor','class'=>'col-sm-1 col-md-12']);?>
	<?=  Html::submitButton('提交', ['class'=>'btn btn-primary','name' =>'submit-button']) ?><?php ActiveForm::end();?>4、大功告成,可以开始测试编辑器功能了,编辑器样式按需求设置即可>

yii2 邮件发送

1.在配置文件main-local.php components=>[]里面配置

'mailer' => [  
   'class' => 'yii\swiftmailer\Mailer',  
    'useFileTransport' =>false,//这句一定有,false发送邮件,true只是生成邮件在runtime文件夹下,不发邮件
   'transport' => [  
       'class' => 'Swift_SmtpTransport',  
       'host' => 'smtp.163.com',  //每种邮箱的host配置不一样
       'username' => '15618380091@163.com',  
       'password' => '*******',  
       'port' => '25',  
       'encryption' => 'tls',  
                           
                   ],   
   'messageConfig'=>[  
       'charset'=>'UTF-8',  
       'from'=>['15618380091@163.com'=>'admin']  
       ],  
],
  1. controller控制器中 代码:
<?php$mail= Yii::$app->mailer->compose();   
$mail->setTo('***********@qq.com');  
$mail->setSubject("邮件测试");  
//$mail->setTextBody('zheshisha ');   //发布纯文字文本$mail->setHtmlBody("<br>问我我我我我");    //发布可以带html标签的文本if($mail->send())  
    echo "success";  
else  
    echo "failse";   
die(); 
?>

ok,这样就可以发送邮件了

如需加载模板 把$mail= Yii::$app->mailer->compose(); 
修改成 $mail= Yii::$app->mailer->compose('xiaoma',['aa'=>222]);
注:aa是想xiaoma.php里面传递的参数。
输入图像描述

邮件模板 xiaoma.php里面的代码 :

<?php  
use yii\helpers\Html;  
  
/* @var $this yii\web\View */  
/* @var $user common\models\User */  
  
$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $aa]);  
?>  
  
  
< a href="#" ><?php echo $resetLink ?></a>

加载模板的邮件代码:

$mail= Yii::$app->mailer->compose('xiaoma',['aa'=>222]);  
       $mail->setTo('1401619705@qq.com');  
       $mail->setSubject("邮件测试");  
       $mail->setTextBody('zheshisha ');  
       if($mail->send())  
           echo "success";  
       else  
           echo "failse";   
     die();

希望对你们有帮助!
更多yii2知识整理:http://happymc.iteye.com/

yii2数据缓存示例

首先配置一下缓存,自己选择是用文件缓存还是数据库缓存等。

'cache'   => [ 
    'class' => 'yii\caching\FileCache',
        ],

然后就可以通过 Yii::$app->cache->set()Yii::$app->cache->get() 设置、获取缓存内容了。
下面是一个带缓存依赖的实例:

//表达式依赖
$dp = new ExpressionDependency([
                        'expression' => 'count(Yii::$app->authManager->getPermissionsByUser(Yii::$app->user->id))'
            ]);
//数据库依赖(sql)  
$dp2 = new DbDependency([
            'sql' => 'select max(updated_at) from auth_item',
            ]);
//链式依赖(把以上2个依赖串起来,任何一个发生变化都会使缓存失效)  
Yii::$app->cache->set($key, $value, 0, new ChainedDependency([
            'dependencies' => [$dp, $dp2]
            ]));

Yii2高级版本复制新项目出现问题解决

Yii2高级版本复制新项目会遇到下面的报错信息:

exception ‘yii\base\InvalidRouteException’ with message ‘Unable to resolve the request “site/error”.’ in /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/base/Module.php:461
Stack trace:
#0 /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/web/ErrorHandler.php(80): yii\base\Module->runAction(‘site/error’)
#1 /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/base/ErrorHandler.php(95): yii\web\ErrorHandler->renderException(Object(yii\web\NotFoundHttpException))
#2 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\NotFoundHttpException))
#3 {main}
Previous exception:
exception ‘yii\base\InvalidRouteException’ with message ‘Unable to resolve the request “site/index”.’ in /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/base/Module.php:461
Stack trace:
#0 /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/web/Application.php(83): yii\base\Module->runAction(‘site/index’, Array)
#1 /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#2 /Users/yuzhiyuan/Documents/htdocs/yii-application/mobile/web/index.php(18): yii\base\Application->run()
#3 {main}
Next exception ‘yii\web\NotFoundHttpException’ with message ‘Page not found.’ in /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/web/Application.php:95
Stack trace:
#0 /Users/yuzhiyuan/Documents/htdocs/yii-application/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#1 /Users/yuzhiyuan/Documents/htdocs/yii-application/mobile/web/index.php(18): yii\base\Application->run()
#2 {main}

解决办法:

找到common\config\bootstrap.php

找到上面的文件,添加一个新的别名:
Yii::setAlias(‘应用名’, dirname(dirname(__DIR__)) . ‘/目录名’);
比如:Yii::setAlias(‘mobile’, dirname(dirname(__DIR__)) . ‘/mobile’);

这样就正常显示了,妈的,让我调整了一个下午。

Yii 用户登陆机制  http://www.linuxidc.com/Linux/2015-01/111602.htm

Yii中引入js和css文件  http://www.linuxidc.com/Linux/2015-01/111603.htm

Yii 不完全解决方案  http://www.linuxidc.com/Linux/2015-01/111606.htm

Yii CGridView 基本使用 http://www.linuxidc.com/Linux/2015-01/111607.htm

Yii框架分布式缓存的实现方案 http://www.linuxidc.com/Linux/2015-02/113828.htm

Yii 的详细介绍请点这里
Yii 的下载地址请点这里

yii2-DetailView

yii\widgets\DetailView 小部件显示的是单一 yii\widgets\DetailView::$model 数据的详情。

它非常适合用常规格式显示一个模型(例如在一个表格的一行中显示模型的每个属性)。 这里说的模型可以是 \yii\base\Model 或者其子类的一个实例,例如子类 active record,也可以是一个关联数组。

DetailView使用 yii\widgets\DetailView::$attributes 属性来决定显示模型哪些属性以及如何格式化。 可用的格式化选项,见 formatter section 章节。

一个典型的DetailView的使用方法如下:

echo DetailView::widget([
    'model' => $model,
    'attributes' => [
        'title',               // title attribute (in plain text)
        'description:html',    // description attribute formatted as HTML
        [                      // the owner name of the model
            'label' => 'Owner',
            'value' => $model->owner->name,
        ],
        'created_at:datetime', // creation date formatted as datetime
    ],
]);

Yii2-ListView

yii\widgets\ListView 小部件用于显示数据提供者 data provider 提供的数据。 每个数据模型用指定的视图文件 yii\widgets\ListView::$itemView 来渲染。 因为它提供开箱即用式的(译者注:封装好的)分页、排序以及过滤这样一些特性,所以它可以很方便地为最终用户显示信息并同时创建数据管理界面。

一个典型的用法如下例所示:

use yii\widgets\ListView;
use yii\data\ActiveDataProvider;

$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
]);
echo ListView::widget([
    'dataProvider' => $dataProvider,
    'itemView' => '_post',
]);

_post 视图文件可包含如下代码:

<?php
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
?>
<div class="post">
    <h2><?= Html::encode($model->title) ?></h2>
    
    <?= HtmlPurifier::process($model->text) ?>    
</div>

在上面的视图文件中,当前的数据模型 $model 是可用的。另外,下面的这些变量也是可用的:

  • $key:混合类型,键的值与数据项相关联。
  • $index:整型,是由数据提供者返回的数组中以0起始的数据项的索引。
  • $widget:类型是ListView,是小部件的实例。

假如你需要传递附加数据到每一个视图中,你可以像下面这样用 yii\widgets\ListView::$viewParams 属性传递键值对:

echo ListView::widget([
    'dataProvider' => $dataProvider,
    'itemView' => '_post',
    'viewParams' => [
        'fullView' => true,
        'context' => 'main-page',
        // ...
    ],
]);

在视图中,上述这些附加数据也是可以作为变量来使用的。

yii2-GridView

数据网格或者说 GridView 小部件是Yii中最强大的部件之一。如果你需要快速建立系统的管理后台, GridView 非常有用。它从数据提供者 data provider 中取得数据并使用 yii\grid\GridView::columns 属性的一组列配置,在一个表格中渲染每一行数据。

表中的每一行代表一个数据项的数据,并且一列通常表示该项的属性(某些列可以对应于属性或静态文本的复杂表达式)。

使用GridView的最少代码如下:

use yii\grid\GridView;
use yii\data\ActiveDataProvider;

$dataProvider = new ActiveDataProvider([
    'query' => Post::find(),
    'pagination' => [
        'pageSize' => 20,
    ],
]);
echo GridView::widget([
    'dataProvider' => $dataProvider,
]);

上面的代码首先创建了一个数据提供者,然后使用GridView显示每一行的每个属性,每一行的数据是从数据提供者取来的。 展现出来的表格封装了排序以及分页功能。

表格列

表格的列是通过 yii\grid\Column 类来配置的,这个类是通过 GridView 配置项中的 yii\grid\GridView::columns 属性配置的。根据列的类别和设置的不同,各列能够以不同方式展示数据。 默认的列类是 yii\grid\DataColumn,用于展现模型的某个属性, 并且可以排序和过滤。

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        // 数据提供者中所含数据所定义的简单的列
        // 使用的是模型的列的数据
        'id',
        'username',
        // 更复杂的列数据
        [
            'class' => 'yii\grid\DataColumn', //由于是默认类型,可以省略 
            'value' => function ($data) {
                return $data->name; // 如果是数组数据则为 $data['name'] ,例如,使用 SqlDataProvider 的情形。
            },
        ],
    ],
]);

请注意,假如配置中没有指定 yii\grid\GridView::columns 属性,那么Yii会试图显示数据提供者的模型中所有可能的列。

列类

通过使用不同类,网格列可以自定义:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        [
            'class' => 'yii\grid\SerialColumn', // <-- 这里
            // 你还可以在此配置其他属性
        ],

除了我们下面将要展开讨论的Yii自带的列类,你还可以创建你自己的列类。

每个列类是从 yii\grid\Column 扩展而来, 从而在配置网格列的时候,你可以设置一些公共的选项。

  • yii\grid\Column::header 允许为头部行设置内容。
  • yii\grid\Column::footer 允许为尾部行设置内容。
  • yii\grid\Column::visible 定义某个列是否可见
  • yii\grid\Column::content 允许你传递一个有效的PHP回调来为一行返回数据,格式如下:
    function ($model, $key, $index, $column) {
        return 'a string';
    }
    

你可以传递数组来指定各种容器式的HTML选项:

  • yii\grid\Column::headerOptions
  • yii\grid\Column::footerOptions
  • yii\grid\Column::filterOptions
  • yii\grid\Column::contentOptions

数据列

yii\grid\DataColumn 用于显示和排序数据。这是默认的列的类型, 所以在使用 DataColumn 为列类时,可省略类的指定(译者注:不需要’class’选项的意思)。

数据列的主要配置项是 yii\grid\DataColumn::format 属性。它的值对应于 formatter application component 应用组件里面的一些方法, 默认是使用 \yii\i18n\Formatter 应用组件:

echo GridView::widget([
    'columns' => [
        [
            'attribute' => 'name',
            'format' => 'text'
        ],
        [
            'attribute' => 'birthday',
            'format' => ['date', 'php:Y-m-d']
        ],
    ],
]); 

在上面的代码中,text 对应于 \yii\i18n\Formatter::asText()。列的值作为第一个参数传递。在第二列的定义中,date 对应于 \yii\i18n\Formatter::asDate()。 同样地,列值也是通过第一个参数传递的,而 ‘php:Y-m-d’ 用作第二个参数的值。

可用的格式化方法列表,请参照 section about Data Formatting

数据列配置,还有一个”快捷格式化串”的方法,详情见API文档 yii\grid\GridView::columns。 (译者注:举例说明, "name:text:Name"快捷格式化串,表示列名为 name 格式为 text 显示标签是 Name

动作列

yii\grid\ActionColumn 用于显示一些动作按钮,如每一行的更新、删除操作。

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        [
            'class' => 'yii\grid\ActionColumn',
            // you may configure additional properties here
        ],

可配置的属性如下:

  • yii\grid\ActionColumn::controller 是应该执行这些动作的控制器ID。 如果没有设置,它将使用当前控制器。
  • yii\grid\ActionColumn::template 定义在动作列中使用的构建每个单元格的模板。 在大括号内括起来的的令牌被当做是控制器的 action 方法ID (在动作列的上下文中也称作按钮名称)。 它们将会被 yii\grid\ActionColumn::$buttons 中指定的对应按钮的关联的渲染回调函数替代。 例如,令牌 {view} 将被 buttons['view'] 关联的渲染回调函数的返回结果所替换。 如果没有找到回调函数,令牌将被替换成一个空串。默认的令牌有 {view} {update} {delete}
  • yii\grid\ActionColumn::buttons 是一个按钮的渲染回调数数组。数组中的键是按钮的名字(没有花括号),并且值是对应的按钮渲染回调函数。 这些回调函数须使用下面这种原型:
    function ($url, $model, $key) {
        // return the button HTML code
    }
    

    在上面的代码中,$url 是列为按钮创建的URL,$model是当前要渲染的模型对象,并且 $key 是在数据提供者数组中模型的键。

  • yii\grid\ActionColumn::urlCreator 是使用指定的模型信息来创建一个按钮URL的回调函数。 该回调的原型和 yii\grid\ActionColumn::createUrl() 是一样的。 假如这个属性没有设置,按钮的URL将使用 yii\grid\ActionColumn::createUrl() 来创建。

复选框列

yii\grid\CheckboxColumn 显示一个复选框列。

想要添加一个复选框到网格视图中,将它添加到 yii\grid\GridView::$columns 的配置中,如下所示:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        // ...
        [
            'class' => 'yii\grid\CheckboxColumn',
            // 你可以在这配置更多的属性
        ],
    ],

用户可点击复选框来选择网格中的一些行。被选择的行可通过调用下面的JavaScript代码来获得:

var keys = $('#grid').yiiGridView('getSelectedRows');
// keys 为一个由与被选行相关联的键组成的数组

序号列

yii\grid\SerialColumn 渲染行号,以 1 起始并自动增长。

使用方法和下面的例子一样简单:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'], // <-- here
        // ...

数据排序

注意:这部分正在开发中。

数据过滤

为了过滤数据的 GridView 需要一个模型 model 来 从过滤表单接收数据,以及调整数据提供者的查询对象,以满足搜索条件。 使用活动记录 active records 时,通常的做法是 创建一个能够提供所需功能的搜索模型类(可以使用 Gii 来生成)。 这个类为搜索定义了验证规则并且提供了一个将会返回数据提供者对象的 search() 方法。

为了给 Post 模型增加搜索能力,我们可以像下面的例子一样创建 PostSearch 模型:

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;

class PostSearch extends Post
{
    public function rules()
    {
        // 只有在 rules() 函数中声明的字段才可以搜索
        return [
            [['id'], 'integer'],
            [['title', 'creation_date'], 'safe'],
        ];
    }

    public function scenarios()
    {
        // 旁路在父类中实现的 scenarios() 函数
        return Model::scenarios();
    }

    public function search($params)
    {
        $query = Post::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        // 从参数的数据中加载过滤条件,并验证
        if (!($this->load($params) && $this->validate())) {
            return $dataProvider;
        }

        // 增加过滤条件来调整查询对象
        $query->andFilterWhere(['id' => $this->id]);
        $query->andFilterWhere(['like', 'title', $this->title])
              ->andFilterWhere(['like', 'creation_date', $this->creation_date]);

        return $dataProvider;
    }
}

你可以在控制器中使用如下方法为网格视图获取数据提供者:

$searchModel = new PostSearch();
$dataProvider = $searchModel->search(Yii::$app->request->get());

return $this->render('myview', [
    'dataProvider' => $dataProvider,
    'searchModel' => $searchModel,
]);

然后你在视图中将 $dataProvider$searchModel 对象分派给 GridView 小部件:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        // ...
    ],
]);

处理关系型模型

当我们在一个网格视图中显示活动数据的时候,你可能会遇到这种情况,就是显示关联表的列的值,例如:发帖者的名字,而不是显示他的 id。 当 Post 模型有一个关联的属性名(译者注: Post 模型中用 hasOne 定义 getAuthor() 函数) 叫 author 并且作者模型(译者注:本例的作者模型是 users )有一个属性叫 name,那么你可以通过在 yii\grid\GridView::$columns 中定义属性名为 author.name来处理。这时的网格视图能显示作者名了,但是默认是不支持按作者名排序和过滤的。 你需要调整上个章节介绍的 PostSearch 模型,以添加此功能。

为了使关联列能够排序,你需要连接关系表,以及添加排序规则到数据提供者的排序组件中:

$query = Post::find();
$dataProvider = new ActiveDataProvider([
    'query' => $query,
]);

// 连接与 `users` 表相关联的 `author` 表
// 并将 `users` 表的别名设为 `author`
$query->joinWith(['author' => function($query) { $query->from(['author' => 'users']); }]);
// 使得关联字段可以排序
$dataProvider->sort->attributes['author.name'] = [
    'asc' => ['author.name' => SORT_ASC],
    'desc' => ['author.name' => SORT_DESC],
];

// ...

过滤也需要像上面一样调用joinWith方法。你也需要在属性和规则中定义该列,就像下面这样:

public function attributes()
{
    // 添加关联字段到可搜索属性集合
    return array_merge(parent::attributes(), ['author.name']);
}

public function rules()
{
    return [
        [['id'], 'integer'],
        [['title', 'creation_date', 'author.name'], 'safe'],
    ];
}

然后在 search() 方法中,你仅需要添加一个额外过滤条件:

$query->andFilterWhere(['LIKE', 'author.name', $this->getAttribute('author.name')]);

信息:在上面的代码中,我们使用相同的字符串作为关联名称和表别名; 然而,当你的表别名和关联名称不相同的时候,你得注意在哪使用你的别名,在哪使用你的关联名称。 一个简单的规则是在每个构建数据库查询的地方使用别名,而在所有其他和定义相关的诸如:attributes()rules() 等地方使用关联名称。

例如,你使用 au 作为作者关系表的别名,那么联查语句就要写成像下面这样:

$query->joinWith(['author' => function($query) { $query->from(['au' => 'users']); }]);

当别名已经在关联函数中定义了时,也可以只调用 $query->joinWith(['author']);

在过滤条件中,别名必须使用,但属性名称保持不变:

$query->andFilterWhere(['LIKE', 'au.name', $this->getAttribute('author.name')]);

排序定义也同样如此:

$dataProvider->sort->attributes['author.name'] = [
     'asc' => ['au.name' => SORT_ASC],
     'desc' => ['au.name' => SORT_DESC],
];

同样,当指定使用 yii\data\Sort::defaultOrder 来排序的时候,你需要使用关联名称替代别名:

$dataProvider->sort->defaultOrder = ['author.name' => SORT_ASC];

信息:更多关于 joinWith 和在后台执行查询的相关信息, 可以查看 active record docs on joining with relations

SQL视图用于过滤、排序和显示数据

还有另外一种方法可以更快、更有用 – SQL 视图。例如,我们要在 GridView 中显示用户和他们的简介,可以这样创建 SQL 视图:

CREATE OR REPLACE VIEW vw_user_info AS
    SELECT user.*, user_profile.lastname, user_profile.firstname
    FROM user, user_profile
    WHERE user.id = user_profile.user_id

然后你需要创建活动记录模型来代表这个视图:


namespace app\models\views\grid;

use yii\db\ActiveRecord;

class UserView extends ActiveRecord
{

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'vw_user_info';
    }

    public static function primaryKey()
    {
        return ['id'];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            // 在这定义你的规则
        ];
    }

    /**
     * @inheritdoc
     */
    public static function attributeLabels()
    {
        return [
            // 在这定义你的属性标签
        ];
    }


}

之后你可以使用这个 UserView 活动记录和搜索模型,无需附加的排序和过滤属性的规则。 所有属性都可开箱即用。请注意,这种方法有利有弊:

  • 你不需要指定不同排序和过滤条件,一切都包装好了;
  • 它可以更快,因为数据的大小,SQL查询的执行(对于每个关联数据你都不需要额外的查询)都得到优化;
  • 因为在SQL视图中这仅仅是一个简单的映射UI,所以在你的实体中,它可能缺乏某方面的逻辑,所以,假如你有一些诸如 isActiveisDeleted 或者其他影响到UI的方法, 你也需要在这个类中复制他们。

单个页面多个网格视图部件

你可以在一个单独页面中使用多个网格视图,但是一些额外的配置是必须的,为的就是它们相互之间不干扰。 当使用多个网格视图实例的时候,你必须要为生成的排序和分页对象配置不同的参数名,以便于每个网格视图有它们各自独立的排序和分页。 你可以通过设置 yii\data\Sort::sortParam 和 yii\data\Pagination::pageParam,对应于数据提供者的 yii\data\BaseDataProvider::$sort 和 yii\data\BaseDataProvider::$pagination 实例。

假如我们想要同时显示 PostUser 模型,这两个模型已经在 $userProvider$postProvider 这两个数据提供者中准备好, 具体做法如下:

use yii\grid\GridView;

$userProvider->pagination->pageParam = 'user-page';
$userProvider->sort->sortParam = 'user-sort';

$postProvider->pagination->pageParam = 'post-page';
$postProvider->sort->sortParam = 'post-sort';

echo '<h1>Users</h1>';
echo GridView::widget([
    'dataProvider' => $userProvider,
]);

echo '<h1>Posts</h1>';
echo GridView::widget([
    'dataProvider' => $postProvider,
]);

Using GridView with Pjax

注意: 这部分正在开发中。

待定

Yii 2.0: yii2-ckeditor-widget

Installation

Skins & Plugins

Usage

Further Information

Resources

Installation

The preferred way to install this extension is throughcomposer.

Either run php composer.phar require "2amigos/yii2-ckeditor-widget" "*" or add "2amigos/yii2-ckeditor-widget" : "*"

to the require section of your application’s composer.json file.

Skins & Plugins

This widget works with default’s dev-full/stable branch of CKEditor, with a set of plugins and skins. If you wish to configure a different skins or plugins that the one proposed, you will have to download them separately and configure the widget’s clientOptions attribute accordingly.

Usage

The library comes with two widgets: CKEditor and CKEditorInline. One is for classic edition and the other for inline editing respectively.

Using a model with a basic preset:

use dosamigos\ckeditor\CKEditor;
 
<?= $form->field($model, 'text')->widget(CKEditor::className(), [
        'options' => ['rows' => 6],        'preset' => 'basic'
    ]) ?>

Using inline edition with basic preset:

use dosamigos\ckeditor\CKEditorInline;
 
<?php CKEditorInline::begin(['preset' => 'basic']);?>
    This text can be edited now :)
<?php CKEditorInline::end();?>Your code here...

Further Information

Please, check the CKEditor plugin site documentation for further information about its configuration options.

Resources

2amigOS!
web development has never been so fun
www.2amigos.us

Be the first person to leave a comment

Please  to leave your comment.