Heim  >  Artikel  >  Backend-Entwicklung  >  Yii Framework Offizieller Leitfaden Serie 41 – Spezialthema: Automatische Codegenerierung

Yii Framework Offizieller Leitfaden Serie 41 – Spezialthema: Automatische Codegenerierung

黄舟
黄舟Original
2017-02-16 09:15:201131Durchsuche

Seit Version 1.1.2 ist Yii mit einem Webschnittstellen-basierten Codegenerierungstool Gii ausgestattet. Es ersetzt das bisherige Befehlszeilencode-Generierungstool yiic shell. In diesem Teil erklären wir, wie man Gii nutzt und wie man Gii erweitert, um unsere Entwicklungsergebnisse zu verbessern.

1. Verwendung von Gii

Gii ist als Modul implementiert und muss in einer vorhandenen Yii-Anwendung verwendet werden. Um Gii zu verwenden, ändern wir zunächst die Konfiguration der Anwendung wie folgt:


return array(
    ......
    'modules'=>array(
        'gii'=>array(
            'class'=>'system.gii.GiiModule',
            'password'=>'在这里填写密码',
            // 'ipFilters'=>array(...IP 列表...),
            // 'newFileMode'=>0666,
            // 'newDirMode'=>0777,
        ),
    ),
);


Oben deklarieren wir eine Datei mit dem Namen gii Modul, seine Klasse ist GiiModule. Wir legen auch ein Passwort für dieses Modul fest. Wenn wir auf Gii zugreifen, wird ein Eingabefeld angezeigt, in dem wir aufgefordert werden, das Passwort einzugeben.

Aus Sicherheitsgründen ist standardmäßig nur der lokale Zugriff auf Gii erlaubt. Um anderen vertrauenswürdigen Computern den Zugriff zu ermöglichen, müssen wir die Eigenschaft GiiModule::ipFilters wie oben gezeigt konfigurieren.

Da Gii neue Dateien generiert und in der Anwendung speichert, müssen wir sicherstellen, dass der Webserverprozess dazu berechtigt ist. Die oben genannten Eigenschaften GiiModule::newFileMode und GiiModule::newDirMode steuern, wie neue Dateien und Verzeichnisse generiert werden.

Hinweis: Gii wird hauptsächlich als Entwicklungstool verwendet. Daher sollte es nur auf Entwicklungsmaschinen installiert werden. Da dadurch neue PHP-Dateien in der Anwendung generiert werden können, sollten wir Sicherheitsaspekten (z. B. Festlegen von Passwörtern, IP-Filterung) genügend Aufmerksamkeit schenken.

Gii kann jetzt über die URL http://www.php.cn/ aufgerufen werden. Hier gehen wir davon aus, dass http://www.php.cn/ die URL für den Zugriff auf die Yii-Anwendung ist.

Wenn die Yii-Anwendung die Format-URL path verwendet (siehe URL-Verwaltung), können wir über die URL http://www.php.cn/ auf Gii zugreifen. Möglicherweise müssen wir die folgenden URL-Regeln vor den vorhandenen URL-Regeln hinzufügen:

'components'=>array(
    ......
    'urlManager'=>array(
        'urlFormat'=>'path',
        'rules'=>array(
            'gii'=>'gii',
            'gii/<controller:\w+>'=>'gii/<controller>',
            'gii/<controller:\w+>/<action:\w+>'=>'gii/<controller>/<action>',
            ...已有的规则...
        ),
    ),
)


Gii verfügt über einige Standardcodegeneratoren. Jeder Codegenerator ist für die Generierung eines bestimmten Codetyps verantwortlich. Beispielsweise generiert der Controller-Generator eine Controller-Klasse und einige Aktionsansichtsskripte; der Modellgenerator generiert eine ActiveRecord-Klasse für die angegebene Datentabelle.

Der grundlegende Vorgang zur Verwendung eines Generators ist wie folgt:

  1. Geben Sie die Generatorseite ein.

  2. Füllen Sie die angegebenen Felder aus Eingabefeld für Codegenerierungsparameter. Um beispielsweise mit dem Modulgenerator ein neues Modul zu erstellen, müssen Sie die Modul-ID angeben.

  3. Klicken Sie auf die Schaltfläche Preview, um eine Vorschau des generierten Codes anzuzeigen. Sie sehen eine Tabelle mit den Dateien, die generiert werden. Sie können auf eine der Dateien klicken, um eine Vorschau des Codes anzuzeigen.

  4. Klicken Sie auf die Schaltfläche Generate, um diese Codedateien zu generieren das Codegenerierungsprotokoll.

  5. 2. Gii erweitern

  6. Obwohl die Standard-Gii-Codegeneratoren sehr leistungsstarken Code generieren können, möchten wir sie oft anpassen oder einen neuen erstellen, um unseren Bedürfnissen gerecht zu werden und Bedürfnisse. Beispielsweise möchten wir, dass der generierte Code den Stil hat, den wir mögen, oder dass der Code mehrere Sprachen unterstützt. All dies ist in Gii sehr einfach umzusetzen.

Gii kann auf zwei Arten erweitert werden: Anpassen von Codevorlagen für vorhandene Codegeneratoren und Schreiben neuer Codegeneratoren.

Codegenerator-Architektur

Ein Codegenerator wird in einem Verzeichnis gespeichert, und der Name dieses Verzeichnisses gilt als Name des Generators. Das Verzeichnis besteht normalerweise aus Folgendem:

Generator-Suchpfad

Gii sucht nach verfügbaren Generatoren in dem durch die GiiModule::generatorPaths-Eigenschaft angegebenen Verzeichnis. Wenn eine Anpassung erforderlich ist, können wir die folgende Konfiguration in der Konfigurationsdatei der Anwendung vornehmen:
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


return array(
    'modules'=>array(
        'gii'=>array(
            'class'=>'system.gii.GiiModule',
            'generatorPaths'=>array(
                'application.gii',   // a path alias
            ),
        ),
    ),
);
Die obige Konfiguration teilt Gii Look mit für den Generator im Verzeichnis mit dem Alias ​​

und dem Standardspeicherort
.

Es ist auch möglich, Generatoren mit demselben Namen in verschiedenen Suchpfaden zu haben. In diesem Fall hat der Generator Priorität, der zuerst in dem durch GiiModule::generatorPaths angegebenen Verzeichnis erscheint. application.giisystem.gii.generatorsBenutzerdefinierte Codevorlagen

Dies ist die einfachste und gebräuchlichste Möglichkeit, Gii zu erweitern. Anhand eines Beispiels stellen wir vor, wie die Codevorlage angepasst wird. Angenommen, wir möchten den vom Modellgenerator generierten Code anpassen.

Wir erstellen zunächst ein Verzeichnis mit dem Namen

. Das

hier bedeutet, dass wir den Standardmodellgenerator

überschreiben

werden. protected/gii/model/templates/compact bedeutet, dass wir einen neuen Codevorlagensatz mit dem Namen model hinzufügen werden. Dann fügen wir templates/compact zu GiiModule::generatorPaths in der Anwendungskonfiguration hinzu. Wie oben gezeigt. compact

现在打开 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 "&#39;$name&#39; => 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 WidgetModelobject. We can thus get the user-entered widget class name via $this->className.



<?php echo &#39;<?php&#39;; ?>

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)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn