A PHP-ben az objektumtulajdonságok beállítására van egy beépített lehetőség (__get() és __set() metódusok), azonban ezek nem típusbiztosak, így ajánlott saját getter és setter metódusokat írni a tulajdonságok kezelésére. Viszont ez igen időigényes feladat, és a Zend Studio-n kívül még nem találkoztam IDE-vel, ami megtenné helyettem, úgyhogy írtam egy kódot ennek a folyamatnak az automatizálására. Ez a leírás elsősorben Windows felhasználóknak lesz hasznos, viszont a kódolás gyorsítására érdemes lehet kipróbálni a scriptet más rendszer alatt fejlesztőknek is. Hogy teljesen világos legyen mindenki számára, hogy mit értek getter és setter metódusok alatt, íme egy példa:
<?php
namespace valami\tartalom\menedzser;
/**
* Egy tartalomkezelőben egy leírást reprezentáló osztály
* @author BlackY
*/
class Content
{
/**
* A leírás címe
* @var string
*/
private $title;
/**
* A leírás beküldője
* @var \valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo
*/
private $author;
/**
* A leírás szövege
* @var string
*/
private $text;
/**
* A leíráshoz kapcsolt tagok
* @var array
*/
private $tags;
}
Az adattagokat az adatelrejtés okán priváttá tettük, viszont valahogy el kéne érni őket. Első próbálkozás lehet a __get() és __set() metódusok használata, azonban az nem típusbíztos: ha biztonságos kódot szeretnénk írni, mindig tesztelnünk kéne az author tulajdonság értékét, hogy null-e ill. objektum-e ill. a megfelelő osztály egy példánya-e. Azonban ha biztosra tudjuk, hogy az author \valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo objektum (a sok \ az ún. névteret adja meg) akkor a plusz ellenőrzések feleslegessé válnak. Ugyanez az osztály az összes getter/setter metódussal:
<?php
namespace valami\tartalom\menedzser;
class Content
{
/**
* A leírás címe
* @var string
*/
private $title;
/**
* A leírás beküldője
* @var \valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo
*/
private $author;
/**
* A leírás szövege
* @var string
*/
private $text;
/**
* A leíráshoz kapcsolt tagok
* @var array
*/
private $tags;
/**
* Getter method of the title property
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Setter method of the title property
* @param string $value - The new value of the property
* @return valami\tartalom\menedzser\Content
*/
public function setTitle($title)
{
$this->title = (string)$title;
return $this;
}
/**
* Getter method of the author property
* @return \valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo
*/
public function getAuthor()
{
return $this->author;
}
/**
* Setter method of the author property
* @param \valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo $value - The new value of the property
* @return valami\tartalom\menedzser\Content
*/
public function setAuthor(\valami\tartalom\menedzser\felhasznaloKezeles\Felhasznalo $author)
{
$this->author = $author;
return $this;
}
/**
* Getter method of the text property
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Setter method of the text property
* @param string $value - The new value of the property
* @return valami\tartalom\menedzser\Content
*/
public function setText($text)
{
$this->text = (string)$text;
return $this;
}
/**
* Getter method of the tags property
* @return array
*/
public function getTags()
{
return $this->tags;
}
/**
* Setter method of the tags property
* @param array $value - The new value of the property
* @return valami\tartalom\menedzser\Content
*/
public function setTags(array $tags)
{
$this->tags = $tags;
return $this;
}
}
(A félig angol félig magyar dokumentáció rosszul néz ki, de két kattintással generáltam) Ez utóbbi folyamatot veszi át a következő kód:
<?php
/**
* GS-Generator
* This tool can be used to create getter and setter method stubs for any class.
* Usage:
* php GS-Generator.php "class_file_name" <optinal flags>
* Optional flags:
* -c = Copy to clipboard instead of printing to file (Windows only, requires MS Word)
* -d = Debug mode - create assertions for setter function with native types
* -gv [public|private|protected] = The visibility of the getter methods
* -sv [public|private|protected] = The visibility of the setter methods
* @version 1.0 beta
* @author BlackY
*/
/**
* The basic level of indention used (default: 1 tabs)
* @var string
*/
$indention = str_repeat("\t", 1);
/**
* The visibility of getter methods
* @var string
*/
$getterVisibility = ($index = array_search('-gv', $argv)) !== false ? $argv[$index + 1] : 'public';
/**
* The visibility of the setter methods
* @var string
*/
$setterVisibility = ($index = array_search('-sv', $argv)) !== false ? $argv[$index + 1] : 'public';
/**
* A flag indicating whether to include assertions in the produces code
* @var bool
*/
$includeAssert = in_array('-d', $argv);
/**
* A list of "black listed" types: those that require no type hinting.
* Array is not listed here, as arrays are handled another way.
* @var array
*/
$typeBlackList = array(
'int', 'integer',
'bool', 'boolean',
'float', 'double', 'real',
'string',
'callback', 'scalar', 'var', 'unknown'
);
/**
* A list of native data types that need no casting
*/
$noCast = array('callback', 'scalar', 'var', 'unknown', 'resource');
/**
* The list of type checking functions to use in the assertions.
* @var array
*/
$typeCheckFunctions = array(
'int' => 'is_int', 'integer' => 'is_int',
'bool' => 'is_bool', 'boolean' => 'is_bool',
'float' => 'is_float', 'double' => 'is_float', 'real' => 'is_float',
'string' => 'is_string',
'resource' => 'is_resource',
'callback' => 'is_callable', 'scalar' => 'is_scalar'
);
/**
* The name of the input file
* @var string
*/
$fileName = null;
/* Find the input file in the arguments */
foreach($argv as $arg) {
if(basename(__FILE__) != basename($arg) && file_exists($arg) && is_readable($arg)) {
$fileName = $arg;
}
}
if(!$fileName) {
die('Input file not specified or not found/readable!');
}
chdir(dirname($fileName));
/** Get the list of classes that need getter/setter methods */
$old_classes = get_declared_classes();
if(!include_once($fileName)) {
die('Input file inclusion failed.');
}
$new_classes = get_declared_classes();
$classes = array_diff($new_classes, $old_classes);
if(!$classes) {
die('No class definition in input file!');
}
/* Generate the methods */
foreach($classes as $class) {
$reflection = new ReflectionClass($class);
$source = '';
foreach($reflection->getProperties() as $property) {
$name = $property->getName();
$docComment = $property->getDocComment();
$type = 'unknown';
if(preg_match('/@var\s+(.*)\b/i', $docComment, $regs)) {
$type = $regs[1];
}
$hasMethods = $reflection->hasMethod('get' . $name) && $reflection->hasMethod('set' . $name);
$nonProtected = $property->isPublic();
$isStatic = $property->isStatic();
if($hasMethods || $nonProtected || $isStatic) {
continue;
}
/* Getter method */
$source .= $indention . '/**' . PHP_EOL;
$source .= $indention . ' * Getter method of the ' . $name . ' property' . PHP_EOL;
$source .= $indention . ' * @return ' . $type . PHP_EOL;
$source .= $indention . '*/' . PHP_EOL;
if(strtolower($type) == 'bool' || strtolower($type) == 'boolean') {
$source .= $indention . $getterVisibility . ' function is' . ucfirst($name) . '()' . PHP_EOL;
} else {
$source .= $indention . $getterVisibility . ' function get' . ucfirst($name) . '()' . PHP_EOL;
}
$source .= $indention . '{' . PHP_EOL;
$source .= $indention . "\t" . 'return $this->' . $name . ';' . PHP_EOL;
$source .= $indention . '}' . PHP_EOL . PHP_EOL;
/* Setter method */
$source .= $indention . '/**' . PHP_EOL;
$source .= $indention . ' * Setter method of the ' . $name . ' property' . PHP_EOL;
$source .= $indention . ' * @param ' . $type . ' $value - The new value of the property' . PHP_EOL;
$source .= $indention . ' * @return ' . $reflection->getName() . PHP_EOL;
$source .= $indention . '*/' . PHP_EOL;
$source .= $indention . $setterVisibility . ' function set' . ucfirst($name) . '(';
$cast = '';
$assert = '';
if(in_array(strtolower($type), $typeBlackList)) {
$source .= '$' . $name;
if(!in_array(strtolower($type), $noCast)) {
$cast = '(' . $type . ')';
}
if($includeAssert && isset($typeCheckFunctions[strtolower($type)])) {
$assert = $indention . "\t" . 'assert(\'' . $typeCheckFunctions[strtolower($type)] . '($' . $name . ')\')' . PHP_EOL;
}
} elseif(strtolower($type) == 'array') {
$source .= 'array $' . $name;
} else {
$source .= $type . ' $' . $name;
}
$source .= ')' . PHP_EOL;
$source .= $indention . '{' . PHP_EOL;
$source .= $assert;
$source .= $indention . "\t" . '$this->' . $name . ' = '. $cast . '$' . $name . ';' . PHP_EOL;
$source .= $indention . "\t" . 'return $this;' . PHP_EOL;
$source .= $indention . '}' . PHP_EOL . PHP_EOL;
}
$filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . basename($reflection->getName() . '_generated.php');
file_put_contents($filename, $source);
if(class_exists('COM') && in_array('-c', $argv) && count($classes) == 1) {
try {
$com = new COM('Word.Application');
$com->Visible = false;
$com->Documents->Add();
$com->Selection->TypeText($source);
$com->Selection->WholeStory();
$com->Selection->Copy();
$com->Quit(false);
unlink($filename);
} catch(Exception $x) {
try {
$com->Quit(false);
} catch(Exception $x) {}
}
}
}
A feladatunk össz-vissz annyi, hogy a fenti - első - Content osztálynak megfelelően leírjuk az osztályunkat: a docCommentekben legyen ott a @var direktíva. Ezután - mindent alapbeállításon hagyva - a kód a > php GS-Generator.php myClassFile.php
utasítást kiadva létrehozza a metódusok forráskódját és elmenti az <osztálynév>_generated.php névvel létrehozott fájlokban. (Ha a bemeneti fájlban több osztály van, több ilyen fájl jön létre). Ezt copy-pastelve az osztály törzsébe, kész is vagyunk. A kód automatikusan generál type hinteket az osztályokhoz és a tömb típushoz, a natív típusokat pedig az elhelyezésük előtt converálja (castolja) a megfelelő típusra. Ezzel az egyetlen probléma az lehet, ha egy tulajdonság vagy egy objektum vagy null értéket vehet fel (a fenti példában például már törölve lett a cikk írója vagy egyéb okból nem elérhető), a null érték miatt a PHP hibát ad. Ezt áthidaló bevezettem a var "típust", ezt használva nincs castolás és típus súgás (sajnos típus biztonság sem). (Ezeket a setterek érdemes kézzel átírni, hogy is_nul() és instanceof-al eldöntsék, helyes-e az érték, mielőtt beírják az értéket) Újra átolvasva a PHP manualt észrevettem a kitételt, hogy a > <típusnév> $valtozo = null
paraméter-definíció esetén adható null érték a változónak. Az oldal végén levő új változat már használja ezt a lehetőséget.A natív adattípusokon (bool, int, float, string) kívül használhatjuk még a scalar (bármelyik skaláris érték) illetve a callback (hívható) típusokat. Az elkészült docCommentekben találkozhatunk még az unknown típussal, ezt használja a rendszer, ha nem volt típus jelölve a tulajdonságnál.A lap végén levő frissített kód hiányzó típusmegadás esetén nem hoz végre settert/gettert.Azokhoz a tulajdonságokhoz, amelyek már rendelkeznek getter és setter függvénnyel vagy (bármilyen oknál fogva) publikusak nem hoz létre metódusokat, így egy új tulajdonság felvitelekor csak az azok kezelését biztosító függvényeket hozza létre. A fentieken felül még néhány további opciót is kezel a rendszer, ezek parancssori paraméterrel kapcsolhatók: - -gv [public|protected|private] - A getter metódusok láthatóságát állíthatjuk be
- -sv [public|protected|private] - A setter metódusok láthatósága
- -d - Debug mód: assert()-ek hozzáadása a kódhoz, így a natív adattípusok is ellenőrzésre kerülnek. Az éles szerverre kerülés előtt generáljuk újra a metódusokat a kapcsoló nélkül!
- -c - Csak Windows rendszeren, telepített Microsoft Word-del (csak ez utóbbi COM objektumain keresztül tudok kommunikálni a vágólappal. Ha tudsz jobb megoldást, szólj!)! Az elkészült kódot nem fájlba menti, hanem a vágólapra másolja
Utóbbi opció azért került bele, hogy a php fájlok helyi menüjéhez hozzá tudjak rendelni egy új elemet, ami legenerálja a metódusokat és azok kódját a vágólapra teszi. Ezt a következő képpen tehetjük meg: indítsuk el a regedit-et. A bal oldali fában keressük meg a HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ .php \ Shell kulcsot. (Ha valamelyik nem létezik, jobb klikk a szülőn, új, majd kulcs). Itt hozzunk létre egy kulcsot azzal a névvel, amilyen nevet a helyi menüben látni szeretnénk. Nálam egy "Metódusok generálása GSGenerator-ral (Assert: On)" ill. "Metódusok generálása GSGenerator-ral (Assert: Off)" lett (két külön kulcs). A létrehozott kulcson belül hozzunk létre egy új kulcsot "Command" néven, majd kattintsunk rá. A jobb oldalon az (Alapértelmezett) értékre kattintva írjuk be a parancsot, amit futtatni szeretnénk: > "C:\A php útvonala\php-win.exe" "C:\A GSGenerator.php fájl útvonala" [flagek] "%1"
A [flagek] helyére természetesen behelyettesítve a fentebb írt paramétereket. Nálam a két kulcs a következőképp néz ki: > "C:\Program Files\xampplite\php\php-win.exe" "C:\Documents and Settings\Rendszergazda\Asztal\GS-Generator.php" -c -d "%1"
és > "C:\Program Files\xampplite\php\php-win.exe" "C:\Documents and Settings\Rendszergazda\Asztal\GS-Generator.php" -c "%1"
Remélem másnak is hasznos lesz ez a rövid script és leírás. Jó munkát! Módosítás: Ahogy azt már fentebb írtam a kivágott részek után, készítettem egy frisebb verziót (letisztultabb lett a kódja stb.) A paraméterézében is történt néhány változás (ehhez mérten a Registry-be írt paramétereket is változnak). Az új használat (<fájlnév> az a fájlnév, amelyen a generálót elmentettük): > php <fájlnév> [<kapcsolók,paraméterek>]
Az új kód működik minden parancssori paraméter nélkül is, ha így indítjuk, a standard inputról olvassa a forráskódot és a standard outputra küldi ki az eredményt. A --input <fájlnév> kapcsoló használatával elérhetjük, hogy a standard input helyett a fájlnév tartalmát értelmezze. A -f kapcsoló segítségével az elkészült kódokat fájlba írja ki, ezek elnevezesét a --template "fájlnév_sablon" paraméterrel módosíthatjuk (ebben az osztálynév (a névtér nem) is behelyettesítésre kerül a %1$s helyekre). A láthatóságot ezentúl a --getter <public|protected|private> és --setter <public|protected|private> paraméterekkel állíthatjuk. Megadhatjuk, hogy hányszoros behúzást használjon a rendszer az --indention <szám> paraméterrel, továbbá az --indentionString "<string>" paraméterrel beállíthatjuk, hogy az egy szintű behúzás mit jelentsen (space és tab indentálás így cserélgethető). Így például a négy szóközzel való, két szintű indentálást a > php <fájlnév> --indentionString " " --indention 2
utasítással érhetjük el. Természetesen megmaradt az assert hívások és az automatikus castolás lehetősége is, ezeket a -a ill. -ac kapcsolókkal érhetjük el. Hiba - vagy figyelmezetések - esetén a kód a standard error csatornára ír ki üzeneteket, ha ezt el akarjuk tüntetni, a -s kapcsolót állítsuk be. Végül a korábbi verzióból megismert vágólapra másolás is visszatért, ezt a -c kapcsoló állításával kapcsolhatjuk be. Ha a -c és -s kapcsolót is használjuk, sikeres lefutás végén egy felbukkanó ablak értesít arról, hogy végzett. (Ez esetemben hasznos, a fenti registry módosítással ez lett az alapvető akció a .php fájl típusoknál, így az Eclipse helyi menüjében az Open With -> System Editorral tudom futtatni, ezért kellett az értesítő) Fontos változás az előző verzióhoz képest, hogy ez a fájlban csak egy osztályt kezel (elkerülve hogy egy teljes keretrendszert megpróbáljon átírni), így vagy csak egy osztályt deklaráljunk a fájlban, vagy használjuk a --class <osztálynév> paramétert.
<?php
/**
* Generate Getter and Setter methods
* This utility can be used to create getter and setter methods for any class.
* -s (Silent mode)
* -f (Output file instead of writing to STDOUT)
* -c (Copy source code instead of writing to STDOUT)
* -a (Add assertions)
* -ac (Add casts)
* --template (The file naming scheme)
* --input (Input file)
* --getter <private|protected|public> - The visibility of the getter functions
* --setter <private|protected|public> - The visibility of the setter functions
* --indention - The number of tabs before each line
* --indentionString - The string used for indention
* @author Szigeti Márton Levente blacky@invitel.hu
* @package ggsm
*/
$indent = cliParameter('indentionString', "\t");
$getterMethodDocCommentTemplate = explode(PHP_EOL, <<<TEMPLATE
/**
* Getter method of the %1\$s property
* @return %2\$s The value of the property
*/
TEMPLATE
);
$setterMethodDocCommentTemplate = explode(PHP_EOL, <<<TEMPLATE
/**
* Setter method of the %1\$s property
* @param %6\$s%4\$s%2\$s \$%1\$s%5\$s The new value of the %1\$s property
* @return %3\$s The instance containing the property
*/
TEMPLATE
);
$getterMethodTemplate = explode(PHP_EOL, <<<TEMPLATE
%2\$s function %4\$s%1\$s()
{
{$indent}return \$this->%3\$s;
}
TEMPLATE
);
$setterMethodTemplate = explode(PHP_EOL, <<<TEMPLATE
%2\$s function %1\$s(%5\$s%4\$s\$%3\$s%6\$s)
{
{$indent}%7\$s\$this->%3\$s = %4\$s%8\$s$%3\$s;
}
TEMPLATE
);
/** No editable parts below */
function getValidator($type)
{
if(!isNative($type)) {
return '';
} else {
$validators = array(
'bool' => 'is_bool', 'boolean' => 'is_bool',
'int' => 'is_int', 'integer' => 'is_int',
'float' => 'is_float', 'double' => 'is_float', 'real' => 'is_float',
'string' => 'is_string', 'object' => 'is_object',
'number' => 'is_numeric', 'callback' => 'is_callable');
if(isset($validators[strtolower($type)])) {
return $validators[strtolower($type)];
}
return null;
}
}
function getCast($type)
{
if(!isNative($type)) {
return '';
} else {
$casts = array(
'bool' => '(bool)', 'boolean' => '(boolean)',
'int' => '(int)', 'integer' => '(integer)',
'float' => '(float)', 'double' => '(double)', 'real' => '(real)',
'string' => '(string)', 'object' => '(object)');
if(isset($casts[strtolower($type)])) {
return $casts[strtolower($type)];
}
return null;
}
}
function isNative($type)
{
return in_array(strtolower(extractBaseType($type)),
array(
'bool', 'boolean', 'int', 'integer', 'float', 'double', 'real',
'string', 'object',
/* Pseudo-types */ 'number', 'callback'
));
}
function extractType($comment)
{
if(preg_match('/@var\s+([&\\\\\w?]+)/', $comment, $regs)) {
return $regs[1];
}
return null;
}
function extractBaseType($type, $classNamespace = null)
{
$type = trim($type, '?&');
if(!is_null($classNamespace)) {
if(dirname($type) == $classNamespace) {
$type = basename($type);
}
}
return $type;
}
function isReference($type)
{
return $type{0} == '&';
}
function isNullable($type)
{
return substr($type, -1) == '?';
}
function cliParameter($parameter, $default = null)
{
global $argv;
$parameter = strtolower($parameter);
foreach($argv as $index => $argument) {
if(strtolower($argument) == '--' . $parameter) {
if(isset($argv[$index + 1]) && $argv[$index + 1]{0} != '-') {
return $argv[$index + 1];
}
}
}
return $default;
}
function cliFlagSet($flag)
{
global $argv;
foreach($argv as $argument) {
if($argument == '-' . $flag || $argument == '/' . $flag) {
return true;
}
}
return false;
}
function println($message, $file = STDOUT)
{
if(!cliFlagSet('s')) {
fwrite($file, $message . PHP_EOL);
}
}
function ifExit($condition, $message = null, $code = null)
{
if($condition) {
if(!is_null($message)) {
println($message, STDERR);
}
exit($code);
}
}
function gsErrorHandler($errno, $errstr, $file, $line)
{
println(sprintf('%3$s[%4$d]: (%1$d) %2$s', $errno, $errstr, basename($file), $line), STDERR);
}
$inputFile = cliParameter('input', null);
$workingDirectory = getcwd();
if(!$inputFile) {
println('Starting in interactive mode (Hit CTRL+Z to quit)', STDERR);
$sourceCode = '';
while(!feof(STDIN)) {
$chunk = fread(STDIN, 8192);
$sourceCode .= $chunk;
}
} else {
$condition = !(file_exists($inputFile) && is_readable($inputFile));
ifExit($condition, sprintf('The specified input file can not be found: %s', $inputFile) ,1);
chdir(dirname($inputFile));
ini_set('include_path', '.' . PATH_SEPARATOR . ini_get('include_path'));
$sourceCode = file_get_contents($inputFile);
}
$classesBefore = get_declared_classes();
ifExit(eval('?>' . $sourceCode) === false, 'Source code could not be parsed', 2);
chdir($workingDirectory);
$classesAfter = get_declared_classes();
$classes = array_values(array_diff($classesAfter, $classesBefore));
ifExit(count($classes) == 0, 'Source code did not contain class declarations. Terminating.', 4);
$class = $classes[0];
ifExit((count($classes) > 1) && ($class = cliParameter('class', false)) === false, 'Source code contained more than one class declaration. Use --class <className>. Terminating.', 5);
/* Prepare templates */
$function = create_function('&$line', '$line = rtrim(str_repeat(cliParameter("indentionString", "\t"), cliParameter("indention", 1)) . $line);');
array_walk($getterMethodDocCommentTemplate, $function);
array_walk($setterMethodDocCommentTemplate, $function);
array_walk($getterMethodTemplate, $function);
array_walk($setterMethodTemplate, $function);
$getterMethodDocCommentTemplate = implode(PHP_EOL, $getterMethodDocCommentTemplate);
$setterMethodDocCommentTemplate = implode(PHP_EOL, $setterMethodDocCommentTemplate);
$getterMethodTemplate = implode(PHP_EOL, $getterMethodTemplate);
$setterMethodTemplate = implode(PHP_EOL, $setterMethodTemplate);
/* Preparing templates end */
$reflection = new ReflectionClass($class);
$properties = $reflection->getProperties();
$propertiesSorted = array();
foreach($properties as $property) {
$propertiesSorted[$property->getName()] = $property;
}
ksort($propertiesSorted);
$properties = $propertiesSorted;
/* Create source code */
$source = '';
$useStatements = '';
$name = explode('\\', $reflection->getName());
$classNamespace = version_compare(phpversion(), '5.3.0') ? implode('\\', array_slice($name, 0, count($name) - 1)) : null;
foreach($propertiesSorted as $property) {
$setterName = 'set' . ucfirst($property->getName());
$getterName = 'get' . ucfirst($property->getName());
if(($reflection->hasMethod($setterName) && $reflection->hasMethod($getterName)) || $property->isPublic()) {
continue;
}
$type = extractType($property->getDocComment());
if(is_null($type)) {
continue;
}
$name = $property->getName();
$baseType = extractBaseType($type, $classNamespace);
$classType = extractBaseType($reflection->getName(), $classNamespace);
$getterVisibility = cliParameter('getter', 'public');
$setterVisibility = cliParameter('setter', 'public');
$cast = cliFlagSet('ac', false) && isNative($type) ? getCast(extractBaseType($type)) : '';
$referenceSign = isReference($type) ? '&' : '';
if($referenceSign) {
$cast = '';
}
$nullStart = isNullable($type) ? '[' : '';
$nullEnd = isNullable($type) ? ' = null] ' : '';
$nullDefault = isNullable($type) ? ' = null' : '';
$typeHint = '';
if(!isNative($type)) {
$namespace = dirname(extractBaseType($type));
if(strtolower(extractBaseType($type)) != 'array' && $namespace != '.' && $classNamespace != $namespace) {
$useStatements .= 'use ' . extractBaseType($type) . ';' . PHP_EOL;
}
$typeHint = basename(extractBaseType($type)) . ' ';
}
$assertion = cliFlagSet('a', false) && isNative($type) ? "assert('" . getValidator(extractBaseType($type)) . "(\$" . $property->getName() . ")');" . PHP_EOL . str_repeat(cliParameter('indentionString', "\t"), cliParameter('indention', 1) + 1) : '';
$source .= sprintf($getterMethodDocCommentTemplate, $name, $baseType);
$source .= sprintf($getterMethodTemplate, $getterName, $getterVisibility, $name, $referenceSign);
$source .= sprintf($setterMethodDocCommentTemplate, $name, $baseType, $classType, $referenceSign, $nullEnd, $nullStart);
$source .= sprintf($setterMethodTemplate, $setterName, $setterVisibility, $name, $referenceSign, $typeHint, $nullDefault, $assertion, $cast);
}
$source = $useStatements . PHP_EOL . $source;
if(cliFlagSet('f')) {
$template = cliParameter('template', '%1$s_generated.php');
file_put_contents(sprintf($template, extractBaseType($class, $classNamespace)), $source);
} elseif(class_exists('COM') && cliFlagSet('c')) {
try {
$wordCom = new COM('Word.Application');
$wordCom->Visible = false;
$wordCom->Documents->Add();
$wordCom->Selection->TypeText($source);
$wordCom->Selection->WholeStory();
$wordCom->Selection->Copy();
$wordCom->Quit(false);
if(cliFlagSet('s')) {
$message = 'Getters and setter copied to clipboard';
$title = 'Finished';
$scriptCom = new COM('WScript.Shell');
$scriptCom->Popup($message, 0, $title, 0);
}
} catch(Exception $x) {
try {
$wordCom->Quit(false);
} catch(Exception $x) {}
exit(5);
}
} else {
echo $source;
}
exit(0);
Harder
Profil
Korábbi hozzászólások (1)
A régi blogon érkezett hozzászólások archívuma. Új hozzászólást már nem lehet írni.
Ez a __get() __set() helyettesítés eléggé ki lett vesézve, bár biztosan tömör és száraz sokaknak, mégis többet ad, mint a legtöbb példa ;) thx
Van hozzáfűznivalód? Írj nekem közvetlenül.
Kapcsolat