Yii使用笔记 2

yii中的 getId等函数, id更多的是一个 string, 而不是数字.
CCaptchaAction > CAction > CComponent. 实现是 IAction.


yii中的验证码的使用

  1. 首先在当前 控制器中, 创建一个 actions的方法/函数, 注意是actions, 不是从前的方法actionIndex之类的. actions是用来定义 captchaFactory的id的, 注意这里, actions就是控制器的方法, 类似于 actionIndex.只不过它是很多方法的集合. 其中每个方法都是返回数组的一个元素 (关联数组的 下标). 所以 , 要访问生成的验证码,直接就用/admin/login/captcha路由就好了!
比较重要的一点是:如何访问到captcha?
因为实际上是没有actionCaptcha这个方法的, 但是有actions方法,这个从字面理解 也知道, 它也是一个方法的集合, 要访问生成的验证码
路由r是: r=admin/login/captcha.

  1. actions 是 Controller的一个方法. actions返回的是一个数组, 是用来描述什么类, 以及这个类方法的属性, 其中的'captcha' => array('class' => 'CCaptchaAction')...
    可以用 "路径别名", 来表示类名: framework 用system来表示, captcha的别名是: (这个是包package名, 或路径名)system.web.widgets.captcha.CCaptchaAction.

  2. 注意CCaptcha 和 CCaptchaAction的区别, 前者是继承自 CWidget, 用来在视图中, 生成验证码这个行为的, (要产生验证码就是在这个类中的方法...), 后者是对验证码本身/内部的特性进行操作的, 两者都包含run, render...等方法.
    比如在视图中生成显示验证码, 使用的就是 CCaptcha类: 在视图中写上: <?php $this->widget('CCaptcha')>

  3. 如果是要点击刷新的话, 使用

<?php
$this->widget('CCaptcha',     // 调用的是 控制器的widget方法, 这个就是产生 captcha这个 小物件... 
    array('showRefreshButton' => false,        // 这个是定义 验证码本身这个图形的性质的.
     'clickableImage' => true,      
            'imageOptions' => array(
                    'alt' => '点击刷新',
                    'title' => '点击刷新',
                    'style' => 'cursorpointer'
                    )
            ));

?>


vim中 ctrl+w +HJKL, 是指当前窗口, 向 ? 方向移动, 并完全占据那个方向的全部尺寸, 如K, 则表示, 完全占据上部的尺寸, 则在水平方向上最大.

### 常识: 在jquery的方法中, 凡是出现多个 并列的选项内容, 都应该将它们放入到 大括号中 {...}, 这样你就能够, 一看到写法的错误, 马上就能够知道错误.

日历控件, 通常用jquey的 datepicker控件, 如果不要显示的结构 text input框, 只要把那个input -text 表单域隐藏了就好了. jquery的datepicker控件, 除了需要jquery.js本身之外, 还需要 jqueryui.core.js和datepicker.js两个js文件, 然后, 还需要 css文件.

任何语言, 对于 不加引号的 "字符序列"的处理和认定, 如果 : 首先是 parsed as "keywords"?, 然后是 parsed as "CONSTANT" 常量, 如果这些都不是, 就会 报错!


验证码的使用方法:

  1. 要创建表单, 可以直接在视图 文件中, 如 modules/admin/views/login/index.php文件中, 直接使用 小物件的方法:
    <?php  $form = $this->beginWidget('CActiveForm')  ?>  // 这里就创建了一个表单 对象, 在视图文件中, 首先创建了一个表单对象!
            //  textField方法需要一个模型对象, 这个模型对象 要在  actionIndex方法中去new LoginForm(),注意不是调用控制器的某个方法来产生 LoginForm的对象. 
            //  然后在actionIndex 方法中通过 render/renderPartial 的数组参数传递到视图中来.
             
            <?php echo $form -> textField($loginModel, 'username', array(表单域 的属性集...) ); 

    
    <?php $this -> endWidget() ?>

但是要注意, 上面的 $loginModel 可以直接在这个视图文件中生成, 而不必在actionIndex中生成, 再传递到view视图中来!

<h1>this is a Form created by using Yii widget LoginForm - Model</h1>
//<?php $loginModel = new LoginForm(); ?>
<p>username: <?php echo $form->textField($loginModel, 'username', array('id'=>'username'));           ?>  <br> </p>

  1. 创建了表单后, 包括 这些text域, password域, 然后就可以插入 captcha验证码了.

stack trace
堆栈追踪
堆栈的生长方向有 从上到下, 和 从下到上, 通常是从下到上. 显示和读取堆栈追踪, 应该是从上到下, 从0 开始, 最上面的0 应该是最早被调用的函数, 即栈顶的函数, 即被最里层被调用的函数. 即最后出错的地方.

