yii+php+当前目录,Yii应用的目录结构和入口脚本

以下是一个通过高级模版安装后典型的Yii应用的目录结构:

~~~

.

├── backend

├── common

├── console

├── environments

├── frontend

├── nbproject

├── tests

├── vendor

├── composer.json

├── composer.lock

├── init

├── init.bat

├── LICENSE.md

├── README.md

├── requirements.php

├── yii

└── yii.bat

~~~

对于高级应用而言,相当于有 backend frontend console 三个独立的Yii应用。 由于 console 类的应用比较特殊,我们稍后再讲。这里讲典型的Web应用的目录结构。

## 公共目录[](http://www.digpage.com/app_struct.html#id1 "Permalink to this headline")

这里的公共目录可不止 common 目录,但这个目录从字面上来看, 是所有公共目录里最“公共”的。common 目录下的东西, 对于本高级应用的任一独立的应用而言,都是可见、可用的。一般情况下,common 具有以下结构:

~~~

.

├── config

├── mail

└── models

~~~

其中:

* config 就是通用的配置,这些配置将作用于前后台和命令行。

* mail 就是应用的前后台和命令行的与邮件相关的布局文件等。

* models 就是前后台和命令行都可能用到的数据模型。 这也是 common 中最主要的部分。

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

好了,现在问题来了。对于 frontend backend console 等独立的应用而言, 他们的内容放在各自的目录下面,他们的运作必然用到Yii框架等 vendor 中的程序。 他们是如何关联起来的?这个秘密,或者说整个Yii应用的目录结构的秘密, 就包含在一个传说中的称为入口文件的地方。

但是在了解入口文件index.php之前,有必要先看看诸如 frontend 等独立应用的目录结构。 这比起整个Yii应用的目录结构面言,更为重要。因为你往往是在 frontend 等目录下写代码。 但是,不大会在path\to\digpage 目录下写代码。

## 前台的目录结构[](http://www.digpage.com/app_struct.html#id2 "Permalink to this headline")

其实,前台和后台是一样的,只是我们逻辑上的一个划分。 典型的, frontend 具有如下的一个目录结构:

~~~

