Yii

来自tomtalk
跳转至: 导航搜索

基础知识

核心应用组件
  • request 组件用于解析用户请求并提供例如 URL,cookie 等信息。
  • assetManager 管理私有资源文件的发布。
  • authManager 管理基于角色的访问控制 (RBAC).
  • cache 提供数据缓存功能。注意,你必须指定实际的类(例如[CMemCache], [CDbCache])。 否则,当你访问此组件时将返回 NULL。
  • clientScript 管理客户端脚本 (javascripts 和 CSS).
  • coreMessages 提供 Yii 框架用到的核心信息的翻译。
  • db 提供数据库连接。注意,使用此组件你必须配置其 [connectionString|CDbConnection::connectionString] 属性。
  • errorHandler 处理未捕获的 PHP 错误和异常。
  • format 格式化数值显示。此功能从版本 1.1.0 起开始提供。
  • messages 提供Yii应用中使用的信息翻译。
  • securityManager 提供安全相关的服务,例如散列,加密。
  • session 提供session相关的功能。
  • statePersister 提供全局状态持久方法。
  • urlManager 提供 URL 解析和创建相关功能
  • user 提供当前用户的识别信息。
  • themeManager 管理主题。

路由是大小写敏感的,可以通过设置[CUrlManager::caseSensitive]为false使路由对大小写不敏感。


布局

布局是一种用来修饰视图的特殊的视图文件.它通常包含了用户界面中通用的一部分视图.例如:布局可以包含header和footer的部分,然后把内容嵌入其间.

......header here......
<?php echo $content; ?>
......footer here......

其中的 $content 则储存了内容视图的渲染结果.

如何在视图中,调用多个模板?

模块

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

模块在一些场景里很有用。对大型应用来说,我们可能需要把它划分为几个模块,每个模块可以单独维护和部署。一些通用的功能,例如用户管理, 评论管理,可以以模块的形式开发,这样他们就可以容易地在以后的项目中被复用。

模块可以无限级嵌套。这就是说,一个模块可以包含另一个模块,而这另一个模块又可以包含其他模块。我们称前者为 父模块 ,后者为 子模块. 子模块必须定义在其父模块的 [modules|CWebModule::modules] 属性中,就像我们前面在应用配置中定义模块一样。


目录

Yii 假定了一系列默认的目录用于不同的场合。如果需要,每个目录都可以自定义。

  • WebRoot/protected: 这是 应用基础目录, 是放置所有安全敏感的PHP脚本和数据文件的地方。Yii 有一个默认的 application 别名指向此目录。 此目录及目录中的文件应该保护起来防止Web用户访问。它可以通过 [CWebApplication::basePath] 自定义。
  • WebRoot/protected/runtime: 此目录放置应用在运行时产生的私有临时文件。 此目录必须对 Web 服务器进程可写。它可以通过 [CApplication::runtimePath]自定义。
  • WebRoot/protected/extensions: 此目录放置所有第三方扩展。 它可以通过 [CApplication::extensionPath] 自定义。
  • WebRoot/protected/modules: 此目录放置所有的应用 模块,每个模块使用一个子目录。
  • WebRoot/protected/controllers: 此目录放置所有控制器类文件。 它可以通过 [CWebApplication::controllerPath] 自定义。
  • WebRoot/protected/views: 此目录放置所有试图文件, 包含控制器视图,布局视图和系统视图。 它可以通过 [CWebApplication::viewPath] 自定义。
  • WebRoot/protected/views/ControllerID: 此目录放置单个控制器类中使用的视图文件。 此处的 ControllerID 是指控制器的 ID 。它可以通过 [CController::viewPath] 自定义。
  • WebRoot/protected/views/layouts: 此目录放置所有布局视图文件。它可以通过 [CWebApplication::layoutPath] 自定义。
  • WebRoot/protected/views/system: 此目录放置所有系统视图文件。 系统视图文件是用于显示异常和错误的模板。它可以通过 [CWebApplication::systemViewPath] 自定义。
  • WebRoot/assets: 此目录放置公共资源文件。 资源文件是可以被发布的,可由Web用户访问的私有文件。此目录必须对 Web 服务器进程可写。 它可以通过 [CAssetManager::basePath] 自定义
  • WebRoot/themes: 此目录放置应用使用的不同的主题。每个子目录即一个主题,主题的名字即目录的名字。 它可以通过 [CThemeManager::basePath] 自定义。

