Mit dem Zend Framework 2 können Sie als Entwickler nicht nur komplexe Webanwendungen und Webservices umsetzen. Der integrierte Code-Generator ist ein praktisches Werkzeug, um lästige Aufgaben bei der Einrichtung neuer Projekte automatisieren zu können. Kombiniert mit einer Konsolenanwendung können Sie Ihr eigenes RAD-Tool (Rapid-Application-Development) aufsetzen, das nicht allein auf die Code-Generierung für das Zend Framework 2 beschränkt ist. In dieser Session lernen Sie das Rüstzeug für den Aufbau eines solchen Tools kennen.
18. PHAR GenerierenPHAR Generieren
18 / 59
// PHAR Paket erstellen lassen
$ bin/create-phar.php
Phar created successfully in /home/devhost/dwx2015-code-generate/phpcg.phar
// Phar Paket verwenden
$ php phpcg.phar
---------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Available commands:
autocomplete Command autocompletion setup
create-hello-you-class Create hello you class
create-user-entities Create user entities
hello-someone Hello someone
hello-world Hello world
hello-you Hello you
help Get help for individual commands
update-user-entities Update user entities
version Display the version of the script
---------------------------------------------------------------------------
19. HilfeHilfe
19 / 59
// Autovervollständigung einrichten
$ bin/phpcg.php help
---------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Available commands:
autocomplete Command autocompletion setup
create-hello-you-class Create hello you class
create-user-entities Create user entities
hello-someone Hello someone
hello-world Hello world
hello-you Hello you
help Get help for individual commands
update-user-entities Update user entities
version Display the version of the script
---------------------------------------------------------------------------
20. Routing BeispieleRouting Beispiele
20 / 59
// Route ohne Parameter 'say-stuff'
$ bin/phpcg.php say-stuff
// Route mit obligatorischem Wertparameter 'say-stuff <stuff>'
$ bin/phpcg.php say-stuff Whatever
// Route mit optionalem Flag 'do-stuff [--strict|-s]:strict'
$ bin/phpcg.php do-stuff -s
// Route mit optionalem Wertparameter 'do-stuff [--target=]'
$ bin/phpcg.php do-stuff --target=Whatever
23. KommandoKommando
23 / 59
<?php
// Datei /src/PHPCG/Command/HelloWorld.php
namespace PHPCGCommand;
use ZendConsoleAdapterAdapterInterface as Console;
use ZendConsoleColorInterface as Color;
use ZFConsoleRoute;
class HelloWorld
{
public function __invoke(Route $route, Console $console)
{
$console->writeLine('Hello World', Color::YELLOW);
}
}
24. KonsoleKonsole
24 / 59
$ bin/phpcg.php hello-world
---------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Hello World
---------------------------------------------------------------------------
29. KommandoKommando
29 / 59
<?php
// Datei /src/PHPCG/Command/HelloSomeOne.php
[...]
use ZendConsolePromptLine;
use ZendConsolePromptSelect;
class HelloSomeOne
{
public function __invoke(Route $route, Console $console)
{
$prompt = new Line('Please enter any name: ');
$you = $prompt->show();
$options = array(Color::BLACK => 'BLACK', [...], Color::BLUE => 'BLUE');
$prompt = new Select('Please choose any color: ', $options);
$color = $prompt->show();
$console->write('Hello ');
$console->write(sprintf(' %s ', $you), Color::WHITE, $color);
$console->writeLine(' ...');
}
}
30. KonsoleKonsole
30 / 59
$ bin/phpcg.php hello-someone
---------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Please enter any name: Ralf
Please choose any color:
1) BLACK
2) RED
3) GREEN
4) YELLOW
5) BLUE
Hello ...
---------------------------------------------------------------------------
ralf@ralf-HP-2013:/home/devhost/dwx2015-code-generierung$
Ralf
35. Class Generator IClass Generator I
35 / 59
<?php
// Datei /src/PHPCG/Generator/HelloYouClassGenerator.php
namespace PHPCGGenerator;
use ZendCodeGeneratorClassGenerator;
use ZendCodeGeneratorMethodGenerator;
use ZendCodeGeneratorParameterGenerator;
use ZendCodeGeneratorPropertyGenerator;
class HelloYouClassGenerator
{
private $class;
public function getClass()
{
return $this->class;
}
public function createClass() {}
}
36. Class Generator IIClass Generator II
36 / 59
<?php
public function createClass()
{
$nameProperty = new PropertyGenerator('name');
$nameProperty->addFlag(PropertyGenerator::FLAG_PRIVATE);
$nameSetMethod = new MethodGenerator('setName');
$nameSetMethod->addFlag(MethodGenerator::FLAG_PUBLIC);
$nameSetMethod->setParameter(new ParameterGenerator('name'));
$nameSetMethod->setBody('$this->name = $name;');
$greetMethod = new MethodGenerator('greet');
$greetMethod->addFlag(MethodGenerator::FLAG_PUBLIC);
$greetMethod->setBody('return sprintf("Hello %s!", $this->name);');
$this->class = new ClassGenerator('HelloYou', 'HelloGreeting');
$this->class->addPropertyFromGenerator($nameProperty);
$this->class->addMethods(array($nameSetMethod, $greetMethod));
}
37. FILE GeneratorFILE Generator
37 / 59
<?php
// Datei /src/PHPCG/Generator/ClassFileGenerator.php
namespace PHPCGGenerator;
use ZendCodeGeneratorClassGenerator;
use ZendCodeGeneratorDocBlockGenerator;
use ZendCodeGeneratorFileGenerator;
class ClassFileGenerator
{
private $file;
public function getFile()
{
return $this->file;
}
public function createFile(ClassGenerator $class)
{
$docBlock = new DocBlockGenerator([...]);
$this->file = new FileGenerator();
$this->file->setClass($class);
$this->file->setDocBlock($docBlock);
}
}
38. KommandoKommando
38 / 59
<?php
// Datei /src/PHPCG/Command/CreateHelloYouClass.php
namespace PHPCGCommand;
[...]
class CreateHelloYouClass
{
public function __invoke(Route $route, Console $console)
{
$fileName = DWX2015_PHPCG_ROOT . '/tmp/HelloYouClass.php';
$classGenerator = new HelloYouClassGenerator();
$classGenerator->createClass();
$class = $classGenerator->getClass();
$fileGenerator = new ClassFileGenerator();
$fileGenerator->createFile($class);
$file = $fileGenerator->getFile();
file_put_contents($fileName, $file->generate());
[...]
}
}
39. KonsoleKonsole
39 / 59
$ bin/phpcg.php create-hello-you-class
----------------------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Created class HelloYou in file
/home/devhost/dwx2015-code-generierung/tmp/HelloYouClass.php
<?php
namespace HelloGreeting;
class HelloYou
{
private $name = null;
public function setName($name)
{
$this->name = $name;
}
public function greet()
{
return sprintf("Hello %s!", $this->name);
}
}
----------------------------------------------------------------------------------------
45. Meta Data Collector IMeta Data Collector I
45 / 59
<?php
// Datei /src/PHPCG/MetaData/Collector.php
namespace PHPCGCollector;
use ZendDbMetadataMetadata;
use ZendDbMetadataObjectColumnObject;
class MetaDataCollector
{
public function __construct(Metadata $metaData)
{
$this->metaData = $metaData;
}
public function fetchTableColumns($tableName)
{
$tableColumns = array();
[...]
return $tableColumns;
}
}
46. Meta Data Collector IIMeta Data Collector II
46 / 59
<?php
[...]
foreach ($tableMeta->getColumns() as $column) {
$config = array('required' => !$column->getIsNullable());
if (in_array($column->getDataType(), array('varchar','text','enum'))) {
$config['type'] = 'string';
} else {
$config['type'] = 'integer';
}
if ($column->getDataType() == 'varchar') {
$config['max_length'] = $column->getCharacterMaximumLength();
} elseif ($column->getDataType() == 'enum') {
$config['values'] = $column->getErrata('permitted_values');
}
$tableColumns[$column->getName()] = $config;
}
47. User Entity Generator IUser Entity Generator I
47 / 59
<?php
// Datei /src/PHPCG/Generator/UserEntityGenerator.php
namespace PHPCGGenerator;
use ZendCodeGeneratorClassGenerator;
use ZendCodeGeneratorDocBlockGenerator;
use ZendCodeGeneratorMethodGenerator;
use ZendCodeGeneratorParameterGenerator;
use ZendCodeGeneratorPropertyGenerator;
use ZendCodeGeneratorValueGenerator;
use ZendFilterWordUnderscoreToCamelCase;
class UserEntityGenerator extends ClassGenerator
{
private $class;
private $filterUTCC;
public function __construct() {}
public function getClass() {}
public function createClass() {}
public function addEntityProperties(array $columns = array()) {}
}
48. User Entity Generator IIUser Entity Generator II
48 / 59
<?php
public function __construct()
{
$this->filterUTCC = new UnderscoreToCamelCase();
}
public function getClass()
{
return $this->class;
}
public function createClass()
{
$this->class = new ClassGenerator('UserEntity', 'UserEntity');
$this->class->setDocBlock(
new DocBlockGenerator([...])
);
}
49. User Entity Generator IIIUser Entity Generator III
49 / 59
<?php
public function addEntityProperties()
{
foreach ($this->columns as $name => $attributes) {
$property = $this->generateProperty($name, $attributes);
$getMethod = $this->generateGetMethod($name, $attributes);
$setMethod = $this->generateSetMethod($name, $attributes);
$this->class->addPropertyFromGenerator($property);
$this->class->addMethodFromGenerator($getMethod);
$this->class->addMethodFromGenerator($setMethod);
}
}
private function generateProperty($name, array $attributes = array())
{
$property = new PropertyGenerator($name);
$property->addFlag(PropertyGenerator::FLAG_PROTECTED);
return $property;
}
50. User Entity Generator IVUser Entity Generator IV
50 / 59
<?php
private function generateGetMethod($name, array $attributes = array())
{
$methodName = 'get' . $this->filterUTCC->filter($name);
$getMethod = new MethodGenerator($methodName);
$getMethod->addFlag(MethodGenerator::FLAG_PUBLIC);
$getMethod->setBody('return $this->' . $name . ';');
return $getMethod;
}
51. User Entity Generator VUser Entity Generator V
51 / 59
<?php
private function generateSetMethod($name, array $attribs = array())
{
$methodName = 'set' . $this->filterUTCC->filter($name);
$defaultValue = !$attribs['required'] ? new ValueGenerator(null) : null;
$setMethod = new MethodGenerator($methodName);
$setMethod->addFlag(MethodGenerator::FLAG_PUBLIC);
$setMethod->setParameter(
new ParameterGenerator($name, null, $defaultValue)
);
$setMethod->setBody('$this->' . $name . ' = $' . $name . ';');
return $setMethod;
}
52. Kommando IKommando I
52 / 59
<?php
// Datei /src/PHPCG/Command/CreateUserEntities.php
namespace PHPCGCommand;
use PHPCGCollectorMetaDataCollector;
use PHPCGGeneratorClassFileGenerator;
use PHPCGGeneratorUserEntityGenerator;
use ZendConsoleAdapterAdapterInterface as Console;
use ZendConsoleColorInterface as Color;
use ZendDbAdapterAdapter;
use ZendDbMetadataMetadata;
use ZFConsoleRoute;
class CreateUserEntities
{
public function __invoke(Route $route, Console $console)
{
[...]
}
}
53. Kommando IIKommando II
53 / 59
<?php
public function __invoke(Route $route, Console $console)
{
$dbConfig = include DWX2015_PHPCG_ROOT . '/config/db.php';
$fileName = DWX2015_PHPCG_ROOT . '/tmp/UserEntity.php';
$dbAdapter = new Adapter($dbConfig['adapter']);
$metaData = new Metadata($dbAdapter);
$collector = new MetaDataCollector($metaData);
$userColumns = $collector->fetchTableColumns('user');
$classGenerator = new UserEntityGenerator();
$classGenerator->createClass();
$classGenerator->addEntityProperties($userColumns);
$class = $classGenerator->getClass();
$fileGenerator = new ClassFileGenerator();
$fileGenerator->createFile($class);
$file = $fileGenerator->getFile();
file_put_contents($fileName, $file->generate());
[...]
}
54. KonsoleKonsole
54 / 59
$ bin/phpcg.php create-user-entities
-------------------------------------------------------------------------------------------------
PHP Code Generator (DWX2015), version 1.0.0
Created class UserEntity in file
/home/devhost/dwx2015-code-generierung/tmp/UserEntity.php
<?php
namespace UserEntity;
class UserEntity
{
protected $id = null;
[...]
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
[...]
}
-------------------------------------------------------------------------------------------------
58. DANKEDANKE
Für Ihre / Eure Aufmerksamkeit!
Repository: https://github.com/RalfEggert/dwx2015-code-generierung
Slides: http://de.slideshare.net/eggertralf/dwx2015-codegenerierung
58 / 59
59. BildnachweisBildnachweis
[B00] Fotos von Ralf Eggert
[B01] Carrot And Stick Incentives Lead Manage http://www.workcompass.com/ von Alan O'Rourke - CC-BY https://creativecommons.org/licenses/by/2.0/
[B02] Frontiers 2011 - Day 2 https://www.flickr.com/photos/frontiersofinteraction/5866676276/ von Frontiersofinteraction - CC-BY https://creativecommons.org/licenses/by/2.0/
[B03] Multi Tools https://www.flickr.com/photos/pennuja/5363515039 von Jim Pennucci - CC-BY https://creativecommons.org/licenses/by/2.0/
[B04] Command https://www.flickr.com/photos/shearforce/3838603833/ von Margaret Shear - CC-BY-SA https://creativecommons.org/licenses/by-sa/2.0/
[B05] Propeller Generator in the Sunset https://www.flickr.com/photos/jiazi/2060352110/ von Tim Wang - CC-BY-SA https://creativecommons.org/licenses/by-sa/2.0/
[B06] Fixing the database https://www.flickr.com/photos/dahlstroms/4140461901 von Håkan Dahlström - CC-BY https://creativecommons.org/licenses/by/2.0/
[B07] I have an idea @ home https://www.flickr.com/photos/ful1to/3783198574/ von Julian Santacruz - CC-BY https://creativecommons.org/licenses/by/2.0/
[B08] Etech05: Audience https://www.flickr.com/photos/oreilly/6648470 von James Duncan Davidson - CC-BY https://creativecommons.org/licenses/by/2.0/
Alle weiteren Screenshots wurden von Ralf Eggert erstellt.
59 / 59