defined('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 = yii\helpers\ArrayHelper::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 yii\web\Application($config);

$application->run();

~~~

### 设置调试模式和代码环境[](http://www.digpage.com/app_struct.html#id3 "Permalink to this headline")

前两行是两个 define 语句::

~~~

defined('YII_DEBUG') or define('YII_DEBUG', true);

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

~~~

定义当前的运行模式和环境。如果定义了 YII_DEBUG , 那么表示当前为调试状态,应用在运行过程中,会有一些调试信息的输出。 在抛出异常时,也会有一个详细的调用栈的显示。默认情况下,YII_DEBUG 为 false 。 但在开发过程中,最好按上面写的那样,定义为 true 这样便于查找和分析错误。

如果定义了 YII_ENV ,那么就是指定了当前应用的运行环境。 上面的代码显示应用将运行于 dev 环境。默认情况下, YII_ENV 为 prod 表示产品环境。

这些环境只是一个名称,具体的意义和环境内容要看环境的定义。 dev prod 是Yii安装后默认的两个环境,分别表示开发环境和最终的产品环境。 此外还有一个 test 环境,表示测试环境。

环境与模式的作用不同。环境在代码中主要是影响配置文件。 YII_ENV 的 dev prod test 三种环境, 会分别使 YII_ENV_DEV YII_ENV_PROD YII_ENV_TEST 的值为 true 。 这样,在应用的配置中,特别是在相同的一个配置文件中,可以对不同环境作出不同的配置。

比如,你希望在测试环境下,使用另一个数据库。在开发环境下,启用调试工作条,等等。那么,可以这么做:

~~~

$config = [...];

if (!YII_ENV_TEST) {

// 以下配置项仅在测试环境中起作用

$config['bootstrap'][] = 'debug';

$config['modules']['debug'] = 'yii\debug\Module';

$config['modules']['gii'] = 'yii\gii\Module';

}

~~~

其实,这个 YII_ENV 的定义就是一个与 init 脚本环境切换的相互补充。 如果各环境比较明晰,用init 来切换各种环境的配置是完全够用的。 不必在脚本中再有如 YII_ENV_TEST 之类的判断语句,这会使本来已经显得很长的配置文件看上去更臃肿。

### 引入必要的文件[](http://www.digpage.com/app_struct.html#id4 "Permalink to this headline")

紧接着两个 define 语句之后,就是4个 require 语句:

~~~

require(__DIR__ . '/../../vendor/autoload.php');

require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');

require(__DIR__ . '/../../common/config/bootstrap.php');

require(__DIR__ . '/../config/bootstrap.php');

~~~

这4个语句的前3个中都使用到了相对于当前目录的叔伯目录中的php文件, 第4个语句使用了相对于当前目录的兄弟目录。

我们知道, __DIR__ 表示当前文件 index.php 所在的目录。 /../../ 表示的是当前目录的爷爷目录。 若 index.php 的当前目录是 /path/to/digpapge.com/frontend/web , 那么爸爸目录就是 frontend,爷爷目录就是 digpage.com 了。

第一个require引入了 /path/to/digpage.com/vendor 下面的 autoload.php 。 这个是composer的类自动加载机制注册文件。引入这个文件后,可以使用composer的类自动加载功能。

第二个引入了 vendor 下面的 yiisoft/yii2/Yii.php ,这是Yii的工具类文件。 引入了这个类文件后,才能使用Yii的提供的各种工具, 才有 Yii::createObject() Yii::$app 之类的东东可以使用。

第三个引入了 /path/to/digpage.com/common 下面的 config/bootstrap.php 。 这个文件主要用于执行一些Yii应用引导的代码,比如定义一系列的路径别名:

~~~

Yii::setAlias('common', dirname(__DIR__));

Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');

Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');

Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');

Yii::setAlias('vendor', dirname(dirname(__DIR__)) . '/vendor');

~~~

这是默认安装后定义好的 common frontend backend console vendor 5个路径别名, 如果你要新增一个用于表示插件的目录 plugin 可以自己在这个文件里面加一行:

~~~

Yii::setAlias('plugin', dirname(dirname(__DIR__)) . '/plugins');

~~~

第四个require引入了 path/to/digpage.com/frontend 下面的 config/bootstrap.php 。 作用与上面类似,只是其中的代码仅适用于当前应用(frontend)。 而第三个require中的,是适应于所有应用(common)。

再接下来,是一个函数 yii\helpers\ArrayHelper::merge() 。 这个函数的作用在于合并参数所指定的各个数组。其中,后面的数组会把前面数组中相同下标的元素覆盖掉。 这个语句的作用,就是读取、合并应用的各配置文件并保存在 $config 变量中。 这里我们看到一共是读取了4个配置文件:

~~~

require('path/to/digpage.com/common/config/main.php'),

require('path/to/digpage.com/common/config/main-local.php'),

require('path/to/digpage.com/frontend/config/main.php'),

require('path/to/digpage.com/frontend/config/main-local.php')

~~~

依次是通用目录common下的2个配置文件,和当前应用frontend下的2个配置文件。 在优先顺序上,当前的配置覆盖通用的配置。 同时,带有 -local 的配置文件在后,所以,本地配置文件覆盖团队配置文件。

最后,以 $config 为参数,实例化了一个 Application 对象,并调用他的 run() 函数。 这时,Yii应用就跑起来了。

## 命令行应用入口脚本[](http://www.digpage.com/app_struct.html#id5 "Permalink to this headline")

命令行应用的入口脚本是 path/to/digpage.com/yii 文件。这个文件被 init 脚本设为可执行的。 他的内容如下:

~~~

#!/usr/bin/env php

defined('YII_DEBUG') or define('YII_DEBUG', true);

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

// fcgi doesn't have STDIN and STDOUT defined by default

defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));

defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w'));

require(__DIR__ . '/vendor/autoload.php');

require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');

require(__DIR__ . '/common/config/bootstrap.php');

require(__DIR__ . '/console/config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(

require(__DIR__ . '/common/config/main.php'),

require(__DIR__ . '/common/config/main-local.php'),

require(__DIR__ . '/console/config/main.php'),

require(__DIR__ . '/console/config/main-local.php')

);

$application = new yii\console\Application($config);

$exitCode = $application->run();

exit($exitCode);

~~~

对比于Web应用的 index.php 入口脚本, yii 并没有太多的新东西,其中核心的东西根本就没变。

我们先来看看这个这个 yii 是什么?

首先,它没有扩展名,我们不好知道其具体类型。 但是从文件内容的第一行 #!/usr/bin/env php 来看,这是一个bash脚本。 第一行在告诉bash,也在告诉我们,这是一个使用PHP运行的脚本。

但第二行的  又清楚的向我们表明,这货其实也是个 PHP 文件,只是没有加上PHP后缀而已 。

接下来, define('STDIN') 和 define('STDOUT') 则为fcgi定义了标准输入和标准输出。

在各require语句中,由于 yii 的位置与 index.php 不同,是位于应用根目录下,所以目录结构上更简单些。

最后,在Yii应用跑起来后,还要获取其返回值,并以该返回值退出脚本,通知操作系统退出时的状态。

对于Windows系统而言,命令行的入口脚本仍然是 yii ,但是命令行下无法直接运行。所以, 细心的Yii为我们准备了一个 yii.bat 。这个文件会以 php yii 形式调用PHP来运行入口脚本 。

