1. 云栖社区>
  2. PHP教程>
  3. 正文

[置顶] yii知识宝库

作者:用户 来源:互联网 时间:2017-12-01 18:26:27

配置文件控制器知识

[置顶]        yii知识宝库 - 摘要: 本文讲的是[置顶] yii知识宝库, [置顶] yii知识宝库,有需要的朋友可以参考下。 应用app 配置文件protected/config/main.php 类型 相关类 CWebApplication CApplication CCon

[置顶] yii知识宝库,有需要的朋友可以参考下。


应用app

配置文件protected/config/main.php

类型

相关类

CWebApplication

CApplication

CConsoleApplication

控制器Controller

存放路径protected/controllers/ControllerID.php

相关类Controller、CController、CBaseController

其它对象

类型

生效方式

相关类

action

函数actionXxx()

存在即生效

extends CAction:改写run()

改写actions()函数以指定action

CAction

filter

函数filterXxx()

改写filters()函数以指定filter

extends CFilter:

改写preFilter($filterChain)、postFilter($filterChain)

CFilter

模型Model

存放路径protected/models/ModelID.php

其它对象

CFormModel

CActiveRecord

视图view

存放路径protected/views/ControllerID/ViewID.php

其它对象

相关类

布局

布局被隐式应用.视图脚本 protected/views/layouts/main.php

可以通过改变 CWebApplication::layout进行自定义。

要渲染一个不带布局的视图,则需调用 renderPartial() 。

小物件

<?php $this->beginWidget('path.to.WidgetClass'); ?>

或者<?php $this->widget('path.to.WidgetClass'); ?>

继承 CWidget 并覆盖其init() 和 run() 方法,可以定义一个新的小物件:class MyWidget extends CWidget

CWidget

系统view

在 framework/views 下, Yii 提供了一系列默认的系统视图. 他们可以通过在 protected/views/system 下创建同名视图文件进行自定义.

组件Component

Yii 应用建立于组件之上。组件是 CComponent 或其子类的实例

声明形式

return array(

......

'components'=>array(

'user'=>array(

// enable cookie-based authentication

'allowAutoLogin'=>true,

),

),

......

);

组件属性

公共成员变量即可。更灵活的方式是定义其 getter 和 setter 方法

组件事件(特殊的属性)

组件事件以 on 开头的命名方式定义

如:public function onClicked($event)

1.其中$event是事件的参数,2.$event是CEvent或其子类的实例。

一个事件可以绑定多个句柄。当事件触发时, 这些句柄将被按照它们绑定到事件时的顺序依次执行。如果句柄决定组织后续句柄被执行,它可以设置 $event->handled 为 true。

组件行为

行为类必须实现 IBehavior 接口。大多数行为可以继承自CBehavior。如果一个行为需要绑定到一个模型, 它也可以从专为模型实现绑定特性的 CModelBehavior 或 CActiveRecordBehavior 继承。

要使用一个行为,它必须首先通过调用此行为的 attach() 方法绑定到一个组件。然后我们就可以通过组件调用此行为方法:

// $name 在组件中实现了对行为的唯一识别

$component->attachBehavior($name,$behavior);

// test() 是行为中的方法。

$component->test();

模块Module

存放路径protected/modules

访问形式r=moduleID/controllerID/actionID

可以使用Gii中的模块创建器创建新模块的基本骨架。

特征

1.模块是一个独立的软件单元,它包含 模型, 视图, 控制器 和其他支持的组件。 在许多方面上,模块看起来像一个 应用。主要的区别就是模块不能单独部署,它必须存在于一个应用里。

2.模块组织在一个目录中,目录的名字即模块的唯一 ID 。 模块目录的结构跟 应用基础目录 很相似。

相关类

CWebModule

声明形式

return array(

......

'modules'=>array('forum',...),

......

);

传参形式:

return array(

......

'modules'=>array(

'forum'=>array(

'postPerPage'=>20,

),

),

......

);

嵌套的模块(可以无限级嵌套)

一个模块可以包含另一个模块,而这另一个模块又可以包含其他模块。我们称前者为 父模块 ,后者为 子模块. 子模块必须定义在其父模块的 modules 属性中,就像我们前面在应用配置中定义模块一样。

要访问子模块中的控制器动作,我们应使用路由 parentModuleID/childModuleID/controllerID/actionID.

路径别名

声明形式

YiiBase::getPathOfAlias(), 别名可以被翻译为其相应的路径。 例如, system.web.CController 会被翻译为 yii/framework/web/CController。

