在实现了创建一个完全属于自己的空白页面之后,再进行的下一步就是确认核心内容,之后逐步添加自己想要的内容。在确认核心之前,需要对yii2框架的整体目录有个大致的了解。
参考:入门(Getting Started): 运行应用(Running Applications) - Yii 2.0 权威指南 - 文档 - Yii Framework 中文网
basic/ 应用根目录
composer.json Composer 配置文件, 描述包信息
config/ 包含应用配置及其它配置
console.php 控制台应用配置信息
web.php Web 应用配置信息
commands/ 包含控制台命令类
controllers/ 包含控制器类
models/ 包含模型类
runtime/ 包含 Yii 在运行时生成的文件,例如日志和缓存文件
vendor/ 包含已经安装的 Composer 包,包括 Yii 框架自身
views/ 包含视图文件
web/ Web 应用根目录,包含 Web 入口文件
assets/ 包含 Yii 发布的资源文件(javascript 和 css)
index.php 应用入口文件
yii Yii 控制台命令执行脚本
这个上面的目录是Yii2框架basic版,最主要的核心目录,还有一些其他的目录,基本都是用到的各类功能才需要的扩展目录,如:tests(测试目录),mail(邮件功能目录),assets(资源控制),widgets(小部件),如不用这些功能,就非必要了。
上面的内容,基本都可以在yii2中文网站的文档中找到,但是说的太多,对于yii有一定了解的人,想要进一步学习的时候,这些内容是很不错的,如这个图上,把Yii2的很多东西都写上去了。但对于不了解的人一看就有点头疼,所以我们需要把核心提炼出来,以最简单的方式,最少的代码,调用yii2的框架,实现hello world页面。实际上,利用yii2框架,核心代码就可以只需要3个文件就行了,入口脚本,配置文件,类文件。
一、极简模式
1.入口脚本
入口脚本有几种,网页的入口脚本就是web\index.php,命令行的入口脚本就是根目录下yii文件,入口脚本内容很简单,一般也很少修改,里面决定了加载哪个配置文件,以及启动语句。实际上,框架自带的入口脚本还不是最简的,这里提供最简三句语句的入口脚本,我们创建新的入口脚本 web\index-base.php ,如下:
<?php
// 加载框架入口文件
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
// 指定配置文件
$config = require __DIR__ . '/../config/base.php';
// 启动命令
(new yii\web\Application($config))->run();
实际上,这么做在项目中意义不大,这里仅是为了方便帮助初学者了解框架的核心。
2.配置文件
一般配置文件都在config目录下,根据配置文件,最主要就是决定启动哪个类文件,其他还有一些功能方面的配置,如果什么功能都不用,很多配置都是不需要的。默认的配置文件中,是无'defaultRoute' 这项的,框架默认的类名是site类,通过'defaultRoute' 的配置,就可以默认加载我们自己定义的类了,也可以不改默认,通过url来定向跳转到我们类,网页跳转就是这么实现的。
这里,同样我们在config目录中,新增一个核心的配置文件,base.php,如下:
<?php
return [
'id' => 'yii2study',
'basePath' => dirname(__DIR__),
'defaultRoute' => 'hello',
];
在这里,我们指定了默认路由 defaultRoute = >'hello' ,不指定的话,就必须要修改SiteController类了,这里我们暂时不改原始文件,我们尽量用新建的文件来实现核心代码。
3.类文件
一般类文件,都在controllers目录下,类文件的文件名和类型必须一致,必须符合yii2框架的命名规范,遵守驼峰命名方式,即首字母大写,以Controller结尾。类名中,默认调用actionIndex执行函数。最终结果需要通过网页显示,一般都继承\yii\web\Controller类,另一种命令行环境下执行的类文件,一般会继承yii\console\Controller类。
<?php
namespace app\controllers;
class HelloController extends \yii\web\Controller
{
public function actionIndex()
{
// echo "Hello World!!!";
return "Hello World!!!";
}
}
这里,echo 或 return 都可以,但更复杂的输出,就会有所区别。
4.结果
到这里,通过浏览器访问URL: http://localhost/yii2_study/web/index-base.php 就可以获得结果了。
这可以说是极简模式下,应用yii2框架,在实际开发中,基本都不会这么用,因为效率还不如直接写单个php页面,我们学习框架,应用框架就是为了不重复造轮子,用别人已经造好的轮子,为自己的项目使用,所以我们需要引用很多框架中的东西。
二、常用模式
1.入口脚本
入口脚本除了最核心加载框架,加载配置,启动执行外,一般还会有以下内容:
a. 定义全局变量、全局常量
b. 加载yii2的扩展框架
<?php
// 定义全局变量、常量
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
// 加载yii2的扩展引用文件
require __DIR__ . '/../vendor/autoload.php';
// 加载yii2框架入口文件
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
// 加载网页配置文件
$config = require __DIR__ . '/../config/web.php';
// 加载测试环境配置文件
// $config = require __DIR__ . '/../config/web-test.php';
// 启动执行
(new yii\web\Application($config))->run();
但总体来说,入口脚本以简单为主,非必要不放在入口脚本中,并且入口文件并不是只能一个,一般来说,会根据配置的不同,有不同的入口文件,最常见的就是正式入口一个,测试入口一个,两者调用的配置是会有所区别的。
2.配置文件
常规配置文件不会集中在一个文件中,会根据不同项目的实际需要,进行拆分,最常见的以正式环境配置和测试环境配置,两者会有相同部分,也会有不同部分,相同部分合并在一个配置文件中,不同部分放在两个不同的配置文件中。
如共同的基础配置文件 config/base.php ,如下:
<?php
return [
'id' => 'yii2study',
'basePath' => dirname(__DIR__),
'name' => 'Yii2-Study',
'bootstrap' => ['log'],
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
],
];
而入口文件正式调用的一般是整合后的配置文件 config/web.php , 如下:
<?php
$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';
$base = require __DIR__ . '/base.php';
$advance = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'Yii2-study-wwsVa4p86yspD1Np5xdKgrWU',
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => $db,
/*
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
*/
],
'params' => $params,
];
$config = array_merge($base, $advance);
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;
在 config/web.config中,可以看到,除了加载了base.php配置外,另外整合了db, params配置文件,如下:
<?php
// db.php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2study',
'username' => 'root',
'password' => '1234',
'charset' => 'utf8',
// Schema cache options (for production environment)
//'enableSchemaCache' => true,
//'schemaCacheDuration' => 60,
//'schemaCache' => 'cache',
];
<?php
// params.php
return [
'adminEmail' => 'admin@example.com',
'senderEmail' => 'noreply@example.com',
'senderName' => 'Example.com mailer',
];
在测试入口脚本中,往往会调用另一个整合后的配置文件,如 config/test.php 其中,可能加载数据库配置文件会是另一个数据库配置db-test.php这类。这才是yii2框架中,配置文件的最佳实践。
3.MVC模式
在正式的开发场景中,仅调用类文件的方式并不多见,一般都是调用类文件,然后类文件中调用模型文件获得数据,在调用视图文件,进行输出,这就是一个基本的MVC模式。
在类的使用中,往往会嵌套继承类,很多项目都会有一个基类,用来实现内部定义全局的类变量、类常量,以及一些权限控制配置,其余的类都会继承这个基类,由基类来继承web\Controller类。当然,也有不用基类,直接继承 web/Controller 类的方式,这两者都属于常规用法。
这里,我们先建一个Login类,并附一个Index动作,在Index动作中,调用User模型,输出index视图页面。
3.1 类文件 controllers/Demo1Controller.php
在Yii框架的类文件,文件名需要和类名一致,并且类名必须以Controller结尾,并继承了web/Controller类,动作函数必须以action开头,这样的命名才符合Yii框架的路由规则,能够通过Url进行访问。路由中如果仅指定了类名,没有指定动作名,则默认访问actionIndex动作。
<?php
namespace app\controllers;
use app\models\UserInfo;
class Demo1Controller extends \yii\web\Controller
{
// 这里设置影响整个Controller的所有action
//public $layout = false; // 不使用布局文件
public function actionIndex()
{
// 这里设置仅这个action有效
$this->layout = false; // 不使用布局文件
$m_user = new UserInfo();
$user = $m_user->findByUsername('admin');
return $this->render('view1', ['userinfo' => $user]);
}
}
Index动作中,通过render加载的视图view1,默认指向views/类名/view1.php,如果没有特别指定,默认加载views/layouts/main.php布局文件。这里我们先从简单说起,暂时不加载布局文件,设置不加载布局,有多种方式,这里列了2种,通过类变量$layout进行设置,则整个类文件中有效,在函数中,设置layout则仅在这个函数中有效。
在Controller向View中传递数据,可以通过render函数中的第二个参数,进行传递,但只能传递数组对象。
在Controller中获取models中的数据,需要先引用对应了model类文件,才能使用。
3.2 模型文件 models/UserInfo.php
在Yii框架中,模型的概念有很多种,可以是和数据库相关的数据模型,也可以本身就代表了的数据对象,也可以是Form表单类型,这里我们先建立一个简单的对象数据模型。这里,我们简单建立一个UserInfo的对象,设定了2个静态值,并提供一个获取数据的方法。
<?php
// models\UserInfo.php
namespace app\models;
class UserInfo extends \yii\base\BaseObject
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
'101' => [
'id' => '101',
'username' => 'demo',
'password' => 'demo',
'authKey' => 'test101key',
'accessToken' => '101-token',
],
];
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
}
3.3 视图文件 views/demo1/view1.php
在MVC模式中,一般视图文件,在views目录下,以类名为目录名,在对应的类名目录下的视图文件。在类函数中,通过不同的调用函数,决定了加载视图的方式,这里,因为是不用布局文件,直接加载的视图,所以视图中就需要自己带上html、body等这类标签,一般这类标签都是在布局文件中定义,视图文件头尾都是用一个div标签包裹就行的。
<?php
/* @var $this yii\web\View */
// 视图中选择布局,仅本视图有效
//$this->context->layout = false; // 不使用布局
$this->title = "Yii2 学习笔记3";
$this->beginPage()
?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
<meta name="keywords" content="yii2,php,yii2-study">
<meta name="author" content="Myron.Maoyz">
<?php $this->registerCsrfMetaTags() ?>
<title><?= $this->title ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<!--页面loading-->
<div>
<pre>
<?php
var_dump($userinfo);
?>
</pre>
</div>
<!--页面loading end-->
</body>
<?php $this->endBody() ?>
</html>
<?php $this->endPage() ?>
4. 结果
通过浏览器访问URL:http://localhost/yii2_study/web/index.php?r=demo1
三、模块
yii2中的模块通常是指包含了完整独立功能的MVC的集合。这个属于yii2的高阶使用技巧了。
最终,说明一下Yii2框架中,核心MVC各自常规使用方式。
M=》Model
主要负责实现数据库的交互,数据模型定义,数据输出。
V=》View
主要负责页面展示,前端用户交互。
C=》Controller
主要负责从Model处获取数据,按照业务需求,进行逻辑处理,最终交付View调用。
最后,说明一下,如何学习Yii2框架?
学习一款框架
第一步,当然是先部署好框架的运行环境,让整个框架可以运行起来。
第二步,通过官方网站的基本介绍说明,了解框架的运行模式,取出最核心的部分,实现Hello World。
第三步,切割框架的各个功能模块,基于基础的Hello World,对各个功能模块,从简单开始,进行逐一学习,我是建议1视图,2模型,3控制。
第四步,基于核心的功能模块整合,实现基础功能,例如基于MVC实现权限控制。
第五步,选择几个开发中较为常见的专题进行研究,如RESTful模式,API模式,控制台模式
第六部,针对各种模式、专题,实现常用场景的功能,积累各种示例代码。
到这里,基本就算是掌握了这款框架了。
对应的示例代码: yii2_study: 学习yii2的各种组件应用示例