[关闭]
@52fhy 2016-04-28T11:50:48.000000Z 字数 7720 阅读 453

Yii 框架学习--02 进阶

PHP


应用结构

入口文件

文件位置: web/index.php

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

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

配置文件

config/web.php

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

  1. <?php
  2. //加载全局配置文件
  3. $params = require(__DIR__ . '/params.php');
  4. //配置开始
  5. $config = [
  6. /* 必要属性 */
  7. 'id' => 'basic', //用来区分其他应用的唯一标识ID。主要给程序使用
  8. 'basePath' => dirname(__DIR__), //指定该应用的根目录。根目录包含应用系统所有受保护的源代码。 在根目录下可以看到对应MVC设计模式的models, views, controllers等子目录
  9. /* 重要属性 */
  10. 'aliases' => [
  11. '@name1' => 'path/to/path1',
  12. '@name2' => 'path/to/path2',
  13. ], //使用这个属性来定义别名,代替 Yii::setAlias() 方法来设置
  14. 'bootstrap' => ['log'], //指定启动阶段yii\base\Application::bootstrap()需要运行的组件
  15. 'catchAll' => [
  16. 'offline/notice',
  17. 'param1' => 'value1',
  18. 'param2' => 'value2',
  19. ], //重定向所有请求到某个控制器方法,通常用于系统维护
  20. 'components' => [
  21. 'request' => [
  22. 'cookieValidationKey' => 'test',
  23. ],
  24. 'cache' => [
  25. 'class' => 'yii\caching\FileCache',
  26. ],
  27. 'user' => [
  28. 'identityClass' => 'app\models\User',
  29. 'enableAutoLogin' => true,
  30. ],
  31. 'errorHandler' => [
  32. 'errorAction' => 'site/error',
  33. ],
  34. 'mailer' => [
  35. 'class' => 'yii\swiftmailer\Mailer',
  36. 'useFileTransport' => true,
  37. ],
  38. 'log' => [
  39. 'traceLevel' => YII_DEBUG ? 3 : 0,
  40. 'targets' => [
  41. [
  42. 'class' => 'yii\log\FileTarget',
  43. 'levels' => ['error', 'warning'],
  44. ],
  45. ],
  46. ],
  47. 'db' => require(__DIR__ . '/db.php'),
  48. /*
  49. 'urlManager' => [
  50. 'enablePrettyUrl' => true,
  51. 'showScriptName' => false,
  52. 'rules' => [
  53. ],
  54. ],
  55. */
  56. ], //注册多个在其他地方使用的应用组件
  57. 'controllerMap' => [
  58. [
  59. 'account' => 'app\controllers\UserController',
  60. 'article' => [
  61. 'class' => 'app\controllers\PostController',
  62. 'enableCsrfValidation' => false,
  63. ],
  64. ],
  65. ], //重映射控制器ID到任意控制器类
  66. 'language'=> 'en', //语言
  67. 'modules' => [
  68. // "booking" 模块以及对应的类
  69. 'booking' => 'app\modules\booking\BookingModule',
  70. // "comment" 模块以及对应的配置数组
  71. 'comment' => [
  72. 'class' => 'app\modules\comment\CommentModule',
  73. 'db' => 'db',
  74. ],
  75. ], //指定应用所包含的 模块
  76. 'name' => '', //给终端用户展示的应用名称,可选
  77. 'version' => '1.0', //版本,可选
  78. 'sourceLanguage' => 'en', //应用代码的语言,可选
  79. 'timeZone' => 'Asia/Shanghai', //默认时区,可选
  80. 'params' => $params, //全局通用参数
  81. /* 实用属性 : 通常使用系统默认值 */
  82. 'charset' => 'UTF-8', //默认值为 'UTF-8'
  83. 'defaultRoute' => 'site', //对于网页应用,默认值为 'site' 对应 SiteController 控制器,并使用默认的动作
  84. 'extensions' => [
  85. [
  86. 'name' => 'extension name',
  87. 'version' => 'version number',
  88. 'bootstrap' => 'BootstrapClassName', // 可选配,可为配置数组
  89. 'alias' => [ // 可选配
  90. '@alias1' => 'to/path1',
  91. '@alias2' => 'to/path2',
  92. ],
  93. ],
  94. ], //指定应用安装和使用的 扩展,默认自动生成和维护更新
  95. 'layout' => 'main', // 视图 默认使用的布局名字,默认值为 'main' 对应布局路径下的 main.php 文件
  96. 'layoutPath' => 'layouts', // 布局文件的路径,默认值为 视图路径 下的 layouts 子目录
  97. 'runtimePath' => '@app/runtime', //指定临时文件如日志文件、缓存文件等保存路径,默认值为带别名的 @app/runtime
  98. 'viewPath' => '@app/views', //视图文件的根目录,默认值为带别名的 @app/views
  99. 'vendorPath' => '@app/vendor', //第三方库。 默认值为带别名的 @app/vendor
  100. 'enableCoreCommands' => true, //是否启用Yii中的核心命令,默认值为 true
  101. /* 应用事件:类似于钩子 */
  102. 'on beforeRequest' => function ($event) {
  103. // ...
  104. },
  105. ];
  106. if (YII_ENV_DEV) {
  107. // configuration adjustments for 'dev' environment
  108. $config['bootstrap'][] = 'debug';
  109. $config['modules']['debug'] = [
  110. 'class' => 'yii\debug\Module',
  111. ];
  112. $config['bootstrap'][] = 'gii';
  113. $config['modules']['gii'] = [
  114. 'class' => 'yii\gii\Module',
  115. 'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 允许访问的 IP 地址
  116. ];
  117. }
  118. return $config;