通过调用 YiiBase::setPathOfAlias(),我们可以定义新的根路径别名。

常用别名

Yii 预定义了以下几个根别名:Root Alias

system: 表示 Yii 框架目录;

zii: 表示 Zii 库 目录;

application: 表示应用的 基础目录;

webroot: 表示 入口脚本 文件所在的目录。此别名从版本 1.0.3 开始有效。

ext: 表示包含了所有第三方 扩展 的目录。此别名从版本 1.0.8 开始有效。

可用于模块

额外的,如果应用使用了 模块, (Yii) 也为每个模块ID定义了根别名,指向相应模块的跟目录。 此功能从版本 1.0.3 起有效。

Importing Classes

导入类的定义

例如,如果我们想包含 CController 类的定义,Yii::import('system.web.CController');

import 方法跟 include 和 require 不同,它更加高效。 导入(import)的类定义并不会真正被包含进来,直到它第一次被引用。 多次导入同样的名字空间也会比 include_once 和 require_once 快得多。

预导入

使用Class Map导入

从1.1.5版本开始,Yii允许用户定义的类通过使Class Map机制来预先导入,这也是Yii内置类使用的方法。 预先引入机制可以在Yii应用的任何地方使用,无需显式地导入或者包含文件。这个特性对于一个建立在Yii基础上的框架或者类库来说很有用。

若要使用预导入功能,要在CWebApplication::run()执行前执行下面的代码:

Yii::$classMap=array(

'ClassName1' => 'path/to/ClassName1.php',

'ClassName2' => 'path/to/ClassName2.php',

......

);

导入目录

我们还可以使用如下语法导入整个目录,这样此目录下的类文件就会在需要时被自动包含。

Yii::import('system.web.*');

其它用法

除 import 外, 别名还在其他许多地方指向类。 例如,路径别名可以传递给 Yii::createComponent() 以创建相应类的实例。 即使类文件在之前从未被包含。

URL

默认情况下,Yii 识别如下格式的 URL:

http://hostname/index.php?r=ControllerID/ActionID

r GET 变量意为 路由(route) ,它可以被Yii解析为 控制器和动作。 如果 ActionID 被省略,控制器将使用默认的动作(在CController::defaultAction中定义); 如果 ControllerID 也被省略(或者 r 变量不存在),应用将使用默认的控制器 (在CWebApplication::defaultController中定义)。

验证器

1.指定验证器

示例:改写model(CFormModel或CActiveRecord类)的rules()方法即可指定验证器,如用于登录的表单model

class LoginForm extends CFormModel{

public function rules()

{

return array(

array('username, password', 'required'),

array('rememberMe', 'boolean'),

array('password', 'authenticate'),

);

}

}

有三种方式可在验证规则中指定 Validator:

第一, Validator 可以是模型类中一个方法的名字,就像上面示例中的 authenticate 。验证方法必须是下面的结构:

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

第二,Validator 可以是一个验证器类的名字,当此规则被应用时, 一个验证器类的实例将被创建以执行实际验证。规则中的附加选项用于初始化实例的属性值。 验证器类必须继承自 CValidator。

第三,Validator 可以是一个预定义的验证器类的别名。一般, required 名字是 CRequiredValidator 的别名。

系统预定义的验证器在framework/validators/CXxxValidator.php

2.触发数据验证

一旦模型被用户提交的数据填充,就可以调用 CModel::validate() 触发数据验证进程。此方法返回一个指示验证是否成功的值。

对 CActiveRecord 模型来说的验证也可以在我们调用其 CActiveRecord::save() 方法时自动触发。

3.提取验证错误

验证完成后,任何可能产生的错误将被存储在模型对象中。 我们可以通过调用 CModel::getErrors() 和CModel::getError() 提取这些错误信息

一个简单的表单相关示例代码:

//表单模型protected/models/LoginForm.php

class LoginForm extends CFormModel

{

rules(){…}

attributeLabels(){…}

}

//控制器位于protected/controllers/SiteController.php

class SiteController extends Controller