数据库

多数Web 应用是由数据库驱动的。为了最佳时间,我们 推荐在对表和列命名时使用如下命名规范。注意,这些规范并不是 Yii 所必须的。

  • 数据库表名和列名都使用小写命名。
  • 名字中的单词应使用下划线分割 (例如 product_order)。
  • 对于表名,你既可以使用单数也可以使用复数。但 不要 同时使用两者。为简单起见,我们推荐使用单数名字。
  • 表名可以使用一个通用前缀,例如 tbl_ 。这样当应用所使用的表和另一个应用说使用的表共存于同一个数据库中时就特别有用。 这两个应用的表可以通过使用不同的表前缀很容易地区别开。


开发流程
  1. 创建目录结构骨架。创建第一个Web应用 中讲到的 yiic 工具可以快速实现此步骤。
  2. 配置此 应用。这是通过修改应用配置文件实现的。 此步骤可能也需要编写一些应用组件(例如用户组件)。
  3. 为所管理的每个类型的数据创建一个 模型 类。 Creating First Yii Application 和 Automatic Code Generation 中讲述的 Gii 工具可以用于快速为每个数据表创建 active record 类。
  4. 为每个类型的用户请求 创建一个 控制器 类。 具体如何对用户请求归类要看实际需求。总体来说,如果一个模型类需要被用户访问,他就应该有一个相应的控制器类。 Gii 工具也可以自动实现这一步骤。
  5. 实现 动作 和他们相应的 视图。 这是真正所需要做的工作。
  6. 在控制器类中配置必要的动作 过滤器。
  7. 如果需要主题功能,创建 主题 。
  8. 如果需要 国际化(I18N) ,创建翻译信息。
  9. 对可缓存的数据点和视图点应用适当的 缓存 技术。
  10. 最终 调整 与部署。

使用表单

在 Yii 中处理表单时,通常需要以下步骤:

  1. 创建用于表现所要收集数据字段的模型类。
  2. 创建一个控制器动作,响应表单提交。
  3. 在视图脚本中创建与控制器动作相关的表单。
CFormModel的示例
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)
	{
		$this->_identity=new UserIdentity($this->username,$this->password);
		if(!$this->_identity->authenticate())
			$this->addError('password','错误的用户名或密码。');
	}
}
预定义的验证器别名的完整列表:
  • boolean: 确保特性有一个 [CBooleanValidator::trueValue] 或 [CBooleanValidator::falseValue] 值。
  • captcha: 确保特性值等于 CAPTCHA 中显示的验证码。
  • compare: 确保特性等于另一个特性或常量。
  • email: 确保特性是一个有效的Email地址。
  • default: 指定特性的默认值。
  • exist: 确保特性值可以在指定表的列中可以找到。
  • file: 确保特性含有一个上传文件的名字。
  • filter: 通过一个过滤器改变此特性。
  • in: 确保数据在一个预先指定的值的范围之内。
  • length: 确保数据的长度在一个指定的范围之内。
  • match: 确保数据可以匹配一个正则表达式。
  • numerical: 确保数据是一个有效的数字。
  • required: 确保特性不为空。
  • type: 确保特性是指定的数据类型。
  • unique: 确保数据在数据表的列中是唯一的。
  • url: 确保数据是一个有效的 URL。
创建动作
public function actionLogin()
{
	$model=new LoginForm;
	if(isset($_POST['LoginForm']))
	{
		// 收集用户输入的数据
		$model->attributes=$_POST['LoginForm'];
		// 验证用户输入,并在判断输入正确后重定向到前一页
		if($model->validate())
			$this->redirect(Yii::app()->user->returnUrl);
	}
	// 显示登录表单
	$this->render('login',array('model'=>$model));
}


新增、编辑表单