使用配置:

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

使用GII

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

开启gii需要将 YII_ENV_DEV 设为 true:

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

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

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

  1. $config = [ ... ];
  2. if (YII_ENV_DEV) {
  3. $config['bootstrap'][] = 'gii';
  4. $config['modules']['gii'] = [
  5. 'class' => 'yii\gii\Module',
  6. 'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 允许访问的 IP 地址,可选
  7. ];
  8. }

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

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

数据库连接

切换数据库

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

  1. $connection = \Yii::$app->db;

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

  1. return [
  2. // ...
  3. 'components' => [
  4. 'db' => require(__DIR__ . '/db.php'),
  5. 'db2' => [
  6. 'class' => 'yii\db\Connection',
  7. 'dsn' => 'mysql:host=localhost;dbname=testdb',
  8. 'username' => 'demo',
  9. 'password' => 'demo',
  10. ],
  11. ];

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

Model里:
通过重写 yii\db\ActiveRecord::getDb() 方法切换数据库连接:

  1. class Customer extends ActiveRecord
  2. {
  3. // ...
  4. public static function getDb()
  5. {
  6. return \Yii::$app->db2; // 使用名为 "db2" 的应用组件
  7. }
  8. }

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

使用SQL直接操作数据库

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

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

查询:

  1. $connection = \Yii::$app->db;
  2. //返回DataReader对象,需要使用yii\db\DataReader解析
  3. $data = $connection->createCommand('SELECT * FROM post')->query();
  4. $rows = $data->readAll(); //返回数组
  5. //查询返回多行:(数组)
  6. $command = $connection->createCommand('SELECT * FROM post');
  7. $posts = $command->queryAll();
  8. //返回单行:(数组)
  9. $command = $connection->createCommand('SELECT * FROM post WHERE id=1');
  10. $post = $command->queryOne();
  11. //返回某个字段的集合:未指定字段返回第一个字段(数组)
  12. $command = $connection->createCommand('SELECT title FROM post');
  13. $titles = $command->queryColumn();
  14. //查询标量值/计算值: (标量)
  15. $command = $connection->createCommand('SELECT COUNT(*) FROM post');
  16. $postCount = $command->queryScalar();

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

  1. // INSERT
  2. $connection->createCommand()->insert('user', [
  3. 'name' => 'Sam',
  4. 'age' => 30,
  5. ])->execute();
  6. // INSERT 一次插入多行
  7. $connection->createCommand()->batchInsert('user', ['name', 'age'], [
  8. ['Tom', 30],
  9. ['Jane', 20],
  10. ['Linda', 25],
  11. ])->execute();
  12. // UPDATE
  13. $connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
  14. // DELETE
  15. $connection->createCommand()->delete('user', 'status = 0')->execute();

预处理语句

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

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

切换数据库类型

修改config/web.php

  1. return [
  2. // ...
  3. 'components' => [
  4. 'db' => [
  5. 'class' => 'yii\db\Connection',
  6. 'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB
  7. //'dsn' => 'sqlite:/path/to/database/file', // SQLite
  8. //'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
  9. //'dsn' => 'cubrid:dbname=demodb;host=localhost;port=33000', // CUBRID
  10. //'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver
  11. //'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver
  12. //'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver
  13. //'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle
  14. 'username' => 'root', //数据库用户名
  15. 'password' => '', //数据库密码
  16. 'charset' => 'utf8',
  17. ],
  18. ],
  19. // ...
  20. ];

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

数据库复制和读写分离

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

通过配置yii\db\Connection可以实现数据库复制和读写分离.

  1. [
  2. 'class' => 'yii\db\Connection',
  3. // 配置主服务器
  4. 'dsn' => 'dsn for master server',
  5. 'username' => 'master',
  6. 'password' => '',
  7. // 配置从服务器
  8. 'slaveConfig' => [
  9. 'username' => 'slave',
  10. 'password' => '',
  11. 'attributes' => [
  12. // use a smaller connection timeout
  13. PDO::ATTR_TIMEOUT => 10,
  14. ],
  15. ],
  16. // 配置从服务器组
  17. 'slaves' => [
  18. ['dsn' => 'dsn for slave server 1'],
  19. ['dsn' => 'dsn for slave server 2'],
  20. ['dsn' => 'dsn for slave server 3'],
  21. ['dsn' => 'dsn for slave server 4'],
  22. ],
  23. ]

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

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

类库扩展

新建helper

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

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

  1. <?php
  2. namespace yii\helpers;
  3. class Utils{
  4. public static function test() {
  5. echo 'test';
  6. }
  7. }

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

  1. Yii::$classMap['yii\helpers\Utils'] = '@app/components/Utils.php';
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注