zoukankan      html  css  js  c++  java
  • yii2框架的详细介绍

    yii2框架的安装我们在之前文章中已经提到下面我们开始了解YII2框架

    强大的YII2框架网上指南:http://www.yii-china.com/doc/detail/1.html?postid=278或者

    http://www.yiichina.com/doc/guide/2.0

    Yii2的应用结构:
    这里写图片描述

    目录篇:

            
     advance版本的特点是:根目录下预先分配了三个模块,分别是前台、后台、控制台模块。
    1.backend
    它主要用于管理后台,网站管理员来管理整个系统。

    assets 目录用于存放前端资源包PHP类。 这里不需要了解什么是前端资源包,只要大致知道是用于管理CSS、js等前端资源就可以了。
    config 用于存放本应用的配置文件,包含主配置文件 main.php 和全局参数配置文件 params.php 。
    models views controllers 3个目录分别用于存放数据模型类、视图文件、控制器类。这个是我们编码的核心,也是我们工作最多的目录。
    widgets 目录用于存放一些常用的小挂件的类文件。
    tests 目录用于存放测试类。
    web 目录从名字可以看出,这是一个对于Web服务器可以访问的目录。 除了这一目录,其他所有的目录不应对Web用户暴露出来。这是安全的需要。
    runtime 这个目录是要求权限为 chmod 777 ,即允许Web服务器具有完全的权限, 因为可能会涉及到写入临时文件等。 但是一个目录并未对Web用户可见。也就是说,权限给了,但是并不是Web用户可以访问到的。

        
    2.frontend

    我们的目标最终用户提供的主要接口的前端应用。其实,前台和后台是一样的,只是我们逻辑上的一个划分.。
     好了,现在问题来了。对于 frontend backend console 等独立的应用而言, 他们的内容放在各自的目录下面,他们的运作必然用到Yii框架等 vendor 中的程序。 他们是如何关联起来的?这个秘密,或者说整个Yii应用的目录结构的秘密, 就包含在一个传说中的称为入口文件的地方。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?phpdefined('YII_DEBUG') or define('YII_DEBUG', true);
    defined('YII_ENV') or define('YII_ENV', 'dev');
    require(__DIR__ . '/../../vendor/autoload.php');
    require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
    require(__DIR__ . '/../../common/config/bootstrap.php');
    require(__DIR__ . '/../config/bootstrap.php');
    $config = yiihelpersArrayHelper::merge(
    require(__DIR__ . '/../../common/config/main.php'),
    require(__DIR__ . '/../../common/config/main-local.php'),
    require(__DIR__ . '/../config/main.php'),
    require(__DIR__ . '/../config/main-local.php'));
    $application = new yiiwebApplication($config);$application->run();


    3.console
    控制台应用程序包含系统所需要的控制台命令的。
     



    下面是全局公共文件夹
    4.common

    其中:

    • config 就是通用的配置,这些配置将作用于前后台和命令行。
    • mail 就是应用的前后台和命令行的与邮件相关的布局文件等。
    • models 就是前后台和命令行都可能用到的数据模型。 这也是 common 中最主要的部分。

     公共的目录(Common)中包含的文件用于其它应用程序之间共享。例如,每一个应用程序可能需要访问该数据库的使用 ActiveRecord。因此,我们可以将AR模型类放置在公共(common)的目录下。同样,如果在多个应用程序中使用了一些辅助(helper )或部件类(widget ),我们也应该把这些放置在公共目录(common)下,以避免重复的代码。
      正如我们将很快解释,应用程序也可以共享一部分的共用配置。因此,我们还可以存储config目录下共同的常见配置。
    当开发一个大型项目开发周期长,我们需要不断调整数据库结构。出于这个原因,我们还可以使用数据库迁移(DB migrations )功能来保持跟踪数据库的变化。我们将所有 DB migrations(数据库迁移)目录同样都放在公共(common)目录下面。

    5.environment
    每个Yii环境就是一组配置文件, 包含了入口脚本 index.php和各类配置文件。 其实他们都放在/environments 目录下面.

     从上面的目录结构图中,可以看到,环境目录下有3个东东:
    • 目录 dev
    • 目录 prod
    • 文件 index.php

    其中, dev 和 prod 结构相同,分别又包含了4个目录和1个文件:

    • frontend 目录,用于前台的应用,包含了存放配置文件的 config 目录和存放web入口脚本的web 目录
    • backend 目录,用于后台应用,内容与 frontend 相同
    • console 目录,用于命令行应用,仅包含了 config 目录,因为命令行应用不需要web入口脚本, 因此没有 web 目录。
    • common 目录,用于各web应用和命令行应用通用的环境配置,仅包含了 config 目录, 因为不同应用不可能共用相同的入口脚本。 注意这个 common 的层级低于环境的层级,也就是说,他的通用,仅是某一环境下通用,并非所有环境下通用。
    • yii 文件,是命令行应用的入口脚本文件。

    对于分散于各处的 web 和 config 目录而言,它们也是有共性的。

    • 凡是 web 目录,存放的都是web应用的入口脚本,一个 index.php 和一个测试版本的index-test.php
    • 凡是 config 目录,存放的,都是本地配置信息 main-local.php 和 params-local.php

    6.vendor
     
     vendor 。 这个目录从字面的意思看,就是各种第三方的程序。 这是Composer安装的其他程序的存放目录,包含Yii框架本身,也放在这个目录下面。 如果你向composer.json 目录增加了新的需要安装的程序,那么下次调用Composer的时候, 就会把新安装的目录也安装在这个 vendor 下面。

    下面也是一些不太常用的文件夹
    7.vagrant
     
    8.tests
     

    入口文件篇:

    1、入口文件路径:

    http://127.0.0.1/yii2/advanced/frontend/web/index.PHP

    每个应用都有一个入口脚本 web/index.PHP,这是整个应用中唯一可以访问的 PHP 脚本。一个应用处理请求的过程如下:

    1.用户向入口脚本 web/index.php 发起请求。
    2.入口脚本加载应用配置并创建一个应用实例去处理请求。
    3.应用通过请求组件解析请求的路由。
    4.应用创建一个控制器实例去处理请求。
    5.控制器创建一个操作实例并针对操作执行过滤器。
    6.如果任何一个过滤器返回失败,则操作退出。
    7.如果所有过滤器都通过,操作将被执行。
    8.操作会加载一个数据模型,或许是来自数据库
    9.操作会渲染一个视图,把数据模型提供给它。
    10.渲染结果返回给响应组件。
    11.响应组件发送渲染结果给用户浏览器

    可以看到中间有模型-视图-控制器 ,即常说的MVC。入口脚本并不会处理请求,而是把请求交给了应用主体,在处理请求时,会用到控制器,如果用到数据库中的东西,就会去访问模型,如果处理请求完成,要返回给用户信息,则会在视图中回馈要返回给用户的内容。

    2、为什么我们访问方法会出现url加密呢?


    我们找到文件:vendor/yiisoft/yii2/web/UrlManager.php

        return "$baseUrl/{$route}{$anchor}";
    } else {
        $url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
        if (!empty($params) && ($query = http_build_query($params)) !== '') {
            $url .= '&' . $query;
        }
    将urlencode去掉就可以了
    3、入口文件内容
     
    入口文件流程如下:
    


    MVC篇:


    一、控制器详解:

    1、修改默认控制器和方法

      修改全局控制器:打开vendor/yiisoft/yii2/web/Application.php

    eg:

    public $defaultRoute = 'student/show';
     修改前台或者后台控制器:
    eg :打开  frontend/config/main.php 中
    'params' => $params,
    'defaultRoute' => 'login/show',
    2、建立控制器示例:StudentController.php

    //命名空间

    namespace frontendcontrollers;


    use Yii; 

    use yiiwebController;   vendor/yiisoft/yii2/web/Controller.php   (该控制器继承的是yiiaseController)
    webController.php中干了些什么  
    1、默认开启了 授权防止csrf攻击
    2、响应Ajax请求的视图渲染
    3、将参数绑定到动作(就是看是不是属于框架自己定义的方法,如果没有定义就走run方法解析)
    4、检测方法(beforeAction)beforeAction() 方法会触发一个 beforeAction 事件,在事件中你可以追加事件处理操作;
    5、重定向路径 以及一些http Response(响应) 的设置
    
    use yiidbQuery; //使用query查询
    use yiidataPagination;//分页  
    use yiidataActiveDataProvider;//活动记录  
    use frontendmodelssDynasty;//自定义数据模型 


    class StudentController extends Controller
    {  
     $request = YII::$app->request;//获取请求组件
       $request->get('id');//获取get方法数据
       $request->post('id');//获取post方法数据
       $request->isGet;//判断是不是get请求
       $request->isPost;//判断是不是post请求
       $request->userIp;//获取用户IP地址
        $res = YII::$app->response;//获取响应组件
        $res->statusCode = '404';//设置状态码
        $this->redirect('http://baodu.com');//页面跳转
        $res->sendFile('./b.jpg');//文件下载
    
     $session = YII::$app->session;
        $session->isActive;//判断session是否开启
        $session->open();//开启session
        //设置session值
        $session->set('user','zhangsan');//第一个参数为键,第二个为值
        $session['user']='zhangsan';
        //获取session值
        $session->get('user');
        $session['user'];
        //删除session值
        $session-remove('user');
        unset($session['user']);
    
     $cookies = Yii::$app->response->cookies;//获取cookie对象
        $cookie_data = array('name'=>'user','value'=>'zhangsan')//新建cookie数据
        $cookies->add(new Cookie($cookie_data));
        $cookies->remove('id');//删除cookie
        $cookies->getValue('user');//获取cookie
    
    
         //显示视图
         return $this->render('add'); 默认.php
         return $this->render('upda',["data"=>$data]); 
     

       }
    }

    二、模型层详解

       简单模型建立:

      

    <?php
    
    namespace frontendmodels;
    class ListtModel extends yiidbActiveRecord
    {
        public static function tableName()
        {
        return 'listt';
        }
        public function one(){
           return $this->find()->asArray()->one();
        }
    }

    控制器引用
    
    <?php
    namespace frontendcontrollers;
    use Yii;
    use yiiwebcontroller;
    use frontendmodelsListtModel;
    
    class ListtController extends Controller{
        public  function  actionAdd(){
            $model=new ListtModel;
            $list=$model->one();
           $data=$model->find()->asArray()->where("id=1")->all();
            print_r($data);
        }
    }
    ?>


    三、视图层详解首先在frontend下建立与控制器名一致的文件(小写)eg:student 在文件下建立文件

    eg:index.php
    每一个controller对应一个view的文件夹,但是视图文件yii不要求是HTML,而是php,所以每个视图文件php里面都是视图片段:


      而views下面会有一个默认的layouts文件夹,里面存放的就是布局文件,什么意思呢?:
    在控制器中,会有一个layout字段,如果制定他为一个layout视图文件,比如common.php,那么视图就会以他为主视图,其他的view视图片段都会作为显示片段嵌入到layout文件common.php中.
    而如果不明确重载layout字段,那么默认layout的值是main,意味着layouts的main.php是视图模板。
    控制器:

    common.php:


    layouts 

    这样就达到了视图复用的作用。
        控制器中写入$layout
    //$layout="main"  系统默认文件
    //$layout=null  会找父类中默认定义的main
    public $layout="common";
    public  function  actionIndex(){
      return  $this->render('index');
    }
     将以下内容插入 common中
      <?=$content;?>  它就是index文件中的内容
    当然了,视图与模板之间还有数据传递以及继承覆盖的功能。





    YII2框架数据的运用

    1、数据库连接

    简介

    一个项目根据需要会要求连接多个数据库,那么在yii2中如何链接多数据库呢?其实很简单,在配置文件中稍加配置即可完成。

    配置

    打开数据库配置文件commonconfigmain-local.php,在原先的db配置项下面添加db2,配置第二个数据库的属性即可

    1. 'db' => [  
    2.     'class' => 'yiidbConnection',  
    3.     'dsn' => 'mysql:host=localhost;dbname=hyii2',   //数据库hyii2  
    4.     'username' => 'root',  
    5.     'password' => 'pwhyii2',  
    6.     'charset' => 'utf8',  
    7. ],  
    8. 'db2' => [  
    9.     'class' => 'yiidbConnection',  
    10.     'dsn' => 'mysql:host=localhost;dbname=hyii',     //数据库hyii  
    11.     'username' => 'root',  
    12.     'password' => 'pwhyii',  
    13.     'charset' => 'utf8',  
    14. ],  

    如上配置就可以完成yii2连接多个数据库的功能,但还是需要注意几个点

    应用

    1.我们在hyii数据库中新建一个测试表test

    blob.png

    2.通过gii生成模型,这里需要注意的就是数据库链接ID处要改成db2

    blob.png

    3.查看生成的模型,比正常的model多了红色标记的地方

    blob.png

    所以各位童鞋,如果使用多数据配置,在建db2的模型的时候,也要加上上图红色的代码。

    好了,以上步骤就完成了,yii2的多数据库配置,配置完成之后可以和原因一样使用model或者数据库操作

    2、数据操作:


    方式一:使用createCommand()函数

    加 

    获取自增id

    $id=Yii::$app->db->getLastInsertID();
    1. Yii::$app->db->createCommand()->insert('user', [    
    2.     'name' => 'test',    
    3.     'age' => 30,    
    4. ])->execute();  

    批量插入数据

    1. Yii::$app->db->createCommand()->batchInsert('user', ['name''age'], [    
    2.     ['test01', 30],    
    3.     ['test02', 20],    
    4.     ['test03', 25],    
    5. ])->execute();  
    删除

    1. Yii::$app->db->createCommand()->delete('user''age = 30')->execute();  

    修改

    1. Yii::$app->db->createCommand()->update('user', ['age' => 40], 'name = test')->execute();  
    查询

    1. //createCommand(执行原生的SQL语句)    
    2. $sql"SELECT u.account,i.* FROM sys_user as u left join user_info as i on u.id=i.user_id";    
    3. $rows=Yii::$app->db->createCommand($sql)->query();    
    4.   
    5. 查询返回多行:      
    6. $command = Yii::$app->db->createCommand('SELECT * FROM post');    
    7. $posts = $command->queryAll();  
    8.    
    9. 返回单行  
    10. $command = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=1');    
    11. $post = $command->queryOne();  
    12.     
    13. 查询多行单值:    
    14. $command = Yii::$app->db->createCommand('SELECT title FROM post');    
    15. $titles = $command->queryColumn();  
    16.     
    17. 查询标量值/计算值:    
    18. $command = Yii::$app->db->createCommand('SELECT COUNT(*) FROM post');    
    19. $postCount = $command->queryScalar();  

    方式二:模型处理数据(优秀程序媛必备)!!


    新增(因为save方法有点low)所以自己在模型层中定义:add和addAll方法

    注意:!!!当setAttributes($attributes,fase);时不用设置rules规则,否则则需要设置字段规则;

     //入库一维数组
        public function add($data)
        {
            $this->setAttributes($data);
            $this->isNewRecord = true;
            $this->save();
            return $this->id;
        }
         //入库二维数组
        public function addAll($data){
            $ids=array();
            foreach($data as $attributes)
            {
                $this->isNewRecord = true;
                $this->setAttributes($attributes);
                $this->save()&& array_push($ids,$this->id) && $this->id=0;
            }
            return $ids;
        }


        public function rules()
        {
            return [
                [['title','content'],'required'
           ]];
        }

        控制器:

        $ids=$model->addAll($data);
         var_dump($ids);

    删除

    使用model::delete()进行删除

    1. $user = User::find()->where(['name'=>'test'])->one();   
    2. $user->delete();  

    直接删除:删除年龄为30的所有用户

    1. $result = User::deleteAll(['age'=>'30']);  

    根据主键删除:删除主键值为1的用户

    1. $result = User::deleteByPk(1);  


     /**
         * @param $files  字段
         * @param $values  值
         * @return int  影响行数
         */
        public function del($field,$values){
    //        $res = $this->find()->where(['in', "$files", $values])->deleteAll();
            $res=$this->deleteAll(['in', "$field", "$values"]);
            return $res;
        }





    修改

    使用model::save()进行修改

    1. $user = User::find()->where(['name'=>'test'])->one(); //获取name等于test的模型  
    2. $user->age = 40; //修改age属性值  
    3. $user->save();   //保存  

    直接修改:修改用户test的年龄为40

    1. $result = User::model()->updateAll(['age'=>40],['name'=>'test']);  


    /**
     * @param $data   修改数据
     * @param $where  修改条件
     * @return int  影响行数
     */
    public function upda($data,$where){
        $result = $this->updateAll($data,$where);
       // return $this->id;
        return $result;
    }


    基础查询

    Customer::find()->one();    此方法返回一条数据;
    
    Customer::find()->all();    此方法返回所有数据;
    
    Customer::find()->count();    此方法返回记录的数量;
    
    Customer::find()->average();    此方法返回指定列的平均值;
    
    Customer::find()->min();    此方法返回指定列的最小值 ;
    
    Customer::find()->max();    此方法返回指定列的最大值 ;
    
    Customer::find()->scalar();    此方法返回值的第一行第一列的查询结果;
    
    Customer::find()->column();    此方法返回查询结果中的第一列的值;
    
    Customer::find()->exists();    此方法返回一个值指示是否包含查询结果的数据行;
    
    Customer::find()->batch(10);  每次取10条数据 
    
    Customer::find()->each(10);  每次取10条数据,迭代查询 
    
    //根据sql语句查询:查询name=test的客户
    Customer::model()->findAllBySql("select * from customer where name = test"); 
    
    //根据主键查询:查询主键值为1的数据
    Customer::model()->findByPk(1); 
    
    //根据条件查询(该方法是根据条件查询一个集合,可以是多个条件,把条件放到数组里面) 
    Customer::model()->findAllByAttributes(['username'=>'admin']); 
    
    //子查询
    $subQuery = (new Query())->select('COUNT(*)')->from('customer');
    // SELECT `id`, (SELECT COUNT(*) FROM `customer`) AS `count` FROM `customer`
    $query = (new Query())->select(['id', 'count' => $subQuery])->from('customer');
    
    //关联查询:查询客户表(customer)关联订单表(orders),条件是status=1,客户id为1,从查询结果的第5条开始,查询10条数据
    $data = (new Query())
        ->select('*')
        ->from('customer')
        ->join('LEFT JOIN','orders','customer.id = orders.customer_id')
        ->where(['status'=>'1','customer.id'=>'1'])
        ->offset(5)
        ->limit(10)
        ->all()


    关联查询

    1. /** 
    2.  *客户表Model:CustomerModel  
    3.  *订单表Model:OrdersModel 
    4.  *国家表Model:CountrysModel 
    5.  *首先要建立表与表之间的关系  
    6.  *在CustomerModel中添加与订单的关系 
    7.  */       
    8. Class CustomerModel extends yiidbActiveRecord  
    9. {  
    10.     ...  
    11.     //客户和订单是一对多的关系所以用hasMany  
    12.     //此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间  
    13.     //id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段  
    14.     public function getOrders()  
    15.     {  
    16.         return $this->hasMany(OrdersModel::className(), ['id'=>'order_id']);  
    17.     }  
    18.       
    19.     //客户和国家是一对一的关系所以用hasOne  
    20.     public function getCountry()  
    21.     {  
    22.         return $this->hasOne(CountrysModel::className(), ['id'=>'Country_id']);  
    23.     }  
    24.     ....  
    25. }  
    26.         
    27. // 查询客户与他们的订单和国家  
    28. CustomerModel::find()->with('orders''country')->all();  
    29.   
    30. // 查询客户与他们的订单和订单的发货地址(注:orders 与 address都是关联关系)  
    31. CustomerModel::find()->with('orders.address')->all();  
    32.   
    33. // 查询客户与他们的国家和状态为1的订单  
    34. CustomerModel::find()->with([  
    35.     'orders' => function ($query) {  
    36.         $query->andWhere('status = 1');  
    37.         },  
    38.         'country',  
    39. ])->all();  















               











  • 相关阅读:
    图片合成
    ASP.net常用对象之一(Request对象)
    vs2010新增功能
    ASP.NET MVC 入门5、View与ViewData【转】
    ASP.NET MVC 入门3、Routing【转】
    ASP.NET MVC 入门2、项目的目录结构与核心的DLL[转]
    ASP.NET MVC 入门4、Controller与Action【转】
    jquery相关文摘
    application技术整理
    vb datagrid中的欄目順序要與recordset的順序一致
  • 原文地址:https://www.cnblogs.com/wepe/p/7424537.html
Copyright © 2011-2022 走看看