zoukankan      html  css  js  c++  java
  • Yii 框架学习--02 进阶

    本文以YII 2.0.7为例。

    应用结构

    入口文件

    文件位置: web/index.php

    <?php
    
    //开启debug,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆栈
    defined('YII_DEBUG') or define('YII_DEBUG', true);
    
    //环境定义
    defined('YII_ENV') or define('YII_ENV', 'dev'); //dev,prod
    
    // 注册 Composer 自动加载器
    require(__DIR__ . '/../vendor/autoload.php');
    
    // 包含 Yii 类文件
    require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
    
    // 加载应用配置
    $config = require(__DIR__ . '/../config/web.php');
    
    // 创建、配置、运行一个应用
    (new yiiwebApplication($config))->run();
    

    需要注意的是,如果想通过命令行方式(cli)访问应用,入口文件是根目录下的yii。里面的内容实质是php代码,与config/web.php类似。Windows下请使用yii.bat。该文件在Linux下需要有执行权限,这样用户就能通过命令./yii <route> [arguments] [options] 来运行cli应用。

    配置文件

    config/web.php

    下面列出全部配置属性,实际项目请选择性配置。

    <?php
    
    //加载全局配置文件
    $params = require(__DIR__ . '/params.php');
    
    //配置开始
    $config = [
        /* 必要属性 */
        'id' => 'basic', //用来区分其他应用的唯一标识ID。主要给程序使用
        'basePath' => dirname(__DIR__), //指定该应用的根目录。根目录包含应用系统所有受保护的源代码。 在根目录下可以看到对应MVC设计模式的models, views, controllers等子目录
        
        /* 重要属性 */
        'aliases' => [
            '@name1' => 'path/to/path1',
            '@name2' => 'path/to/path2',
        ], //使用这个属性来定义别名,代替 Yii::setAlias() 方法来设置
        'bootstrap' => ['log'], //指定启动阶段yiiaseApplication::bootstrap()需要运行的组件
        'catchAll' => [
            'offline/notice',
            'param1' => 'value1',
            'param2' => 'value2',
        ], //重定向所有请求到某个控制器方法,通常用于系统维护
        'components' => [
            'request' => [
                'cookieValidationKey' => 'test',
            ],
            'cache' => [
                'class' => 'yiicachingFileCache',
            ],
            'user' => [
                'identityClass' => 'appmodelsUser',
                'enableAutoLogin' => true,
            ],
            'errorHandler' => [
                'errorAction' => 'site/error',
            ],
            'mailer' => [
                'class' => 'yiiswiftmailerMailer',
                'useFileTransport' => true,
            ],
            'log' => [
                'traceLevel' => YII_DEBUG ? 3 : 0,
                'targets' => [
                    [
                        'class' => 'yiilogFileTarget',
                        'levels' => ['error', 'warning'],
                    ],
                ],
            ],
            'db' => require(__DIR__ . '/db.php'),
            /*
            'urlManager' => [
                'enablePrettyUrl' => true,
                'showScriptName' => false,
                'rules' => [
                ],
            ],
            */
        ], //注册多个在其他地方使用的应用组件
        'controllerMap' => [
            [
                'account' => 'appcontrollersUserController',
                'article' => [
                    'class' => 'appcontrollersPostController',
                    'enableCsrfValidation' => false,
                ],
            ],
        ], //重映射控制器ID到任意控制器类
        'language'=> 'en', //语言
        'modules' => [
            // "booking" 模块以及对应的类
            'booking' => 'appmodulesookingBookingModule',
    
            // "comment" 模块以及对应的配置数组
            'comment' => [
                'class' => 'appmodulescommentCommentModule',
                'db' => 'db',
            ],
        ], //指定应用所包含的 模块
        'name' => '', //给终端用户展示的应用名称,可选
        'version' => '1.0', //版本,可选
        'sourceLanguage' => 'en', //应用代码的语言,可选
        'timeZone' => 'Asia/Shanghai', //默认时区,可选
        'params' => $params, //全局通用参数
        
        /* 实用属性 : 通常使用系统默认值 */
        'charset' => 'UTF-8', //默认值为 'UTF-8'
        'defaultRoute' => 'site', //对于网页应用,默认值为 'site' 对应 SiteController 控制器,并使用默认的动作
        'extensions' => [
            [
                'name' => 'extension name',
                'version' => 'version number',
                'bootstrap' => 'BootstrapClassName',  // 可选配,可为配置数组
                'alias' => [  // 可选配
                    '@alias1' => 'to/path1',
                    '@alias2' => 'to/path2',
                ],
            ],
        ], //指定应用安装和使用的 扩展,默认自动生成和维护更新
        'layout' => 'main', // 视图 默认使用的布局名字,默认值为 'main' 对应布局路径下的 main.php 文件
        'layoutPath' => 'layouts', // 布局文件的路径,默认值为 视图路径 下的 layouts 子目录
        'runtimePath' => '@app/runtime', //指定临时文件如日志文件、缓存文件等保存路径,默认值为带别名的 @app/runtime
        'viewPath' => '@app/views', //视图文件的根目录,默认值为带别名的 @app/views
        'vendorPath' => '@app/vendor', //第三方库。 默认值为带别名的 @app/vendor
        'enableCoreCommands' => true, //是否启用Yii中的核心命令,默认值为 true
        
        /* 应用事件:类似于钩子 */
        'on beforeRequest' => function ($event) {
        // ...
        },
    ];
    
    if (YII_ENV_DEV) {
        // configuration adjustments for 'dev' environment
        $config['bootstrap'][] = 'debug';
        $config['modules']['debug'] = [
            'class' => 'yiidebugModule',
        ];
    
        $config['bootstrap'][] = 'gii';
        $config['modules']['gii'] = [
            'class' => 'yiigiiModule',
            'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 允许访问的 IP 地址
        ];
    }
    
    return $config;
    

    使用配置:

    components:使用Yii::$app->ComponentID 全局访问
    params:Yii::$app->params['key']
    

    使用GII

    gii是yii提供的代码自动生成器,可以通过简单的输入生成ControllerModelView等文件代码,并提供代码预览功能。

    开启gii需要将 YII_ENV_DEV 设为 true:

    defined('YII_ENV') or define('YII_ENV', 'dev');
    

    我们通过 URL 访问 Gii:http://hostname/index.php?r=gii

    由于Gii 是 Yii 中的一个模块。可以通过配置应用的 yiiaseApplication::modules 属性开启它。通常来讲在 config/web.php 文件中会有以下配置代码:

    $config = [ ... ];
    
    if (YII_ENV_DEV) {
        $config['bootstrap'][] = 'gii';
        $config['modules']['gii'] = [
            'class' => 'yiigiiModule',
            'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 允许访问的 IP 地址,可选
        ];
    }
    

    这段配置表明,如果当前是开发环境,应用会包含 gii 模块,模块类是 yiigiiModule

    关于GII的用法请查看:http://www.yiichina.com/doc/guide/2.0/start-gii

    数据库连接

    切换数据库

    默认使用的是config/db.php里的数据库配置。配置连接组件后Yii里可以使用以下语法访问:

    $connection = Yii::$app->db;
    

    同理,我们可以修改config/web.php

    return [
        // ...
        'components' => [
            'db' => require(__DIR__ . '/db.php'),
            'db2' => [
                'class' => 'yiidbConnection',
                'dsn' => 'mysql:host=localhost;dbname=testdb',
                'username' => 'demo',
                'password' => 'demo',
            ],
    ];
    

    定义多个数据库连接配置。

    Model里:
    通过重写 yiidbActiveRecord::getDb() 方法切换数据库连接:

    class Customer extends ActiveRecord
    {
        // ...
    
        public static function getDb()
        {
            return Yii::$app->db2;  // 使用名为 "db2" 的应用组件
        }
    }
    

    http://www.yiichina.com/doc/guide/2.0/db-active-record

    使用SQL直接操作数据库

    ActiveRecord 提供了数据库与模型(MVC 中的 M,Model) 的交互,QueryBuilder 用于创建动态的查询语句。

    yii除了可以使用模型对象的方式(ORM)操作数据库外,还可以使用原生的SQL语句。通过yiidbCommand::createCommand可以执行SQL语句。

    查询:

    $connection = Yii::$app->db;
    
    //返回DataReader对象,需要使用yiidbDataReader解析
    $data = $connection->createCommand('SELECT * FROM post')->query();  
    $rows = $data->readAll(); //返回数组
      
    //查询返回多行:(数组)  
    $command = $connection->createCommand('SELECT * FROM post');  
    $posts = $command->queryAll();  
    
    //返回单行:(数组)  
    $command = $connection->createCommand('SELECT * FROM post WHERE id=1');  
    $post = $command->queryOne();  
    
    //返回某个字段的集合:未指定字段返回第一个字段(数组) 
    $command = $connection->createCommand('SELECT title FROM post');  
    $titles = $command->queryColumn();  
    
    //查询标量值/计算值:  (标量)
    $command = $connection->createCommand('SELECT COUNT(*) FROM post');  
    $postCount = $command->queryScalar();  
    

    可以使用insert,update,delete 方法,这些方法会根据参数生成合适的SQL并执行:

    // INSERT
    $connection->createCommand()->insert('user', [
        'name' => 'Sam',
        'age' => 30,
    ])->execute();
    
    // INSERT 一次插入多行
    $connection->createCommand()->batchInsert('user', ['name', 'age'], [
        ['Tom', 30],
        ['Jane', 20],
        ['Linda', 25],
    ])->execute();
    
    // UPDATE
    $connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
    
    // DELETE
    $connection->createCommand()->delete('user', 'status = 0')->execute();
    

    预处理语句

    为安全传递查询参数可以使用预处理语句,首先应当使用:placeholder占位,再将变量绑定到对应占位符:

    $command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
    $command->bindValue(':id', $_GET['id']);
    $post = $command->query();
    另一种用法是准备一次预处理语句而执行多次查询:
    
    $command = $connection->createCommand('DELETE FROM post WHERE id=:id');
    $command->bindParam(':id', $id);
    
    $id = 1;
    $command->execute();
    
    $id = 2;
    $command->execute();
    

    切换数据库类型

    修改config/web.php

    return [
        // ...
        'components' => [
            'db' => [
                'class' => 'yiidbConnection',
                'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB
                //'dsn' => 'sqlite:/path/to/database/file', // SQLite
                //'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
                //'dsn' => 'cubrid:dbname=demodb;host=localhost;port=33000', // CUBRID
                //'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver
                //'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver
                //'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver
                //'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle
                'username' => 'root', //数据库用户名
                'password' => '', //数据库密码
                'charset' => 'utf8',
            ],
        ],
        // ...
    ];
    

    http://www.yiichina.com/doc/guide/2.0/db-dao

    数据库复制和读写分离

    很多数据库支持数据库复制 database replication来提高可用性和响应速度. 在数据库复制中,数据总是从主服务器 到 从服务器. 所有的插入和更新等写操作在主服务器执行,而读操作在从服务器执行.

    通过配置yiidbConnection可以实现数据库复制和读写分离.

    [
        'class' => 'yiidbConnection',
    
        // 配置主服务器
        'dsn' => 'dsn for master server',
        'username' => 'master',
        'password' => '',
    
        // 配置从服务器
        'slaveConfig' => [
            'username' => 'slave',
            'password' => '',
            'attributes' => [
                // use a smaller connection timeout
                PDO::ATTR_TIMEOUT => 10,
            ],
        ],
    
        // 配置从服务器组
        'slaves' => [
            ['dsn' => 'dsn for slave server 1'],
            ['dsn' => 'dsn for slave server 2'],
            ['dsn' => 'dsn for slave server 3'],
            ['dsn' => 'dsn for slave server 4'],
        ],
    ]
    

    以上的配置实现了一主多从的结构,从服务器用以执行读查询,主服务器执行写入查询,读写分离的功能由后台代码自动完成。调用者无须关心。

    http://www.yiichina.com/doc/guide/2.0/db-dao

    类库扩展

    新建helper

    示例:新建一个Utils类。该文件可以在任何目录,例如 @app/components

    我们在根目录新建components文件夹,并新建components/Utils.php:

    <?php
    
    namespace yiihelpers;
    
    class Utils{
        
        public static function test() {
            echo 'test';
        }
    }
    
    

    引入:
    在应用程序入口文件(index.php)处,在引入的 yii.php 文件后面 添加以下代码行,用 Yii 自动加载器 来加载自定义类 代替框架的原始助手类:

    Yii::$classMap['yiihelpersUtils'] = '@app/components/Utils.php';
    

    未完待续。。。

  • 相关阅读:
    electron项目打包成dmg
    到底什么是流?
    cent日常操作实践(二)
    pm2基本使用
    koa + sequelize + mysql 项目实践笔记
    cenos 磁盘操作
    MySQL基础操作汇总二
    Python调用shell
    Python常用模块之七 PIL
    random
  • 原文地址:https://www.cnblogs.com/52fhy/p/5349394.html
Copyright © 2011-2022 走看看