使用PHP的Yii框架的gii自动代码生成工具,可以为我们生成控制器、数据库操作、表单、模型和模块代码,在使用模块代码生成器生成模块代码后,模块却无法执行,不知道大家是否也遇到过该问题。
首先,使用gii自动代码生成工具生成module代码,代码会自动生成在项目工程中:
使用“Module Generator”生成模块代码后,会自动将生成的模块代码嵌入项目工程中,如下:
代码生成后,运行该模块,报错:
意思是找不到Controller.php文件,那什么地方使用了该文件呢?在自动生成的模板文件中,controllers文件夹下的DefaultController.php文件继承了Controller类,导致该错误产生:
<?php
class DefaultController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
}
真奇怪,gii自动生成的代码,居然找不到Yii framework的系统文件。那为什么在创建Yii工程时,默认生成的×××controller.php文件不会报这个错误呢?因为该文件继承的是CController类,而不是Controller类。而且,在index.php中,还添加了yii.php和main.php文件的引用。比如,在Yii提供的实例代码Hangman中,自动生成的GameController.php,部分代码如下:
class GameController extends CController
{
/**
* @var string sets the default action to be 'play'
*/
public $defaultAction='play';
它继承了CController类,而不是Controller类。为什么继承了CController类不会报错,而继承了Controller类就会报错呢?还得从Yii的核心类自动加载机制说起,一般来说,创建好Yii工程后,会生成一个index.php文件,文件内容大概如下:
<?php
$yii=dirname(__FILE__).'/../../framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';
require_once($yii);
Yii::createWebApplication($config)->run();
通常,我们会把yii框架的framework文件夹放置在项目工程的protected文件夹下,见上面的工程目录图。这时我们要修改一下$yii的目录为:
$yii=dirname(__FILE__)."/protected/framework/yii.php";
为什么要加载这个yii.php文件呢,因为它是Yii框架的起始执行文件,文件内容如下:
<?php
/**
* Yii bootstrap file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 Yii Software LLC
* @license http://www.yiiframework.com/license/
* @package system
* @since 1.0
*/
require(dirname(__FILE__).'/YiiBase.php');
/**
* Yii is a helper class serving common framework functionalities.
*
* It encapsulates {@link YiiBase} which provides the actual implementation.
* By writing your own Yii class, you can customize some functionalities of YiiBase.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @package system
* @since 1.0
*/
class Yii extends YiiBase
{
}
注意,yii.php中的:
require(dirname(__FILE__).'/YiiBase.php');
加载YiiBase.php文件,关键就在该文件中,查阅一下该文件代码,我们只看关键的几处,如下是定义Yii框架的目录位置:
/**
* Defines the Yii framework installation path.
*/
defined('YII_PATH') or define('YII_PATH',dirname(__FILE__));
/**
* Defines the Zii library installation path.
*/
defined('YII_ZII_PATH') or define('YII_ZII_PATH',YII_PATH.DIRECTORY_SEPARATOR.'zii');
一旦我们在index.php添加了yii.php的引用,Yii框架本身就知道了它在文件系统中的具体位置。
既然Yii框架已经知道了自己的位置,为什么还会出现找不到框架文件的情况呢?这是因为Yii是一个高效框架,体现在它的懒加载(lazy load)模式,即,引用的文件只有在使用到时才会加载&