YII学习,初体验 ,对YII的一些理解.
先说点没用的:
不会选择,选择后不坚持,不断的选择.这是人生中的一个死循环,前两一直迷茫.觉得自己前进方向很不明朗.想去学的东西有很多.想学好YII,想学PYTHON 想学学hadoop什么的,又想研究下mongodb.还想学习redis.这么多的想法一股脑的涌入我的脑海,一下让我这个脑袋不堪重负.一下就乱了阵脚.于是静下心来好好想想.经历了几天的思想挣扎.终于静下心来,从最想学的开始,研究YII.在网上无意中看见这句话,觉得挺符合我当时的心境的.现在想想.其实无非是,贵在坚持.
想好好学习YII的框架,在网上一片好评的框架.可是我发现网上真的很少有能够让初学者感兴趣的文章.所有文章一概的搬官方的指南,或者是翻译两本国外的图书,根本很难理解,很生涩.而且很多地方不适合国内环境.其实很多人学习YII框架的目的无非是HOW(怎么用).没有多少人愿意去研究WHY.我耗时好几天去研究YII的框架.我虽然不需要完全理解YII是如何那么好的运行的.但是我至少要知道.它大概是怎么工作的.我该从何入手.做什么能够影响到YII的运行.
进入正题:
YII框架的好处我就不多说了,大家可以自己去百度上面google一下.至于YII怎么安装,能够自动的建立应用之类的云云,大家可以自行参考YII中文官方网站上面的博客指南和权威指南.我想使用YII做一套CMS.这是我的目的.于是我带着我的目的去研究了.
开始深入.
在YII框架建立好了应用之后,目录结构和下面的差不多 官方网站上有解释各个目录都是干啥地
testdrive/ index.php Web 应用入口脚本文件 index-test.php 功能测试使用的入口脚本文件 assets/ 包含公开的资源文件 css/ 包含 CSS 文件 images/ 包含图片文件 themes/ 包含应用主题 protected/ 包含受保护的应用文件 yiic yiic 命令行脚本 yiic.bat Windows 下的 yiic 命令行脚本 yiic.php yiic 命令行 PHP 脚本 commands/ 包含自定义的 'yiic' 命令 shell/ 包含自定义的 'yiic shell' 命令 components/ 包含可重用的用户组件 Controller.php 所有控制器类的基础类 Identity.php 用来认证的 'Identity' 类 config/ 包含配置文件 console.php 控制台应用配置 main.php Web 应用配置 test.php 功能测试使用的配置 controllers/ 包含控制器的类文件 SiteController.php 默认控制器的类文件 data/ 包含示例数据库 schema.mysql.sql 示例 MySQL 数据库 schema.sqlite.sql 示例 SQLite 数据库 testdrive.db 示例 SQLite 数据库文件 extensions/ 包含第三方扩展 messages/ 包含翻译过的消息 models/ 包含模型的类文件 LoginForm.php 'login' 动作的表单模型 ContactForm.php 'contact' 动作的表单模型 runtime/ 包含临时生成的文件 tests/ 包含测试脚本 views/ 包含控制器的视图和布局文件 layouts/ 包含布局视图文件 main.php 所有视图的默认布局 column1.php 使用单列页面使用的布局 column2.php 使用双列的页面使用的布局 site/ 包含 'site' 控制器的视图文件 pages/ 包含 "静态" 页面 about.php "about" 页面的视图 contact.php 'contact' 动作的视图 error.php 'error' 动作的视图(显示外部错误) index.php 'index' 动作的视图 login.php 'login' 动作的视图 system/ 包含系统视图文件
---------以上摘自官方YII权威指南页面---------------
既然骨架建立出来了,很多人估计到这步的时候跟我一样了.不明觉厉.而且现在的状态是,摸不着头脑.我滴个娘亲啊,这得从何下手啊.这个时候大多数人做的事情我想和我一样.肯定是现打开index.php看看里面到底写了点啥玩意儿.打开了index.php后看见如下代码了
<?php // change the following paths if necessary $yii=dirname(__FILE__).'/../../framework/yii.php'; $config=dirname(__FILE__).'/protected/config/main.php'; // remove the following line when in production mode // defined('YII_DEBUG') or define('YII_DEBUG',true); require_once($yii); Yii::createWebApplication($config)->run();
这几行我估计大家都看的懂,定义了YII框架所在的目录,引入了一个main.php的配置文件,然后打开了debug.最后直接调用了Yii::createWebApplication方法.看后面的调用方式,这个方法一定返回了某个类的具体实例.
看样子问题转移到了这个实例到底是啥滴实例?
并且传入的$config给实例后,实例干了些什么?
调用run方法又干了些什么?
当我想继续研究的时候我发现我进入了追查阶段.但是我想的只是怎么用这个框架.好吧 回到主题.我要做CMS.
做cms的话前端展示和后台管理一定要分开啊.而且据说YII支持模块.于是我参考了几个国内的YII做的cms后发现大多数人都吧admin写成了模块.我也来写一个模块.据说yii有个自动化的工具叫做Gii.于是我配置了Gii.并且生成了我想要的模块admin模块.
这个时候Gii会提示我们在main.php,也就是配置文件的modules里面添加上模块的信息.打开了main.php文件之后有让我大吃一惊.what?为虾米是个数组.既然你是数组,我就先把你放在这里.一会研究你.先不管.把我的模块添加进来;
'modules'=>array( // uncomment the following to enable the Gii tool//这句就是说取消注释启用Gii 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'??????????', // If removed, Gii defaults to localhost only. Edit carefully to taste. 'ipFilters'=>array('127.0.0.1','::1'), ),//这个是参照官方的文档添加的Gii模块,其实本来就已经写好了,只需要取消注释就好了 'admin',//这个才是我添加的admin模块. ),
先看看效果,访问http://yourwebroot/index.php?r=admin就能够看到你新建模块的东西了.此时显示了你的访问路径和两句帮助信息,说这个页面是怎么来滴.在那个控制器下面.而且告诉你要修改什么文件.此时我发现了一个很不爽的地方就是为啥你不给我定义控制器名称的地方,我不想让我的控制器名称叫default.好吗?于是修改了控制器的名称,和控制器对应的view文件夹名称还有控制器的文件名称.但是,此时发现再访问这个控制器滴时候竟然报错了.说找不到控制器.好吧.我用脚后跟这么一想,一定是有个地方能设置默认的控制器.待我找找.打开模块目录.模块自然是继承自模块基类.当打开模块目录后看到的第一个PHP文件里面的内容如下:
<?php class AdminModule extends CWebModule { public function init() { // this method is called when the module is being created // you may place code here to customize the module or the application //这两句的意思是这个方法将会在模块被建立的时候调用.你可以在这里编写代码用于验证等工作. //注意到这个模块继承自CWebModule,也就是说CWebModule里面的属性和方法在这里会被首先调用,那好,我在这里自然也可以设置从模块的基础类继承出来的属性. //注意此时还没有涉及到控制器. // import the module-level models and components $this->defaultController = '控制器名称,不带Controller后缀的,小写.'; $this->setImport(array( 'admin.models.*', 'admin.components.*', )); } public function beforeControllerAction($controller, $action) { if(parent::beforeControllerAction($controller, $action)) { // this method is called before any module controller action is performed // you may place customized code here //这个地方会在控制器的方法被调用之前执行.也就是说这个地方很适合用来做验证. return true; } else return false; } }
上面注释里面说了 ,我要去参考下CWebModules类里面定义的属性和方法.(官方有手册)果断找到了里面定义的defaultController 属性.于是在init里面添加了一行$this->defaultController = '控制器名称,不带Controller后缀的,小写.';搞定了控制器.再次访问我们的网址http://yourwebroot/index.php?r=admin,OK了,看样子我们的设置起作用了.其实在这里面还有很多我们可以设置的属性.yii的手册写的很不错.虽然一开始我并不知道应该怎么去读他.
修改LAYOUT
此时我发现了一个更让我不能够接受的东西.为虾米我的这个模块会调用和首页一样的样式风格,也就是一样的视图模板去渲染啊.这后台的模板一定是不能和前台一样的.于是研究YII的视图.也就是说此时我要实现的目的是让admin模块使用和前台不一样的视图.在YII的权威指南上我们可以找到视图的说明.上面说视图分为布局,视图,和小物件.看完之后发现小物件暂时用不到.那我就来看看布局吧.由于模块的目录结构和网站整体的目录结构很想.看一下目录结构.发现控制器有自己单独的视图文件夹.layout文件夹里面放置的是用来渲染的公共部分.在YII里面,我们可以理解为layout就是一个公共的模板框架.而真正的内容在layout所输出的content里面.也就是说在开发的过程中.我们先写好整体的公共部分框架,放在layouts文件夹里面,然后再在各个控制器单独对应的视图文件夹里面去写不同的地方就行了.这里面可以用来渲染数据.好吧,我又用我的脚后跟想了想.一定有个地方能够控制layout目录.在什么地方呢.程序的运行逻辑是:
入口文件(载入配置)->模块文件(配置模块的一些信息)->调用控制器->调用控制器里面的方法/动作->渲染视图文件.
也就是说是在控制器里面的方法下渲染的视图文件.参考SiteController里面的action可以知道render()方法能够没有参数就执行.也就是说这个layout的默认属性应该是被配置在了控制器这一层.
打开控制器文件,如下:
<?php class AdminController extends Controller { public function init(){ $this->layout="application.modules.admin.views.layouts.admin"; } public function actionIndex() { $this->render('index'); } public function actionLogin() { } }
这里面的AdminController继承自Controller.通过目录结构可以看到这个文件在components目录下面,而且这个Controller继承自Ccontroller.那么我想Ccontroller里面一定有一个属性是默认的layout.果然找到了.于是我在里面设置了layout属性.如果想让所有admin模块下面的layout属性都指定到这个目录.我们可以参考controller来重写一个继承自Ccontroller的类.在里面设置这个属性.只要在其子类里面不去覆盖这个属性,那么我们设置的这个属性就会被继承.这个同上.在手册上我们可以看见有很多属性可以去设置.也有很多方法供我们使用.
到现在,我一共做了几件事情,首先我修改了模块里面的默认控制器,同比我也可以在作为模块中控制器的父类里面设置每一个继承控制器类的默认动作.我又设置了默认的layout方法.使用的别名路径.这个是yii提供的一个功能.可以在权威指南上找到.接下来我们要做的事情就是针对admin模块并参考默认的view文件夹来写后台的基础视图,实现后台用户的验证.并且能够渲染后台的主页面,实现后台登陆用户的管理.等等等等.这些工作后面在做.还记得上面我提的3个问题么.
我们在index.php的入口文件里面看见yii建立了一个某类的实例并且调用了这个类的run方法.而且还传入到类里面一个配置文件.这个到底是哪个类的方法呢.追查代码.我们会发现这个类是CWebApplication的实例.传入的config数组一定是用来配置并生成这个类的实例了.也就是说这个配置文件是被CwebApplication这个类来解析的.具体的解析在这个类的基类CModule中的configure()方法上面.可以看手册自己去追.这样说也就是意味着所有写在config数组里面的配置对会逐一的被配置到CwebApplication这个类上面.所以我们可以参考这个类的手册来写数组.打个比方来说.在这个类里面有一个参数叫做layout;我们在配置数组里面写如下的参数 'layout' => '这里写一个路径别名'; 那么在没有他处指定layout的情况下这个默认的layout就会被使用.
而这个配置文件里面又包含了数组.同样会被解析.例如modules里面的数组 我们同样可以配置module的各个属性在配置数组里面,例如上面的admin模块中,我们可以这样配置
'modules'=>array( // uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'zhangjian.123!', // If removed, Gii defaults to localhost only. Edit carefully to taste. 'ipFilters'=>array('127.0.0.1','::1'), ), 'admin'=>array( 'defaultController'=>'admin', 'layout'=>'设置layout的路径',
//在这里可以设置所有admin模块所继承的基类的属性.可以看手册Ccontroller里面的各个属性.
//在这里设置的属性会在模块被调用的时候直接被设置成值.
), ),
如果我们的模块配置文件比较大.还可以把这个模块的配置分离出去.然后在主配置文件里面去引用这个模块的配置文件.这样也方便大家一起开发.当然我们也可以在继承的子类里面设置自己的属性.也可以通过这个来设置.
YII对网站进行了抽象,每一个站点实际上都是CwebApplication的一个实例.这个实例里包含了属性,方法,而有的属性是控制器.有的属性是模块.有的属性是组件.就像我们把一个网站比作一辆小汽车.那么yii就是一个汽车制造工厂.每个汽车的组成不同.有的有gps定位.有的是手自一体的.网站也就不一样.有的使用了cache.有的使用了数据库.而我们建设网站就像是组装汽车一样.可以从YII提供的组件里选择自己得心应手的组件来应用.或者稍加修改.如果没有我们想用的组件.我们也可以自己开发一个组件.用在网站上.就像汽车出厂的时候没有行车记录仪一样.我们可以给我们建造的"小汽车"安装一个行车记录仪.
对于YII的初体验就写到这里.后面我还想继续写..如果觉得本文对你有所帮助,还请帮忙推荐一下.毕竟是个人观点,如果有什么地方写的不好.还希望各位大神指正.