public function actionAddLession()
{
    $model = new Lession;
 
    if (isset($_POST['Lession'])) {
        $model->attributes = $_POST['Lession'];
        $model->teacher_id = $this->_user['masterId'];
 
        if ($model->validate()) {
            $file = XUpload::upload($_FILES['attach']);
            if (is_array($file)) {
                $model->pic = $file['pathname'];
                @unlink($_POST['oAttach']);
                @unlink($_POST['oThumb']);
            }
        }
 
        if ($model->save()) {
            $this->redirect(array('mylession'));
        }
    }
 
    $this->render('addlession', array(
        'model' => $model,
    ));
}
 
 
public function actionUpdateLesson()
{
    $model = Lession::model()->findByPk($_GET['id']);
 
    if (isset($_POST['Lession'])) {
        $model->attributes = $_POST['Lession'];
 
        if ($model->validate() AND $model->save()) {
            $this->redirect(array('mylession'));
        }
    }
 
    $this->render('addlession', array('model' => $model));
}

使用数据库

Yii 的Active Record( AR ),实现了被广泛采用的对象关系映射(ORM)办法,进一步简化数据库编程。按照约定,一个类代表一个表,一个实例代表一行数据。Yii AR消除了大部分用于处理CRUD(创建,读取,更新和删除)数据操作的sql语句的重复任务。

尽管Yii的DAO和AR能够处理几乎所有数据库相关的任务,您仍然可以在Yii application中使用自己的数据库库。事实上,Yii框架精心设计使得可以与其他第三方库同时使用。


单表操作

虽然 Yii DAO 可以处理几乎任何数据库相关的任务, 但很可能我们会花费 90% 的时间以编写一些执行普通 CRUD(create, read, update 和 delete)操作的 SQL 语句。 而且我们的代码中混杂了SQL语句时也会变得难以维护。要解决这些问题,我们可以使用 Active Record。

选最好项目,使用AR。

AR配置
class Post extends CActiveRecord
{
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
 
    public function tableName()
    {
        return 'tbl_post';
    }
}