vim在normal模式下跳转到某一行, 使用的命令是 ngg, 或nG , 注意是 行号n在前面, 不是G/gg在前面, 否则, 总是 G -> nn ,gg ->n, 总是跳转到开头或结尾. 这样后面的数字命令就无效了

=============================

提示CCaptcha.0 没有设置? 在CCaptcha这个类中, properties属性数组中, 都是关联数组, 如果数组的下标没有"名称", 则被

视为0, 而CCaptcha中, 没有为 "0" 的属性, 所以就 显示出了: CException: CCaptcha.0 is undefined 的错误了.
实际上经过仔细查看后 , 是在 $this -> widget('CCaptcha', array(''..., 'imageOptions' =>array(....))) 中, 少了一个
imageOptions, 原来的代码中没有写这个, 直接写成了array(...)

在imgageOptions中, style的手形是: 'style' =>'cursor: pointer' 注意是 pointer 不是point!
实际上可以在视图的source code中看到, style就是css的样式.

在yii框架中 , 就没有使用 form表单了, 直接使用的是 widget, 那么就要注意, 所有的表单元素都要放在这个begin和end之间了,
否则, 如果submit的button放在endWidget()后, 就 提交 无效了. 这时候, 你在$_POST中就看不到内容了.

还要注意, $this -> widget(...) 生成的表单中, 使用的默认的提交方法就是 POST, 你可以打印出$_POST,
然后可以看到提交的内容是 $_POST['LoginForm'], 通常在接受页面, index.php, 判断接受情况的 "固定"代码是:

在 funtion actionIndex() 中, 
$loginForm = new LoginForm();

if(isset($_POST['LoginForm'])){   // 如果这个为true, 就表示 前端页面的表单数据确实是提交到处理页面了
    $loginForm -> attributes = $_POST['LoginForm'];
    if($loginForm -> validate()){
        .....
        }
    
    }

但是, 在使用yii的CActiveForm时, 点击验证码图形, 并没有换图? 是因为我们使用的渲染模式 是 renderPartial, 而renderPartial是不会载入jquery,js等框架和脚本的!

但是, 如果我们确实要使用renderPartial(因为, 有时候, 我们确实只需要我们自己的content, 而不需要layouts时), 可以修改核心类 CActiveForm

修改框架中的CCaptchaAction.php中的方法:

public function run(){... else $this -> renderImage($this->getVerifyCode(/*原来这里为空的, 修改时,改成true*/))}

run方法调用了 getVerifyCode()方法, 
然后, getVerifyCode方法中的参数$regenerate默认为false, 中根据条件, 调用了 generateVerifyCode(...)
但是只有在 getVerifyCode($regenerate 为true)的时候, 才会重新生成验证码..



generateVerifyCode() 方法中, 首先判断最小和最长验证码的个数, 设置了 最小为3, 最大为20, 然后用 mt_rand(产生一个最小值和最大值之间的一个正整数!)


验证码的错误显示,提示?

  1. 需要在form表单的下方增加 多个 错误显示区域:
    <ul> <li> <?php $form -> error($loginModel, 'username')?></li> </ul>
  2. 在Models/LoginForm.php模型的rules方法中书写我们字定义的验证规则:
    验证规则的格式是 array('表单域的名称, 如captcha', '验证规则, 可以是内置的, 如captcha', 'message' =>'验证错误时的提示信息, 如验证码错误...')
  3. 触发验证: $loginForm->validate(){....}
  4. 在视图页面, 写表单验证的错误提示信息时, 使用的是 "当前创建的表单" 这个对象, 而不是模型对象: <?php echo $form->error($loginFormModel, 'captcha'); ?>
    要注意, 这里的 echo form->error产生的是 一个 div 的提示信息块, 它的类是.而 .errorMessage. 所以要"美化"错误提示信息, 可以给.errorMessage设置css样式.

在Yii中, 后台专门是放在 一个 模块 modules/admin/中的! 在后台页面中, 要用render的布局, 来启用 jquery等js验证. 但是, 这时, 后台会默认 套用 前台的layout, 所以为了使用后台的布局, 要专门给后台, (仿照前台的目录结构), 设置一个 components ,layouts等.

1.在modules/admin/ 中创建components目录, 现在的版本都预先创建好了 components, views/layouts等文件夹了.


修改后他modules/admin/Controller.php中的后台使用布局:
public $layout='/layouts/admin' 这里不能用双斜线//, 而要用单斜线/, 双斜线表示的是前台的默认布局