如果觉得《深入理解Yii2.0》对您有所帮助,也请[帮助《深入理解Yii2.0》](http://www.digpage.com/donate.html#donate)。 谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542510.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8086 寻址方式_8086微处理器的不同寻址模式

8086 寻址方式Introduction: 介绍: Addressing mode tells us what is the type of the operand and the way they are accessed from the memory for execution of an instruction and how to fetch particular instruction from the memory. There are mainly 8 …

决策树的value是什么意思_从零开始的机器学习实用指南(六):决策树

类似SVM,决策树也是非常多功能的机器学习算法,可以分类,回归,甚至可以完成多输出的任务,能够拟合复杂的数据集(比如第二章的房价预测例子,虽然是过拟合了。)决策树也是很多集成学习的…

Hive中生成随机唯一标识ID的方法

2019独角兽企业重金招聘Python工程师标准>>> HIVE中处理的数据往往比较多,在处理数据的时候希望给处理得到的数据一个ID标识,这时候可以用到UUID。 UUID的算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成UUID。从理论上讲&#…

php从网页获得数据,php根据URL获得网页内容

php 中根据url来获得网页内容非常的方便,可以通过系统内置函数file_get_contents(),传入url,即可返回网页的内容,比如获得百度首页的内容代码为:$html file_get_contents(http://www.baidu.com/);echo $html;就可以显示出百度首页的内容&…

2020知道python语言应用答案_2020知到Python语言应用答案章节期末答案

组合管理理论最早由哈维马科维兹于1962年系统的提出,他开创了对投资进行整体管理的先 公司型基金和契约型基金的区别,下列不包括()。 A.资金的性质B.基金的营运依据C.基 我国(&#…

如何在Bootstrap中使用Jumbotron和页面标头类?

Introduction 介绍 In the previous article, we have learned how Responsive column, Nesting Columns and offset Columns work and how to use them? I hope now, you all are comfortable with the grid system; what is it, how to use it and how we can use it for c…

python中的数字类型格式与运算,python数字数据类型

python数字数据类型1. 数字在我们很小的时候,父母便开始教我们数数,从1数到10,聪明的孩子可以数的更多。python支持3中数值类型整型(int),通常称之为整型或整数,这个概念与我们小学时学过的整数是相同的,py…

getprocaddress得到为0_基于ZU+系列MPSoC芯片的USB3.0/2.0接口硬件设计

本文主要介绍Zynq UltraScale MPSoC系列芯片的USB3.0/2.0接口硬件设计。ZU系列MPSoC要实现USB3.0/2.0的全部功能,需要同时使用MIO和GTR。因为GTR接口中的USB接口只支持USB3.0,对USB2.0的支持需要通过MIO接口外接USB PHY实现。ZU系列MPSoC包括两个USB接口…

如何设置单词第一个字母大写_大写一行中每个单词的第一个和最后一个字母

如何设置单词第一个字母大写Problem statement: 问题陈述: Given an input line, capitalize first and last letter of each word in the given line. Its provided that the input line is in lowercase. 给定输入行, 将给定行中每个单词的第一个和最…

php如何编造简历,在简历里编造内容需要注意哪些问题?

在个人简历里编造内容可得有一定依据才行,总得为自己后期做个准备工作是不是?你编造的东西不只是给企业看一看而已,企业还会对这些内容作出进一步的判断,并且可能就其对你进行提问,如果你答不出来而曝光自己是在欺骗企…

Java LinkedList公共对象pollLast()方法(带示例)

LinkedList公共对象pollLast()方法 (LinkedList public Object pollLast() method) This method is available in package java.util.LinkedList.pollLast(). 软件包java.util.LinkedList.pollLast()中提供了此方法。 This method is used to retrieves the last or ending ele…

python编写学生成绩排序_Python实现按学生年龄排序的实际问题详解

前言 本文主要给大家了关于利用Python按学生年龄排序的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 问题:定义一个Class:包含姓名name、性别gender、年龄age,需要按…

前方危险-让很多“高逼格”高管深刻反思的文章

在很多的时候,现实会让我们每个人迷惑,周边的人和事可以让人极度的膨胀,你可以想吃了迷药一样,分不清是现实还是虚幻。很久以前,在公司的一次会议上,某主管告诉我们说,“他一个同事,…

oracle实例的概念组成,oracle体系结构的两个基本概念:数据库和实例

您可能感兴趣的话题:oracle核心提示:要了解oracle体系结构必须先了解两个基本的概念: 数据库和实例.要了解oracle体系结构必须先了解两个基本的概念: 数据库和实例.一: 数据库数据库(database)是一个数据集合.无论数据库是采用关系结构还是面向对象结构,…

c#二维数据最大最小值_C#| 打印类型,各种数据类型的最大值和最小值

c#二维数据最大最小值In the below example – we are printing types, min value, max value of various data types in C#, like integer data types, floating point data types, Boolean data type, Reference types, Nullable types. 在下面的示例中-我们正在打印C&#x…

自定义taglib引入失败_小程序拼团总失败?看看微信官方和开发者们怎么说

阅读时间:6m最懂小程序生态商业的自媒体可怕... 刚过国庆,南方还在短袖短裙,北方竟然都下雪了!什么叫一天之内感受四季?晓程序观察(yinghoo-tech)的小伙伴们算是深刻体验了,穿着短袖上飞机,抵达…

微信公众平台开发5:翻译功能

思路分析首先对用户发送过来的消息进行判断,判断消息里是否含有“翻译”关键字,如果有,则提取翻译内容,然后调用网络上开放的翻译API 进行翻译。我们用有道翻译API:http://fanyi.youdao.com/openapi?pathdata-mode记下…

Linux之基础I/O

目录 一、C语言中的文件操作 二、系统文件操作I/O 三、文件描述符fd 1、文件描述符的引入 2、对fd的理解 3、文件描述符的分配规则 四、重定向 1、重定向的原理 2、重定向的系统调用dup2 五、Linux下一切皆文件 一、C语言中的文件操作 1、打开和关闭 在C语言的文…

moore和mealy_Mealy机和Moore机的比较研究 目录

moore和mealyFinite automata may also have outputs corresponding to each input symbol. Such finite automata are known as finite automata with the output. 有限自动机还可以具有与每个输入符号相对应的输出。 这种有限自动机称为输出的有限自动机。 There are two fi…

oracle sys连接不上,oracle – 为什么我不能在SYS拥有的对象上创建触发器?

在尝试创建名为ghazal_current_bef_upd_row的触发器时&#xff1a;create trigger ghazal_current_bef_upd_rowbefore update on ghazal_currentfor each rowwhen (new.Rating < old.Rating)begininsert into ghazal_current_audit(GhazalName,Old_Rating,New_Rating)values…