由于 AR 类经常在多处被引用,我们可以导入包含 AR 类的整个目录,而不是一个个导入。 例如,如果我们所有的 AR 类文件都在 protected/models 目录中,我们可以配置应用如下: Tom [php] return array(

'import'=>array(
    'application.models.*',
),
创建记录
$post=new Post;
$post->title='sample post';
$post->content='post body content';
$post->save();
读取记录

静态方法 model() 是每个 AR 类所必须的。

如果使用给定的查询条件在数据库中没有找到任何东西, find 方法将返回 null 。

$post=Post::model()->find($condition,$params);                         // 查找满足指定条件的结果中的第一行
$post=Post::model()->findByPk($postID,$condition,$params);             // 查找具有指定主键值的那一行
$post=Post::model()->findByAttributes($attributes,$condition,$params); // 查找具有指定属性值的行
$post=Post::model()->findBySql($sql,$params);                          // 通过指定的 SQL 语句查找结果中的第一行

当有多行数据匹配指定的查询条件时,我们可以通过下面的 findAll 方法将他们全部带回。 每个都有其各自的 find 方法,就像我们已经讲过的那样。

$posts=Post::model()->findAll($condition,$params);                         //查找满足指定条件的所有行
$posts=Post::model()->findAllByPk($postIDs,$condition,$params);            // 查找带有指定主键的所有行
$posts=Post::model()->findAllByAttributes($attributes,$condition,$params); // 查找带有指定属性值的所有行
$posts=Post::model()->findAllBySql($sql,$params);                          // 通过指定的SQL语句查找所有行
 
$rows = UsersFamily::model()->findAll(array(
    'condition' => 'host_uid=' . $this->getUid()
));

如果没有任何东西符合查询条件,findAll 将返回一个空数组。这跟 find 不同,find 会在没有找到什么东西时返回 null。

除了上面讲述的 find 和 findAll 方法,为了方便,(Yii)还提供了如下方法:

$n=Post::model()->count($condition,$params);       // 获取满足指定条件的行数
$n=Post::model()->countBySql($sql,$params);        // 通过指定的 SQL 获取结果行数
$exists=Post::model()->exists($condition,$params); // 检查是否至少有一行复合指定的条件
删除记录

如果一个 AR 实例被一行数据填充,我们也可以删除此行数据。

$post=Post::model()->findByPk(10); // 假设有一个帖子,其 ID 为 10
$post->delete();                   // 从数据表中删除此行

代码片断

public function actionSettingSave()
{
    if (isset($_POST['ID'])) {
        $model = Settings::model()->findByAttributes(array('ID' => $_POST['ID']));
        $model->NAME = $_POST['NAME'];
        $model->VALUE = $_POST['VALUE'];
        $model->DESC = $_POST['DESC'];
        $model->update(array('NAME','VALUE','DESC'));
    } else {
        $model = new Settings;
        $model->_attributes = $_POST;
        $model->insert();
    }
 
    echo json_encode(array(
        'success' => true
    ));
}

关系型 Active Record

在我们使用 AR 执行关联查询之前,我们需要让 AR 知道一个 AR 类是怎样关联到另一个的。

两个 AR 类之间的关系直接通过 AR 类所代表的数据表之间的关系相关联。在 AR 中,有四种关系:

  • BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A (例如 Post 属于 User);
  • HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B (例如 User 有多个 Post);
  • HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B (例如 User 最多有一个 Profile);
  • MANY_MANY: 这个对应于数据库中的 多对多 关系。 由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表将 多对多 关系分割为 一对多 关系。

在我们的示例数据结构中,tbl_post_category 就是用于此目的的。 在 AR 术语中,我们可以解释 MANY_MANY 为 BELONGS_TO 和 HAS_MANY 的组合。 例如,Post 属于多个(belongs to many) Category ,Category 有多个(has many) Post.


yii中获取get,post和cookie参数

Yii::app()->request->getParam() 相当于REQUEST

Yii::app()->request->getPost() 相当于post

Yii::app()->request->getBrowser() 返回用户浏览器的相关信息

Yii::app()->request->getCookies() 返回cookie信息

yii框架中的session和cookie设置、使用以及清空 (2013-05-23 11:04:17)转载▼
标签: session cookie 王乐乐	分类: Yii框架
我们在开发项目中南面使用到session给和cookie,那么在yii中有他自己的规则
如下案例:
  session使用
    function actionS1(){
        echo $this->id;
        echo $this->action->id;
        设置session,通过session组件来设置
        Yii::app()->session['username'] = "zhangsan";
        Yii::app()->session['useraddr'] = "beijing";
        echo "make session success";
    }
   
    function actionS2(){
        使用session
        echo Yii::app()->session['username'];
        echo Yii::app()->session['useraddr'];
        echo "use session success";
    }
   
    function actionS3(){
        删除一个session
        unset(Yii::app()->session['useraddr']);
       
        删除全部session
        Yii::app()->session->clear();  //删除session变量
        Yii::app()->session->destroy(); //删除服务器的session信息
    }
   
   cookie在Yii框架使用

    function actionC1(){
        设置cookie
        $ck = new CHttpCookie('hobby','篮球,足球');
        $ck -> expire = time()+3600;
        把$ck对象放入cookie组件里边
        Yii::app()->request->cookies['hobby'] = $ck;

数据库操作

private function getTeachers($student_id)
{
    $teachers = Yii::app()->db->createCommand()
        ->select('t.*, cat.catalog_name')
        ->from('seed_teacher t')
        ->leftjoin('seed_student_teacher st', 't.id=st.teacher_id')
        ->leftjoin('seed_catalog as cat', 'cat.id=t.catalog_id')
        ->where('st.student_id=:student_id', array(':student_id' => $student_id))
        ->order('ctime desc')
        ->limit(4, $pager->currentPage * $pager->pageSize)
        ->queryAll();
 
    return $teachers;
}


Yii直接执行SQL语句

//查询
$connection = Yii::app()->db;  
$sql = "SELECT * FROM `project` ORDER BY id DESC";  
$command = $connection->createCommand($sql);  
$result = $command->queryAll();  
print_r($result);  
 
//更新
$connection = Yii::app()->db;
$sql = "update seed_student_lesson set qrcode = '123456' where student_id = $student_id and lesson_id = $lesson_id";
$command = $connection->createCommand($sql);
$command->execute()