zoukankan      html  css  js  c++  java
  • yii2开发后记

    前些天准备写一个自己的博客CMS,考虑PHP框架的时候想到了据说非常强大的yii,接触yii时发现有2.0版本,果断尝最鲜的。这么一尝试感觉入了坑了,yii2.0是2014年12月发布的,估计国内用的人比较少,资料比较少,遇到问题百度yii2.0查出来好多1.0版本的答案,只好去google看英文站。一个小问题没人提醒,又是STACK OVERFLOW又是自己翻源码,弄了一天多。。。可谓是吃尽了苦头。

    不过网站总算是做出来了,地址:http://www.alwayscoding.cn,以后博客在此站同步更新,而且,我也可以在上面肆无忌惮的放上自己喜欢的文章了~~另外源码也放在了github上,地址:https://github.com/zhenbianshu/blog-cms,有想使用本CMS的我可以提供支持~最后自己也总结出来了下列的使用心得,准备入手yii2.0的可以看一下,留个爪。


    基础总结

    1.修改默认控制器/方法

    yii默认是site控制器,可以在web.php中设置$config中的'defaultRoute'='xxxx';使用自定义默认的控制器。也可以改写Yii::$app->defaultRoute属性。

    yii的默认方法是index,可以在vender/yiisoft/yii2/base/Controller.php 中进行初始设置,也可以在控制器中改写defaltAction='action'。

    2.添加独立模块

    yii可以在modules文件夹中添加自定义模块,添加完成后在web.php中的$config中的'modules'=[id=..class=...]设置模块的开关。

    模块一般用于一些独立的功能,像我站里的admin模块整体负责后台逻辑。

    3.模型操作表设置

    yii的模型有Model和ActiveRecord两种,Model类用来处理基本的业务逻辑,没有数据库相关方法,如果要操作同名数据表,请继承ActiveRecord类。

    我们用一个在models文件夹中的Operation.class里Operation类来继承yiidbActiveRecord来操作Operation表。

    如果要操作其他表,也可以重写public $tableName属性来设置。或改写其tableName方法(注意是静态方法) : public static function tableName(){return 'tableName'}

    4.视图层构成

    yii的视图层使用.php文件,而且其内部的实现也多采用yii内置小部件的形式,如<?= LinkPager::widget(['pagination'=>$pagination]) ?>来表示其分页类。

    而且,像input这样的小部件,用ActiveForm类来展现,yii会对每个自动加入ajax验证,其一般的小部件都放在yiiwidget里,我们还可以在此文件夹里构建自定义的小部件类。

    5.布局模式

    yii会默认开启布局模式,其布局模板为view中的layout中的main.php,我们可以在veder/yiisoft/yii2/web/controller.php基础类中public $layout属性修改模板文件的配置。

    我们还可以设置关闭或指定特定的layout:

    • 控制器内控制 public $layout=false/'layout'
    • 控制器成员方法内控制 $this->layout=false/'layout'
    • 视图中选择布局 $this->context->layout=false/'layout'

    6.模型的基本设置

    yii的模型是MVC的处理器,它执行对MVC逻辑的处理。 model的属性定义是其核心,由于默认定义魔术方法get/set,所以可以直接在model外调用$modle->attr='value',对模型的属性进行获取/赋值。

    场景设置

    yii中有对场景的定义,定义场景可以使得yii在不同的情况下返回不同的数据信息。用model的scenarios()方法来设置返回数据。

    我们在使用model时传入场景名 $model=new Model(['scenario'=>'login']);来确定场景。

    规则设置

    yii中对验证规则的定义,使用rules()方法可以一条定义多条规则,也可以根据不同的场景进行定义。外部验证时用$model->validate()方法来执行验证。

    在安全模式下,要进行安全验证,即每一个属性都要在rules里验证,如果没有特定规则,也要添加'safe'验证。否则验证失败,存入数据库也会失败。

    标签设置

    在处理表单时,多用$model->attributes属性来表示全部的属性。其中attributeLabels方法return一个数组用来表示视图层中ActiveForm产生的各个表单项的label标签

    7.引用JS/CSS文件

    yii中的view也使用面向对象方式 ,所以引入CSS和JS文件要用特殊的方法。

    • 使用$this->registerJsFile('js.js')来引入js文件;
    • 使用$this->registerJsFile('js.js')来引入js文件;

    8.分页类的使用

    //在模型中计算出总数量
    $count=$this->find()->where()->count();
    //用总条数和设定的每页个数实例化一个yiidataPagination类
    $page=new Pagination([totalCount' => $count,'defaultPageSize'   => 2,]);
    //使用分页类的属性搜索想要的数据,并返回数据
    $res=$this->find()->where()->offset($page->offset)->limit($page->limit)->all();
    return [$res,$page];
    //使用控制器渲染页面
    $data=$model->getData();
    return $this->render('index',$data);
    //在视图页面中使用数据。
    foreach($res as key)...
    yiiwidgetsLinkPager::widget([pagination=$page,prevPageLabel='上一页'])。
    

    9.创建url

    use yiihelpersUrl;
    Url::to(['xxx/xxx']);
    //或
    Yii::$app->urlManager->createUrl('xxx.xxx')
    

    10查询构建器

    yii里的QUERY查询语句构造器非常简单好用,它可以用在模型和控制器中,虽然可能会造成模型与表不对应,但其构成接近sql语句,使用它可以轻易写出复杂的sql语句而不必严格遵从yii的内置规则。

    方法为:

    $res=(new yiidbQuery())->select()->from()->leftJoin()->where->()->all();
    

    其中where语句较为复杂:

    where('in','id',$array)或where('id'=>$array)
    

    具体可以查看http://www.yiichina.com/doc/guide/2.0/db-query-builder中对where方法的解析。

    11.自定义函数

    yii里面自定义函数可以在vendor/yiisoft/yii2/helpers/文件夹里,新建一个XXX.php文件,然后定义一个自定义类,再定义静态方法YYY()。

    使用时应用基命名空间,use yiihelpersXXX,然后用类来引用基静态方法XXX::YYY()

    12.关联模型

    yii里面的关联模型,用来在取得当前表内的一条记录时,会取出对应表的记录。如A表内每取出一条信息,也取出B表中跟A表对应有信息,在ModelA里定义一个getBtable方法

    function getBtable()
    {
        return $this->hasOne/hasMany(Btable::className,['bid'=>'aid']);
    }
    

    查询时可以使用joinWith('Btable')->find();会在查找时查找其关联对象;也可以使用$this->find()等方法结果对象

    使用$res->btable来直接引用对象。

    使用$res[n]->btable->attr来引用B表的对应属性。

    13.使用ActiveForm创建表单

    yii2中使用小部件创建view视图的步骤: 设置一个Model设置其属性

    public $username;
    public $password;
    

    设置其rule或场景等

    public function rules(){
        return [
                [['username', 'password','conpass'], 'required'],
                ['conpass', 'password',
            ];
    }
    

    设置其label

    public function attributeLabels(){
            return [
                'username' => '管理员',
                'password' => '密码',
            ];
        }
    

    然后在controller中将model的实例渲染进去:

    $this->render('index',['model'=>(new Model/ActiveRecord)])
    

    最后在页面中使用ActiveForm

    use yiiwidgetsActiveForm;
    <?php $form = ActiveForm::begin([
        'action' => ['log/login'],
        'method'=>'post'
        ]); ?>
        <?= $form->field($model, 'username') ?>
        <?= $form->field($model, 'password') ?>
        <div class="form-group">
            <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
        </div>
    <?php ActiveForm::end(); ?>
    

    14.使用验证码

    在controller中设置验证码的独立方法

    public function actions() {
            return [
                'captcha' =>  [
                    'class' => 'yiicaptchaCaptchaAction',
                    'height' => 50,
                    'width' => 80,
                    'minLength' => 4,
                    'maxLength' => 4
                ],
            ];
        }
    

    在model里设置rule和label,label同上

    public function rules(){
        return [['verifyCode', 'captcha','captchaAction'=>'admin/log/captcha'],];
    }
    

    (captchaAction要设置为controller中的位置,如果自定义module要设置module) 在view中使用

    use yiicaptchaCaptcha;
    <?= $form->field($model, 'verifyCode')->widget(Captcha::className(),
        ['captchaAction'=>'log/captcha',
            'imageOptions'=>
            ['alt'=>'点击换图', 'style'=>'cursor:pointer']
        ]) ?>
    

    15.视图中块的使用

    块内容在$this->beginBlock(['id'=>xxx])和$this->endBlock()之间定义,在layout中使用$view->block[id]来引用。可以在完成向模板中导入视图数据。

    也可以定义$this->var=xxx;在layout中用$this->var来引用。

    16.更新和删除

    更新
    //查找到一条结果
    $res=$this->find()->where()->one();
    //对结果修改
    $res->attr='xxx';
    //执行更新操作
    $res->update();
    
    删除
    //删除一条数据
    $this->findOne($id)->delete();
    //删除所有符合条件的数据
    $this->deleteAll([where]);
    

    注意和窍门

    1.URL模块间跳转

    在模块中用Url::to()方法创建URL时,会自动在前面添加模块名,导致无法跳转到其他模块,我们可以在字符串前添加'//'符来返回根模块,例如Url::to(['//index/index'])表示跳转到初始地址。

    2.初始化变量

    想在控制器中每一个操作前,初始化一个变量的话不要重写__construct构造函数,因为它需要传入各种变量。最好重写beforeAction()函数,它会在执行每一个action时都执行一下。

    并且注意:方法的最后一定要添加return true语句。

    3.在JS中使用YII的变量

    若想在JS中使用YII的URL变量等,可以使用html中的script标签,将变量在第一次渲染视图时预先解析出来,将下面代码放在需要使用变量的地方之前。

    <script type="text/javascript">
        var key="<?=Url::to(['xxx/xxx']) ?>"
    </script>
    

    然后在JS文件中正常使用。

    4.全局常量的定义

    我们可以在config文件夹中的params.php中定义全局常量。

    然后在脚本中用Yii::$app->params['key']来引用。

    5.yii模型属性转数组

    YII用toArray()方法可以将模型的属性转换为数组进行输出,可独立使用,也可以在查询时用连续操作方式使用。

    6.在使用controller渲染view页面时,一定要在render前加echo或return 写作echo/return $this->render('view',$data);

    7.yii中的属性,谨记!在ActiveForm中如果数据表中有了此字段,就不要再用public声明一个属性了,会导致attribute无法赋值。。。。(血泪)。

  • 相关阅读:
    马氏距离的深入理解
    Mahalanobis Distance(马氏距离)
    Weka EM 协方差
    数据挖掘、概率分析与决策支持
    二、 Android中gravity与layout_gravity的区别
    一、 Android完全退出应用程序
    python configparse
    时间戳与时间互转
    python argparse
    时间插件
  • 原文地址:https://www.cnblogs.com/zhenbianshu/p/5126416.html
Copyright © 2011-2022 走看看