1.1.2 버전부터 Yii에는 웹 인터페이스 기반 코드 생성 도구 Gii가 탑재되어 있습니다. 이는 이전 명령줄 코드 생성 도구 yiic shell
를 대체합니다. 이번 파트에서는 Gii를 어떻게 활용하는지, Gii를 확장하여 개발 성과를 높이는 방법에 대해 설명하겠습니다.
Gii는 모듈로 구현되어 있으며, 기존 Yii 애플리케이션에서 사용해야 합니다. Gii를 사용하기 위해 먼저 애플리케이션의 구성을 다음과 같이 변경합니다.
return array( ...... 'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'在这里填写密码', // 'ipFilters'=>array(...IP 列表...), // 'newFileMode'=>0666, // 'newDirMode'=>0777, ), ), );
위에서는 gii
이라는 파일을 선언했습니다. 모듈의 클래스는 GiiModule입니다. 또한 이 모듈에 대한 비밀번호를 설정했습니다. Gii에 액세스하면 비밀번호를 입력하라는 입력 상자가 나타납니다.
보안상의 이유로 Gii에 대한 로컬 액세스만 기본적으로 허용됩니다. 다른 신뢰할 수 있는 컴퓨터가 액세스할 수 있도록 허용하려면 위에 표시된 대로 GiiModule::ipFilters 속성을 구성해야 합니다.
Gii는 새 파일을 생성하여 애플리케이션에 저장하기 때문에 웹 서버 프로세스에 해당 권한이 있는지 확인해야 합니다. 위의 GiiModule::newFileMode 및 GiiModule::newDirMode 속성은 새 파일과 디렉터리가 생성되는 방법을 제어합니다.
참고: Gii는 주로 개발 도구로 사용됩니다. 따라서 개발 머신에만 설치해야 합니다. 애플리케이션에서 새로운 PHP 파일을 생성할 수 있으므로 보안 문제(비밀번호 설정, IP 필터링 등)에 충분한 주의를 기울여야 합니다.
이제 URLhttp://www.php.cn/
을 통해 Gii에 액세스할 수 있습니다. 여기서는 http://www.php.cn/
이 Yii 애플리케이션에 액세스하기 위한 URL이라고 가정합니다.
Yii 애플리케이션이 path
형식의 URL을 사용하는 경우(URL 관리 참조) http://www.php.cn/
URL을 통해 Gii에 액세스할 수 있습니다. 기존 URL 규칙 앞에 다음 URL 규칙을 추가해야 할 수도 있습니다.
'components'=>array( ...... 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'gii'=>'gii', 'gii/<controller:\w+>'=>'gii/<controller>', 'gii/<controller:\w+>/<action:\w+>'=>'gii/<controller>/<action>', ...已有的规则... ), ), )
Gii에는 몇 가지 기본 코드 생성기가 있습니다. 각 코드 생성기는 특정 유형의 코드를 생성하는 역할을 담당합니다. 예를 들어, 컨트롤러 생성기는 컨트롤러 클래스와 일부 작업 보기 스크립트를 생성합니다. 모델 생성기는 지정된 데이터 테이블에 대한 ActiveRecord 클래스를 생성합니다.
생성기 사용의 기본 과정은 다음과 같습니다.
생성기 페이지를 입력하세요.
지정된 내용을 입력하세요. 코드 생성 매개변수 입력 상자. 예를 들어, 모듈 생성기를 사용하여 새 모듈을 생성하려면 모듈 ID를 지정해야 합니다.
생성될 코드를 미리 보려면 Preview
버튼을 클릭하세요. 생성될 파일이 나열된 테이블이 표시됩니다.
Generate
버튼을 클릭하면
보기할 수 있습니다. 코드 생성 로그.
기본 Gii 코드 생성기는 매우 강력한 코드를 생성할 수 있지만 종종 필요에 따라 이를 사용자 정의하거나 새로운 코드를 만들고 싶어합니다. 그리고 필요합니다. 예를 들어 생성된 코드가 우리가 원하는 스타일이기를 원하거나 코드가 여러 언어를 지원하기를 원합니다. 이 모든 것은 Gii에서 구현하기가 매우 쉽습니다.
Gii는 기존 코드 생성기에 대한 코드 템플릿을 사용자 정의하고 새로운 코드 생성기를 작성하는 두 가지 방법으로 확장할 수 있습니다.
코드 생성기는 디렉터리에 저장되며, 이 디렉터리의 이름이 생성기의 이름으로 간주됩니다. 디렉터리는 일반적으로 다음으로 구성됩니다.
model/ the model generator root folder ModelCode.php the code model used to generate code ModelGenerator.php the code generation controller views/ containing view scripts for the generator index.php the default view script templates/ containing code template sets default/ the 'default' code template set model.php the code template for generating model class code
Gii는 GiiModule::generatorPaths 속성에 지정된 디렉터리에서 사용 가능한 생성기를 찾습니다. 사용자 정의가 필요한 경우 애플리케이션의 구성 파일에서 다음 구성을 만들 수 있습니다.
return array( 'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', 'generatorPaths'=>array( 'application.gii', // a path alias ), ), ), );
위 구성은 Gii에게 별칭 생성기는 application.gii
디렉터리와 기본 위치 system.gii.generators
에서 검색됩니다.
다른 검색 경로에 동일한 이름을 가진 생성기가 있을 수도 있습니다. 이 경우 GiiModule::generatorPaths에 의해 지정된 디렉터리에 처음 나타나는 생성기가 우선순위를 가집니다.
Gii를 확장하는 가장 쉽고 일반적인 방법입니다. 예제를 사용하여 코드 템플릿을 사용자 정의하는 방법을 소개합니다. 모델 생성기가 생성한 코드를 사용자 정의한다고 가정해 보겠습니다.
먼저 protected/gii/model/templates/compact
라는 디렉터리를 만듭니다. 여기서 model
는 기본 모델 생성기를 재정의한다는 의미입니다. templates/compact
은 compact
이라는 이름의 새 코드 템플릿 세트를 추가한다는 의미입니다.
그런 다음 애플리케이션 구성의 GiiModule::generatorPaths에 application.gii
을 추가합니다. 위에 표시된 것처럼.
现在打开 model 代码生成器页面。点击 Code Template
输入框。我们应当看到一个下拉列表,这个列表包含了我们新建的模板目录 compact
。可是,若我们选择此模板生成代码,我们将看到错误。这是因为我们还没有在新的 compact
模板集中放入任何实际的代码模板文件。
复制文件 framework/gii/generators/model/templates/default/model.php
到protected/gii/model/templates/compact
。若我们再次尝试以 compact
模板生成,我们会成功。但是,生成的代码和以 default
模板集生成的代码没什么不同。
现在是时候做点真正的工作了。打开文件 protected/gii/model/templates/compact/model.php
以编辑它。记得这个文件将作为类似一个视图文件被使用,意味着它可以包含 PHP 表达式和语句。让我们更改模板以便生成的代码里 attributeLabels()
方法使用 Yii::t()
来翻译属性标签:
public function attributeLabels() { return array( <?php foreach($labels as $name=>$label): ?> <?php echo "'$name' => Yii::t('application', '$label'),\n"; ?> <?php endforeach; ?> ); }
在每个代码模板中,我们可以访问一些预定义的变量,例如上面例子中的 $labels
。这些变量由对应的代码生成器提供。不同的代码生成器可能在他们的代码模板中提供不同的变量。请认真阅读默认代码模板中的描述。
In this sub-section, we show how to create a new generator that can generate a new widget class.
We first create a directory named protected/gii/widget
. Under this directory, we will create the following files:
WidgetGenerator.php
: contains the WidgetGenerator
controller class. This is the entry point of the widget generator.
WidgetCode.php
: contains the WidgetCode
model class. This class has the main logic for code generation.
views/index.php
: the view script showing the code generator input form.
templates/default/widget.php
: the default code template for generating a widget class file.
Creating WidgetGenerator.php
The WidgetGenerator.php
file is extremely simple. It only contains the following code:
class WidgetGenerator extends CCodeGenerator { public $codeModel='application.gii.widget.WidgetCode'; }
In the above code, we specify that the generator will use the model class whose path alias isapplication.gii.widget.WidgetCode
. The WidgetGenerator
class extends from CCodeGenerator which implements a lot of functionalities, including the controller actions needed to coordinate the code generation process.
Creating WidgetCode.php
The WidgetCode.php
file contains the WidgetCode
model class that has the main logic for generating a widget class based on the user input. In this example, we assume that the only input we want from the user is the widget class name. Our WidgetCode
looks like the following:
class WidgetCode extends CCodeModel { public $className; public function rules() { return array_merge(parent::rules(), array( array('className', 'required'), array('className', 'match', 'pattern'=>'/^\w+$/'), )); } public function attributeLabels() { return array_merge(parent::attributeLabels(), array( 'className'=>'Widget Class Name', )); } public function prepare() { $path=Yii::getPathOfAlias('application.components.' . $this->className) . '.php'; $code=$this->render($this->templatepath.'/widget.php'); $this->files[]=new CCodeFile($path, $code); } }
The WidgetCode
class extends from CCodeModel. Like a normal model class, in this class we can declarerules()
and attributeLabels()
to validate user inputs and provide attribute labels, respectively. Note that because the base class CCodeModel already defines some rules and attribute labels, we should merge them with our new rules and labels here.
The prepare()
method prepares the code to be generated. Its main task is to prepare a list of CCodeFileobjects, each of which represent a code file being generated. In our example, we only need to create oneCCodeFile object that represents the widget class file being generated. The new widget class will be generated under the protected/components
directory. We call CCodeFile::render method to generate the actual code. This method includes the code template as a PHP script and returns the echoed content as the generated code.
Creating views/index.php
Having the controller (WidgetGenerator
) and the model (WidgetCode
), it is time for us to create the viewviews/index.php
.
<h1>Widget Generator</h1> <?php $form=$this->beginWidget('CCodeForm', array('model'=>$model)); ?> <p class="row"> <?php echo $form->labelEx($model,'className'); ?> <?php echo $form->textField($model,'className',array('size'=>65)); ?> <p class="tooltip"> Widget class name must only contain word characters. </p> <?php echo $form->error($model,'className'); ?> </p> <?php $this->endWidget(); ?>
In the above, we mainly display a form using the CCodeForm widget. In this form, we display the field to collect the input for the className
attribute in WidgetCode
.
When creating the form, we can exploit two nice features provided by the CCodeForm widget. One is about input tooltips. The other is about sticky inputs.
If you have tried any default code generator, you will notice that when setting focus in one input field, a nice tooltip will show up next to the field. This can easily achieved here by writing next to the input field a p
whose CSS class is tooltip
.
For some input fields, we may want to remember their last valid values so that the user can save the trouble of re-entering them each time they use the generator to generate code. An example is the input field collecting the controller base class name default controller generator. These sticky fields are initially displayed as highlighted static text. If we click on them, they will turn into input fields to take user inputs.
In order to declare an input field to be sticky, we need to do two things.
First, we need to declare a sticky
validation rule for the corresponding model attribute. For example, the default controller generator has the following rule to declare that baseClass
and actions
attributes are sticky:
public function rules() { return array_merge(parent::rules(), array( ...... array('baseClass, actions', 'sticky'), )); }
Second, we need to add a CSS class named sticky
to the container p
of the input field in the view, like the following:
<p class="row sticky"> ...input field here... </p>
Creating templates/default/widget.php
Finally, we create the code template templates/default/widget.php
. As we described earlier, this is used like a view script that can contain PHP expressions and statements. In a code template, we can always access the $this
variable which refers to the code model object. In our example, $this
refers to the WidgetModel
object. We can thus get the user-entered widget class name via $this->className
.
<?php echo '<?php'; ?> class <?php echo $this->className; ?> extends CWidget { public function run() { } }
This concludes the creation of a new code generator. We can access this code generator immediately via the URL http://www.php.cn
以上就是Yii框架官方指南系列41——专题:自动代码生成的内容,更多相关内容请关注PHP中文网(www.php.cn)!