{

...

public function actionLogin() //动作login

{

$model=new LoginForm; //生成model(这里是表单)实例

// if it is ajax validation request //如果是ajax方式的验证,处理方法是向客服端打印验证结果,而不是像普通验证那样进行页面跳转

if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

{

echo CActiveForm::validate($model);

Yii::app()->end();

}//???那何时login呢

// collect user input data

if(isset($_POST['LoginForm']))

{

$model->attributes=$_POST['LoginForm']; //安全的特性赋值(给model(这里是表单)实例赋值)(attributes 属性由 CModel 定义)

// validate user input and redirect to the previous page if valid

if($model->validate() && $model->login()) //触发验证

$this->redirect(Yii::app()->user->returnUrl);//如果验证成功,重定向用户浏览器到之前需要身份验证的页面。

}

// display the login form

$this->render('login',array('model'=>$model)); //验证或登录失败,则跳回名为login的view,(当前的模型$model作为参数,以填充页面)

}

//视图位于protected/views/site/login.php; protected/views/site/index.php等等

表单帮助者:CHtml和CActiveForm。

用于生成先进的表单html,能直接带有与服务端一致的客户端验证。

创建CHtml和CActiveForm实例时,需要将一个model实例(CFormModel)作为一个参数传给帮助者,原因是(1)以便帮助者知道有那些验证条件;(2)CFormModel的获取特性标签名的方法attributeLabels()为帮助者提供了显示label的字符串。

CHtml

Yii 提供了几个助手(helper)类简化视图编写。例如, 要创建一个文本输入域,我们可以调用 CHtml::textField()

CActiveForm

从版本 1.1.1 开始,提供了一个新的小物件 CActiveForm 以简化表单创建。 这个小物件可同时提供客户端及服务器端无缝的、一致的验证。

表单生成器CForm。(自版本 1.1.0)

包括哪些数据模型关联到此表单,以及如何渲染整个表单。

一、Controller

public function actionLogin()

{

$model = new LoginForm;

$form = new CForm('application.views.site.loginForm', $model);

//1.CForm构造时一定接收了$_POST['LoginForm'],2.指定表单配置文件,3.指定了model

if($form->submitted('login') && $form->validate())//这里,$form调用validate(),其实是引起$model自身的validate()调用

$this->redirect(array('site/index'));

else

$this->render('login', array('form'=>$form));//验证失败的话,则跳回名为login的view,(当前的$form作为参数,以填充页面)

}

二、view视图login.php,很简单,如下。(echo $form;相当于echo $form->render();)

<h1>Login</h1>

<div class="form">

<?php echo $form; ?>

</div>

三、表单配置文件放在protected/views/ControllerID/xxx.php。它返回一个数组,指定表单中有哪些输入框,如

return array(

'title'=>'Please provide your login credential',

'elements'=>array(

'username'=>array(

'type'=>'text',

'maxlength'=>32,

),

'password'=>array(

'type'=>'password',

'maxlength'=>32,

),

'rememberMe'=>array(

'type'=>'checkbox',

)

),

'buttons'=>array(

'login'=>array(

'type'=>'submit',

'label'=>'Login',

),

),

);

访问表单元素

和访问数组元素一样简单。CForm::elements 属性返回一个 CFormElementCollection 对象, 它扩展自 CMap 并允许以类似于一个普通数组的方式来访问它的元素。例如,要访问登录表单中的元素 username,我们可以使用下面的代码:

$username = $form->elements['username'];

$email = $form->elements['user']->elements['email'];//对于子表单的情况

或简化为

$username = $form['username'];

$email = $form['user']['email']; //对于子表单的情况

特殊的表单配置文件形式

1.对于type为list的,包括 dropdownlist, checkboxlist 和 radiolist。

'gender'=>array(

'type'=>'dropdownlist',

'items'=>User::model()->getGenderOptions(),//利用模型model来返回array作为列表下拉选项

'prompt'=>'Please select:',

),

//model文件

class User extends CActiveRecord

{

public function getGenderOptions()

{

return array(

0 => 'Male',

1 => 'Female',

);

}

2.除了内置的类型, type 选项也可以是一个 widget 类名字或 widget 类的路径别名。 widget 类必须扩展自 CInputWidget 或 CJuiInputWidget。当渲染输入元素时, 一个指定 widget 类的实例将被创建并渲染。

3.指定静态文本

可以在 CForm::elements 集合中指定HTML 代码作为静态文本。只要指定静态文本字符串作为一个数组元素,在 CForm::elements 恰当的位置。例如,

return array(

'elements'=>array(

......

'password'=>array(

'type'=>'password',

'maxlength'=>32,

),

'<hr />',

'rememberMe'=>array(

'type'=>'checkbox',

)

),

......

);

4.嵌套表单(指定子表单)

子表单被用来分离一个长的表单为几个逻辑部分。 例如,我们可以分离用户注册表单为两部分:登录信息和档案信息。 每个子表单和一个数据模型有无关联均可。若一个子表单需要关联一个数据模型,我们也可以配置它的 CForm::model 属性。

return array(

'elements'=>array(

......

'user'=>array(

'type'=>'form',

'title'=>'Login Credential',

'elements'=>array(

'username'=>array(

'type'=>'text',

),

'password'=>array(

'type'=>'password',

),

'email'=>array(

'type'=>'text',

),

),

),

对于嵌套表单的Controller、view、表单配置文件的写法请参见yiichina.com

表格输入验证(注意:这里yiichina.com的写法可能有点错误,我这里已修正)

//控制器处理

public function actionBatchUpdate()

{

// 假设每一项(item)是一个 'Item' 类的实例,

// 提取要通过批量模式更新的项

$items=$this->getItemsToUpdate();

if(isset($_POST['Item']))

{

$valid=true;

foreach($items as $i=>$item)

{

if(isset($_POST['Item']))

$item->attributes=$_POST['Item'];

$valid=$valid && $item->validate();//所有条目有效才算有效

}

if($valid) // 如果所有项目有效

// ...则在此处做一些操作

}

// 显示视图收集表格输入

$this->render('batchUpdate',array('items'=>$items));//转发到视图batchUpdate

}

//视图batchUpdate显示。("[$i]name"的形式)

<?php echo CHtml::beginForm(); ?>

<table>

<tr><th>Name</th><th>Price</th><th>Count</th><th>Description</th></tr>

<?php foreach($items as $i=>$item): ?>

<tr>

<td><?php echo CHtml::activeTextField($item,"[$i]name"); ?></td>

<td><?php echo CHtml::activeTextField($item,"[$i]price"); ?></td>

<td><?php echo CHtml::activeTextField($item,"[$i]count"); ?></td>

<td><?php echo CHtml::activeTextArea($item,"[$i]description"); ?></td>

</tr>

<?php endforeach; ?>

</table>

<?php echo CHtml::submitButton('Save'); ?>

<?php echo CHtml::endForm(); ?>

</div><!-- form -->

使用数据库连接

法一:

$connection=new CDbConnection($dsn,$username,$password);

// 建立连接。你可以使用 try...catch 捕获可能抛出的异常

$connection->active=true;

......

$connection->active=false; // 关闭连接

法二:

由于 CDbConnection 继承自 CApplicationComponent,将其作为一个 应用组件 使用,在应用配置 中配置一个 db (或其他名字)应用组件如下:

array(

......

'components'=>array(

......

'db'=>array(

'class'=>'CDbConnection',

'connectionString'=>'mysql:host=localhost;dbname=testdb',

'username'=>'root',

'password'=>'password',

'emulatePrepare'=>true, // needed by some MySQL installations

),

),

)

执行sql

$command=$connection->createCommand($sql);

一条 SQL 语句会通过 CDbCommand 以如下两种方式被执行:

execute(): 执行一个无查询 (non-query)SQL语句, 例如 INSERT, UPDATE 和 DELETE 。如果成功,它将返回此执行所影响的行数。

query(): 执行一条会返回若干行数据的 SQL 语句,例如 SELECT。 如果成功,它将返回一个 CDbDataReader 实例,通过此实例可以遍历数据的结果行。为简便起见, (Yii)还实现了一系列 queryXXX() 方法以直接返回查询结果。

$rowCount=$command->execute(); // 执行无查询 SQL

$dataReader=$command->query(); // 执行一个 SQL 查询

$rows=$command->queryAll(); // 查询并返回结果中的所有行

$row=$command->queryRow(); // 查询并返回结果中的第一行

$column=$command->queryColumn(); // 查询并返回结果中的第一列

$value=$command->queryScalar(); // 查询并返回结果中第一行的第一个字段

获取查询结果

在CDbCommand::query() 生成 CDbDataReader 实例之后,你可以通过重复调用 CDbDataReader::read() 获取结果中的行。你也可以在 PHP 的 foreach 语言结构中使用 CDbDataReader 一行行检索数据。

$dataReader=$command->query();

// 重复调用 read() 直到它返回 false

while(($row=$dataReader->read())!==false){ ... }

// 使用 foreach 遍历数据中的每一行

foreach($dataReader as $row) { ... }

// 一次性提取所有行到一个数组

$rows=$dataReader->readAll();

执行 SQL 语句时


以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索配置文件 , 控制器 , 知识 ,以便于您获取更多的相关知识。