修改了这里的布局使用后 , 那么还要相应的在modules/admin/views/layouts/中创建实体的 admin.php
Components/Controller.php中的上面的只是引用, 只是说明.

关于layouts和render的关系?

renderPartial是直接显示当前方法对应的视图; 而render只是说明当前方法的显示, 要 由layouts 来决定, 但是到底
显示还是不显示视图对应的内容, 还是由布局layouts中的 是否有这条语句: echo $content; 来决定 如果有就显示,否则就不显示; 注意是content, 而不是contents.

在php中, 变量的名称是不包含 $符号的, 只是在书写的时候, 才加上


创建数据库, 表, 插入记录的 "常规/记住/固定"fangfa:

  1. 到底是使用utf8还是 UTF-8? 没有统一的固定的标准, 默认的("标准")是: 大写的中间加横线UTF-8, 但是很多时候,没有严格区分的, 有小写的, 有不加横线的, 所以, 为了简洁(减省)就写成 utf8了.
  2. int(n)中的n只是显示问题, 跟实际存储无关, 所以为了避免这个"不是问题的问题", 就 采用默认的 显示 位数, 不用写显示数字. id不要都写成id, 还是加一个 "引导字符"来表示, 如uid, not null default '', 一般密码用md5来加密, 所以他的长度应该是固定的 32位: password char(32).
  3. 在protected/config/main.php中的配置文件中, db的主机地址要写作127.0.0.1, 只有在windows中, 才可以写作 localhost.
  4. 插入记录时, 为什么要写出字段名, 是因为, 后面在赋值的时候, 可以省略 id/uid/aid这种自增字段 的赋值, 而不会出错..
  5. 今后创建 数据表 的时候, 要习惯性的, 加上 表前缀
  6. 表前缀的用法是: (表前缀只是在创建和声明的时候, 用到, 其他在model模型中, 都不需要表前缀): 首先在配置文件main.php中, 的db数组元素中定义该 'tabelePrefix' => 'my_', , 然后在创建表的时候, create table my_user()... 最后在使用模型的时候, 就不用管这个 表前缀了.


固定一个版本, 是Yii的1.1.17版本.因为这个跟自己的使用习惯和学习成本有关.

以前版本的配置, 是把数据库的配置全部都放在main.php中的, 1.1.17版本, 是把数据库的配置独立出来放在了文件database.php文件中了.
这样protected/coinfig中就有四个配置文件了(console.php for yiic的, test.php为测试的, 我们主要使用的是main.php和database.php)

配置的方式是: 'connectionString' => 'mysql:host=127.0.0.1; dbname='foodemo'',...

什么叫 emulatePrepare? 参考:http://www.cnblogs.com/abei2017/p/6689854.html

是指数据库的 模拟预处理: 'emulate : 模拟, prepare: 指数据库的预处理机制(把sql脚本语句当作一个参数传递到数据库服务器), 是为了预防sql脚本注入的安全机制考虑的.
是由: PDO::ATTR_EMULATE_PREPARE来实现的?


当你设置了ATTR_EMULATE_PREPARES = false时,的确我们会采用数据库的预处理,但是PHP知道安全才是第一位的,因此即便你设置了false,当数据库自己的预处理突然抽风不好用了的时候,PDO并没有放弃,而是立刻启动自身的模拟预处理,保障数据的安全性。

'emulatePrepare'=>false

对了,就是false,false,false。

即便你设置了false,当数据库自己的预处理突然抽风不好用了的时候,PDO并没有放弃,而是立刻启动自身的模拟预处理,保障数据的安全性。 即推荐的是使用数据库自己的预处理, 这样性能上比较好一些. 但这里使用 true也可以


数据库连接的设置变量, 在system.web.db.CDbConnectiong.php中定义的

测试连接是否成功, 使用 var_dump(Yii::app()->db), db是程序的一个数据库组件 "数组".

后台的模型也是放在 项目/Models/中的, 一般, 一个数据表创建一个模型. 模型的名称应该和文件名称和数据表的名称相一致.


不管是在tp还是yii等框架中, 都是通过 "模型" 来操作 数据库的, 模型对应着数据库, Models/user.php类文件对应着 表, 通过类来操作 数据表的增删改查. 模型类 class user extends CActiveRecord通常继承自 CActiveRecord, 在CActiveRecord 这个基类中, 就提供了 crud的操作函数.

临时测试, 打印中间结果, 查看调试, 使用 var_dump($debug_info); die. 使用 die语句就好了.

yii中的类, 如果前面有C- 表示是基类, 如 UserIdentity extends CUserIdentity...

posted @ 2017-04-11 09:04  noitanym  阅读(285)  评论(0编辑  收藏  举报