Γεννήτρια κώδικα PHP

Ψάχνετε ένα εργαλείο για τη δημιουργία κώδικα PHP για κλάσεις, συναρτήσεις ή πλήρη αρχεία;
  • Υποστηρίζει όλα τα τελευταία χαρακτηριστικά της PHP (όπως αγκίστρια ιδιοτήτων, enums, attributes, κ.λπ.)
  • Σας επιτρέπει να τροποποιείτε εύκολα τις υπάρχουσες κλάσεις
  • Έξοδος συμβατή με το στυλ κωδικοποίησης PSR-12 / PER
  • Ώριμη, σταθερή και ευρέως χρησιμοποιούμενη βιβλιοθήκη

Εγκατάσταση

Κατεβάστε και εγκαταστήστε το πακέτο χρησιμοποιώντας το Composer:

composer require nette/php-generator

Για τη συμβατότητα με την PHP, δείτε τον πίνακα.

Κλάσεις

Ας ξεκινήσουμε με ένα απλό παράδειγμα δημιουργίας κλάσης με τη χρήση του ClassType:

$class = new Nette\PhpGenerator\ClassType('Demo');

$class
	->setFinal()
	->setExtends(ParentClass::class)
	->addImplement(Countable::class)
	->addComment("Description of class.\nSecond line\n")
	->addComment('@property-read Nette\Forms\Form $form');

// για να δημιουργήσετε κώδικα PHP, απλά μετατρέψτε τον σε συμβολοσειρά ή χρησιμοποιήστε το echo:
echo $class;

Θα αποδώσει αυτό το αποτέλεσμα:

/**
 * Description of class.
 * Second line
 *
 * @property-read Nette\Forms\Form $form
 */
final class Demo extends ParentClass implements Countable
{
}

τον οποίο, σε αντίθεση με το echo $class, θα μπορούμε να διαμορφώσουμε περαιτέρω:

$printer = new Nette\PhpGenerator\Printer;
echo $printer->printClass($class);

Μπορούμε να προσθέσουμε σταθερές (κλάση Constant) και ιδιότητες (κλάση Property):

$class->addConstant('ID', 123)
	->setProtected() // σταθερή ορατότητα
	->setType('int')
	->setFinal();

$class->addProperty('items', [1, 2, 3])
	->setPrivate() // ή setVisibility('private')
	->setStatic()
	->addComment('@var int[]');

$class->addProperty('list')
	->setType('?array')
	->setInitialized(); // εκτυπώνει '= null'

Δημιουργεί:

final protected const int ID = 123,

/** @var int[] */
private static $items = [1, 2, 3];

public ?array $list = null;

Και μπορούμε να προσθέσουμε μεθόδους:

$method = $class->addMethod('count')
	->addComment('Count it.')
	->setFinal()
	->setProtected()
	->setReturnType('?int') // τύπος επιστροφής της μεθόδου
	->setBody('return count($items ?: $this->items);');

$method->addParameter('items', []) // $items = []
	->setReference()           // &$items = []
	->setType('array');        // array &$items = []

Αυτό έχει ως αποτέλεσμα:

/**
 * Count it.
 */
final protected function count(array &$items = []): ?int
{
	return count($items ?: $this->items);
}

Οι προωθημένες παράμετροι που εισήχθησαν από την PHP 8.0 μπορούν να περάσουν στον κατασκευαστή:

$method = $class->addMethod('__construct');
$method->addPromotedParameter('name');
$method->addPromotedParameter('args', [])
	->setPrivate();

Αυτό έχει ως αποτέλεσμα:

public function __construct(
	public $name,
	private $args = [],
) {
}

Οι ιδιότητες και οι κλάσεις που είναι μόνο για ανάγνωση μπορούν να επισημανθούν μέσω της διεύθυνσης setReadOnly().


Αν η προστιθέμενη ιδιότητα, σταθερά, μέθοδος ή παράμετρος υπάρχει ήδη, τότε θα εκπέμψει εξαίρεση.

Τα μέλη μπορούν να αφαιρεθούν με τη χρήση removeProperty(), removeConstant(), removeMethod() ή removeParameter().

Μπορείτε επίσης να προσθέσετε υπάρχοντα αντικείμενα Method, Property ή Constant στην κλάση:

$method = new Nette\PhpGenerator\Method('getHandle');
$property = new Nette\PhpGenerator\Property('handle');
$const = new Nette\PhpGenerator\Constant('ROLE');

$class = (new Nette\PhpGenerator\ClassType('Demo'))
	->addMember($method)
	->addMember($property)
	->addMember($const);

Μπορείτε να κλωνοποιήσετε υπάρχουσες μεθόδους, ιδιότητες και σταθερές με διαφορετικό όνομα χρησιμοποιώντας το cloneWithName():

$methodCount = $class->getMethod('count');
$methodRecount = $methodCount->cloneWithName('recount');
$class->addMember($methodRecount);

Διεπαφή ή γνώρισμα

Μπορείτε να δημιουργήσετε διασυνδέσεις και γνωρίσματα (κλάσεις InterfaceType και TraitType):

$interface = new Nette\PhpGenerator\InterfaceType('MyInterface');
$trait = new Nette\PhpGenerator\TraitType('MyTrait');

Χρήση γνωρισμάτων:

$class = new Nette\PhpGenerator\ClassType('Demo');
$class->addTrait('SmartObject');
$class->addTrait('MyTrait')
	->addResolution('sayHello as protected')
	->addComment('@use MyTrait<Foo>');
echo $class;

Αποτέλεσμα:

class Demo
{
	use SmartObject;
	/** @use MyTrait<Foo> */
	use MyTrait {
		sayHello as protected;
	}
}

Enums

Μπορείτε εύκολα να δημιουργήσετε τα enums που φέρνει η PHP 8.1 (κλάση EnumType):

$enum = new Nette\PhpGenerator\EnumType('Suit');
$enum->addCase('Clubs');
$enum->addCase('Diamonds');
$enum->addCase('Hearts');
$enum->addCase('Spades');

echo $enum;

Αποτέλεσμα:

enum Suit
{
	case Clubs;
	case Diamonds;
	case Hearts;
	case Spades;
}

Μπορείτε επίσης να ορίσετε κλιμακωτά ισοδύναμα για τις περιπτώσεις για να δημιουργήσετε ένα υποστηριζόμενο enum:

$enum->addCase('Clubs', '♣');
$enum->addCase('Diamonds', '♦');

Είναι δυνατόν να προσθέσετε ένα σχόλιο ή χαρακτηριστικά σε κάθε περίπτωση χρησιμοποιώντας το addComment() ή το addAttribute().

Ανώνυμη κλάση

Δώστε το όνομα null και έχετε μια ανώνυμη κλάση:

$class = new Nette\PhpGenerator\ClassType(null);
$class->addMethod('__construct')
	->addParameter('foo');

echo '$obj = new class ($val) ' . $class . ';';

Αποτέλεσμα:

$obj = new class ($val) {

	public function __construct($foo)
	{
	}
};

Παγκόσμια Λειτουργία

Ο κώδικας των συναρτήσεων θα δημιουργήσει την κλάση GlobalFunction:

$function = new Nette\PhpGenerator\GlobalFunction('foo');
$function->setBody('return $a + $b;');
$function->addParameter('a');
$function->addParameter('b');
echo $function;

// ή χρησιμοποιήστε το PsrPrinter για έξοδο που συμμορφώνεται με PSR-2 / PSR-12 / PER
// echo (new Nette\PhpGenerator\PsrPrinter)->printFunction($function);

Αποτέλεσμα:

function foo($a, $b)
{
	return $a + $b;
}

Κλείσιμο

Ο κώδικας των closures θα δημιουργήσει την κλάση Closure:

$closure = new Nette\PhpGenerator\Closure;
$closure->setBody('return $a + $b;');
$closure->addParameter('a');
$closure->addParameter('b');
$closure->addUse('c')
	->setReference();
echo $closure;

// ή χρησιμοποιήστε το PsrPrinter για έξοδο που συμμορφώνεται με PSR-2 / PSR-12 / PER
// echo (new Nette\PhpGenerator\PsrPrinter)->printClosure($closure);

Αποτέλεσμα:

function ($a, $b) use (&$c) {
	return $a + $b;
}

Βέλος Συνάρτηση

Μπορείτε επίσης να εκτυπώσετε το κλείσιμο ως λειτουργία βέλους χρησιμοποιώντας εκτυπωτή:

$closure = new Nette\PhpGenerator\Closure;
$closure->setBody('$a + $b');
$closure->addParameter('a');
$closure->addParameter('b');

echo (new Nette\PhpGenerator\Printer)->printArrowFunction($closure);

Αποτέλεσμα:

fn($a, $b) => $a + $b

Υπογραφή μεθόδου και συνάρτησης

Οι μέθοδοι αντιπροσωπεύονται από την κλάση Method. Μπορείτε να ορίσετε την ορατότητα, την τιμή επιστροφής, να προσθέσετε σχόλια, χαρακτηριστικά κ.λπ:

$method = $class->addMethod('count')
	->addComment('Count it.')
	->setFinal()
	->setProtected()
	->setReturnType('?int');

Κάθε παράμετρος αναπαρίσταται από μια κλάση Parameter. Και πάλι, μπορείτε να ορίσετε κάθε δυνατή ιδιότητα:

$method->addParameter('items', []) // $items = []
	->setReference() // &$items = []
	->setType('array'); // array &$items = []

// function count(&$items = [])

Για να ορίσετε τις λεγόμενες παραμέτρους variadics (ή επίσης τον τελεστή splat, spread, ellipsis, unpacking ή three dots), χρησιμοποιήστε setVariadic():

$method = $class->addMethod('count');
$method->setVariadic(true);
$method->addParameter('items');

Generates:

function count(...$items)
{
}

Σώμα μεθόδου και συνάρτησης

Το σώμα μπορεί να περάσει στη μέθοδο setBody() αμέσως ή διαδοχικά (γραμμή προς γραμμή) καλώντας επανειλημμένα τη μέθοδο addBody():

$function = new Nette\PhpGenerator\GlobalFunction('foo');
$function->addBody('$a = rand(10, 20);');
$function->addBody('return $a;');
echo $function;

Αποτέλεσµα

function foo()
{
	$a = rand(10, 20);
	return $a;
}

Μπορείτε να χρησιμοποιήσετε ειδικά placeholders για εύχρηστο τρόπο εισαγωγής μεταβλητών.

Απλά πλαίσια θέσης ?

$str = 'any string';
$num = 3;
$function = new Nette\PhpGenerator\GlobalFunction('foo');
$function->addBody('return substr(?, ?);', [$str, $num]);
echo $function;

Αποτέλεσμα:

function foo()
{
	return substr('any string', 3);
}

Variadic placeholder ...?

$items = [1, 2, 3];
$function = new Nette\PhpGenerator\GlobalFunction('foo');
$function->setBody('myfunc(...?);', [$items]);
echo $function;

Αποτέλεσμα:

function foo()
{
	myfunc(1, 2, 3);
}

Μπορείτε επίσης να χρησιμοποιήσετε ονομαστικές παραμέτρους PHP 8 χρησιμοποιώντας placeholder ...?:

$items = ['foo' => 1, 'bar' => true];
$function->setBody('myfunc(...?:);', [$items]);

// myfunc(foo: 1, bar: true);

Αποφύγετε το placeholder χρησιμοποιώντας slash \?

$num = 3;
$function = new Nette\PhpGenerator\GlobalFunction('foo');
$function->addParameter('a');
$function->addBody('return $a \? 10 : ?;', [$num]);
echo $function;

Αποτέλεσμα:

function foo($a)
{
	return $a ? 10 : 3;
}

Εκτυπωτές και συμμόρφωση PSR

Η κλάση Printer χρησιμοποιείται για τη δημιουργία κώδικα PHP:

$class = new Nette\PhpGenerator\ClassType('Demo');
// ...

$printer = new Nette\PhpGenerator\Printer;
echo $printer->printClass($class); // το ίδιο όπως: echo $class

Μπορεί να παράγει κώδικα για όλα τα άλλα στοιχεία, προσφέροντας μεθόδους όπως printFunction(), printNamespace(), κ.λπ.

Επιπλέον, είναι διαθέσιμη η κλάση PsrPrinter, της οποίας η έξοδος είναι σύμφωνη με το στυλ κωδικοποίησης PSR-2 / PSR-12 / PER:

$printer = new Nette\PhpGenerator\PsrPrinter;
echo $printer->printClass($class);

Χρειάζεται να ρυθμίσετε τη συμπεριφορά σας ανάλογα με τις ανάγκες σας; Δημιουργήστε τον δικό σας εκτυπωτή κληρονομώντας την κλάση Printer. Μπορείτε να ρυθμίσετε εκ νέου αυτές τις μεταβλητές:

class MyPrinter extends Nette\PhpGenerator\Printer
{
	// μήκος της γραμμής μετά το οποίο θα γίνει η διακοπή της γραμμής
	public int $wrapLength = 120;
	// χαρακτήρας εσοχής, μπορεί να αντικατασταθεί με μια ακολουθία διαστημάτων
	public string $indentation = "\t";
	// αριθμός κενών γραμμών μεταξύ των ιδιοτήτων
	public int $linesBetweenProperties = 0;
	// αριθμός κενών γραμμών μεταξύ μεθόδων
	public int $linesBetweenMethods = 2;
	// αριθμός κενών γραμμών μεταξύ ομάδων δηλώσεων χρήσης για κλάσεις, συναρτήσεις και σταθερές
	public int $linesBetweenUseTypes = 0;
	// θέση της εισαγωγικής αγκύλης για συναρτήσεις και μεθόδους
	public bool $bracesOnNextLine = true;
	// τοποθέτηση μιας παραμέτρου σε μια γραμμή, ακόμη και αν έχει ένα χαρακτηριστικό ή αν προωθείται
	public bool $singleParameterOnOneLine = false;
	// omits namespaces that do not contain any class or function
	public bool $omitEmptyNamespaces = true;
	// διαχωριστικό μεταξύ της δεξιάς παρένθεσης και του τύπου επιστροφής των συναρτήσεων και των μεθόδων
	public string $returnTypeColon = ': ';
}

Πώς και γιατί ακριβώς διαφέρουν τα πρότυπα Printer και PsrPrinter; Γιατί δεν υπάρχει μόνο ένας εκτυπωτής, ο PsrPrinter, στο πακέτο;

Το πρότυπο Printer μορφοποιεί τον κώδικα όπως τον κάνουμε σε όλη τη Nette. Δεδομένου ότι η Nette δημιουργήθηκε πολύ νωρίτερα από το PSR, και επίσης επειδή το PSR για πολλά χρόνια δεν παρέδιδε τα πρότυπα εγκαίρως, αλλά μερικές φορές ακόμη και με καθυστέρηση αρκετών ετών από την εισαγωγή ενός νέου χαρακτηριστικού στην PHP, αυτό είχε ως αποτέλεσμα μερικές μικρές διαφορές στο πρότυπο κωδικοποίησης. Η μεγαλύτερη διαφορά είναι απλώς η χρήση των tabs αντί των κενών. Γνωρίζουμε ότι με τη χρήση tabs στα έργα μας επιτρέπουμε την προσαρμογή του πλάτους, κάτι που είναι απαραίτητο για τα άτομα με προβλήματα όρασης. Ένα παράδειγμα μιας μικρής διαφοράς είναι η τοποθέτηση της καμπύλης αγκύλης σε ξεχωριστή γραμμή για τις συναρτήσεις και τις μεθόδους και πάντα. Θεωρούμε ότι η σύσταση του PSR είναι παράλογη και οδηγεί σε μείωση της σαφήνειας του κώδικα.

Τύποι

Κάθε τύπος ή τύπος ένωσης/διασταύρωσης μπορεί να περάσει ως συμβολοσειρά, μπορείτε επίσης να χρησιμοποιήσετε προκαθορισμένες σταθερές για εγγενείς τύπους:

use Nette\PhpGenerator\Type;

$member->setType('array'); // ή Type::Array,
$member->setType('?array'); // or Type::nullable(Type::Array);
$member->setType('array|string'); // or Type::union(Type::Array, Type::String)
$member->setType('Foo&Bar'); // ή Type::intersection(Foo::class, Bar::class)
$member->setType(null); // αφαιρεί τον τύπο

Το ίδιο ισχύει και για τη μέθοδο setReturnType().

Κυριολεκτικά

Με το Literal μπορείτε να περάσετε αυθαίρετο κώδικα PHP, για παράδειγμα, σε προεπιλεγμένες τιμές ιδιοτήτων ή παραμέτρων κ.λπ:

use Nette\PhpGenerator\Literal;

$class = new Nette\PhpGenerator\ClassType('Demo');

$class->addProperty('foo', new Literal('Iterator::SELF_FIRST'));

$class->addMethod('bar')
	->addParameter('id', new Literal('1 + 2'));

echo $class;

Αποτέλεσμα:

class Demo
{
	public $foo = Iterator::SELF_FIRST;

	public function bar($id = 1 + 2)
	{
	}
}

Μπορείτε επίσης να περάσετε παραμέτρους στη διεύθυνση Literal και να τις μορφοποιήσετε σε έγκυρο κώδικα PHP χρησιμοποιώντας ειδικούς συμπαραστάτες:

new Literal('substr(?, ?)', [$a, $b]);
// παράγει, για παράδειγμα: substr('hello', 5);

Το λεκτικό που αντιπροσωπεύει τη δημιουργία ενός νέου αντικειμένου παράγεται εύκολα από τη μέθοδο new:

Literal::new(Demo::class, [$a, 'foo' => $b]);
// παράγει, για παράδειγμα: new Demo(10, foo: 20)

Χαρακτηριστικά

Μπορείτε να προσθέσετε χαρακτηριστικά της PHP 8 σε όλες τις κλάσεις, μεθόδους, ιδιότητες, σταθερές, περιπτώσεις enum, συναρτήσεις, κλεισίματα και παραμέτρους. Οι κυριολεκτικοί χαρακτήρες μπορούν επίσης να χρησιμοποιηθούν ως τιμές παραμέτρων.

$class = new Nette\PhpGenerator\ClassType('Demo');
$class->addAttribute('Table', [
	'name' => 'user',
	'constraints' => [
		Literal::new('UniqueConstraint', ['name' => 'ean', 'columns' => ['ean']]),
	],
]);

$class->addProperty('list')
	->addAttribute('Deprecated');

$method = $class->addMethod('count')
	->addAttribute('Foo\Cached', ['mode' => true]);

$method->addParameter('items')
	->addAttribute('Bar');

echo $class;

Αποτέλεσμα:

#[Table(name: 'user', constraints: [new UniqueConstraint(name: 'ean', columns: ['ean'])])]
class Demo
{
	#[Deprecated]
	public $list;


	#[Foo\Cached(mode: true)]
	public function count(
		#[Bar]
		$items,
	) {
	}
}

Άγκιστρα ιδιοκτησίας

Μπορείτε επίσης να ορίσετε άγκιστρα ιδιοτήτων (που αντιπροσωπεύονται από την κλάση PropertyHook) για λειτουργίες get και set, ένα χαρακτηριστικό που εισήχθη στην PHP 8.4:

$class = new Nette\PhpGenerator\ClassType('Demo');
$prop = $class->addProperty('firstName')
    ->setType('string');

$prop->addHook('set', 'strtolower($value)')
    ->addParameter('value')
	    ->setType('string');

$prop->addHook('get')
	->setBody('return ucfirst($this->firstName);');

echo $class;

Αυτό παράγει:

class Demo
{
    public string $firstName {
        set(string $value) => strtolower($value);
        get {
            return ucfirst($this->firstName);
        }
    }
}

Ιδιότητες και άγκιστρα ιδιοτήτων μπορούν να είναι αφηρημένες ή τελικές:

$class->addProperty('id')
    ->setType('int')
    ->addHook('get')
        ->setAbstract();

$class->addProperty('role')
    ->setType('string')
    ->addHook('set', 'strtolower($value)')
        ->setFinal();

Ασύμμετρη ορατότητα

Η PHP 8.4 εισάγει την ασύμμετρη ορατότητα για τις ιδιότητες. Μπορείτε να ορίσετε διαφορετικά επίπεδα πρόσβασης για ανάγνωση και εγγραφή.

Η ορατότητα μπορεί να οριστεί είτε χρησιμοποιώντας τη μέθοδο setVisibility() με δύο παραμέτρους, είτε χρησιμοποιώντας τις μεθόδους setPublic(), setProtected() ή setPrivate() με την παράμετρο mode που καθορίζει αν η ορατότητα ισχύει για τη λήψη ή τη ρύθμιση της ιδιότητας. Η προεπιλεγμένη λειτουργία είναι η 'get'.

$class = new Nette\PhpGenerator\ClassType('Demo');

$class->addProperty('name')
    ->setType('string')
    ->setVisibility('public', 'private'); // public for read, private for write

$class->addProperty('id')
    ->setType('int')
    ->setProtected('set'); // protected for write

echo $class;

Αυτό δημιουργεί:

class Demo
{
    public private(set) string $name;

    protected(set) int $id;
}

Χώρος ονομάτων

Οι κλάσεις, τα γνωρίσματα, οι διεπαφές και τα enums (εφεξής κλάσεις) μπορούν να ομαδοποιηθούν σε χώρους ονομάτων (PhpNamespace):

$namespace = new Nette\PhpGenerator\PhpNamespace('Foo');

// δημιουργία νέων κλάσεων στο χώρο ονομάτων
$class = $namespace->addClass('Task');
$interface = $namespace->addInterface('Countable');
$trait = $namespace->addTrait('NameAware');

// ή να εισαγάγετε μια υπάρχουσα κλάση στο χώρο ονομάτων
$class = new Nette\PhpGenerator\ClassType('Task');
$namespace->add($class);

Εάν η κλάση υπάρχει ήδη, πετάει εξαίρεση.

Μπορείτε να ορίσετε δηλώσεις χρήσης:

// use Http\Request;
$namespace->addUse(Http\Request::class);
// use Http\Request as HttpReq;
$namespace->addUse(Http\Request::class, 'HttpReq');
// use function iter\range;
$namespace->addUseFunction('iter\range');

Χρησιμοποιήστε τη μέθοδο simplifyName για να απλοποιήσετε ένα όνομα κλάσης, συνάρτησης ή σταθεράς με πλήρη προσόντα σύμφωνα με τα καθορισμένα ψευδώνυμα:

echo $namespace->simplifyName('Foo\Bar'); // 'Bar', επειδή το 'Foo' είναι ο τρέχων χώρος ονομάτων
echo $namespace->simplifyName('iter\range', $namespace::NameFunction); // 'range', λόγω του καθορισμένου use-statement

Αντίθετα, μπορείτε να μετατρέψετε ένα απλοποιημένο όνομα κλάσης, συνάρτησης ή σταθεράς σε όνομα με πλήρη προσόντα χρησιμοποιώντας τη μέθοδο resolveName:

echo $namespace->resolveName('Bar'); // 'Foo\Bar'
echo $namespace->resolveName('range', $namespace::NameFunction); // 'iter\range'

Επίλυση ονομάτων κλάσεων

Όταν μια κλάση είναι μέρος ενός χώρου ονομάτων, αποδίδεται ελαφρώς διαφορετικά: όλοι οι τύποι (π.χ. υποδείξεις τύπου, τύποι επιστροφής, όνομα γονικής κλάσης, υλοποιημένες διασυνδέσεις, χρησιμοποιούμενα γνωρίσματα και χαρακτηριστικά) επιλύονται αυτόματα (εκτός αν το απενεργοποιήσετε, δείτε παρακάτω). Αυτό σημαίνει ότι πρέπει να χρησιμοποιείτε πλήρως προσδιορισμένα ονόματα κλάσεων στους ορισμούς, και θα αντικατασταθούν με ψευδώνυμα (με βάση τις ρήτρες χρήσης) ή πλήρως προσδιορισμένα ονόματα στον κώδικα που θα προκύψει:

$namespace = new Nette\PhpGenerator\PhpNamespace('Foo');
$namespace->addUse('Bar\AliasedClass');

$class = $namespace->addClass('Demo');
$class->addImplement('Foo\A') // θα απλοποιηθεί σε A
	->addTrait('Bar\AliasedClass'); // θα απλοποιηθεί σε AliasedClass

$method = $class->addMethod('method');
$method->addComment('@return ' . $namespace->simplifyType('Foo\D')); // στα σχόλια απλοποιήστε χειροκίνητα
$method->addParameter('arg')
	->setType('Bar\OtherClass'); // θα επιλυθεί σε \Bar\OtherClass

echo $namespace;

// ή χρήση PsrPrinter για έξοδο σύμφωνη με PSR-2 / PSR-12 / PER
// echo (new Nette\PhpGenerator\PsrPrinter)->printNamespace($namespace);

Αποτέλεσμα:

namespace Foo;

use Bar\AliasedClass;

class Demo implements A
{
	use AliasedClass;

	/**
	 * @return D
	 */
	public function method(\Bar\OtherClass $arg)
	{
	}
}

Η αυτόματη ανάλυση μπορεί να απενεργοποιηθεί με αυτόν τον τρόπο:

$printer = new Nette\PhpGenerator\Printer; // ή PsrPrinter
$printer->setTypeResolving(false);
echo $printer->printNamespace($namespace);

PHP Files

Οι κλάσεις, οι συναρτήσεις και οι χώροι ονομάτων μπορούν να ομαδοποιηθούν σε αρχεία PHP που αντιπροσωπεύονται από την κλάση PhpFile:

$file = new Nette\PhpGenerator\PhpFile;
$file->addComment('This file is auto-generated.');
$file->setStrictTypes(); // προσθέτει declare(strict_types=1)

$class = $file->addClass('Foo\A');
$function = $file->addFunction('Foo\foo');

// ή
// $namespace = $file->addNamespace('Foo');
// $class = $namespace->addClass('A');
// $function = $namespace->addFunction('foo');

echo $file;

// ή χρήση του PsrPrinter για έξοδο σύμφωνη με PSR-2 / PSR-12 / PER
// echo (new Nette\PhpGenerator\PsrPrinter)->printFile($file);

Αποτέλεσμα:

<?php

/**
 * This file is auto-generated.
 */

declare(strict_types=1);

namespace Foo;

class A
{
}

function foo()
{
}

Παρακαλώ σημειώστε: Δεν μπορεί να προστεθεί πρόσθετος κώδικας στα αρχεία εκτός των συναρτήσεων και των κλάσεων.

Δημιουργία σύμφωνα με τις υπάρχουσες

Εκτός από τη δυνατότητα μοντελοποίησης κλάσεων και συναρτήσεων χρησιμοποιώντας το API που περιγράφηκε παραπάνω, μπορείτε επίσης να τις δημιουργήσετε αυτόματα με βάση τις υπάρχουσες:

// δημιουργεί μια κλάση πανομοιότυπη με την κλάση PDO
$class = Nette\PhpGenerator\ClassType::from(PDO::class);

// δημιουργεί μια συνάρτηση πανομοιότυπη με την trim()
$function = Nette\PhpGenerator\GlobalFunction::from('trim');

// δημιουργεί ένα κλείσιμο όπως ορίζεται
$closure = Nette\PhpGenerator\Closure::from(
	function (stdClass $a, $b = null) {},
);

Τα σώματα συναρτήσεων και μεθόδων είναι κενά από προεπιλογή. Αν θέλετε να τα φορτώσετε και αυτά, χρησιμοποιήστε αυτόν τον τρόπο (απαιτεί την εγκατάσταση του nikic/php-parser ):

$class = Nette\PhpGenerator\ClassType::from(Foo::class, withBodies: true);

$function = Nette\PhpGenerator\GlobalFunction::from('foo', withBody: true);

Φορτώνοντας από αρχείο PHP

Μπορείτε επίσης να φορτώσετε συναρτήσεις, κλάσεις, διεπαφές και enums απευθείας από μια συμβολοσειρά κώδικα PHP. Για παράδειγμα, δημιουργούμε το αντικείμενο ClassType με αυτόν τον τρόπο:

$class = Nette\PhpGenerator\ClassType::fromCode(<<<XX
	<?php

	class Demo
	{
		public $foo;
	}
	XX);

Όταν φορτώνετε κλάσεις από κώδικα PHP, τα σχόλια μιας γραμμής εκτός των σωμάτων των μεθόδων αγνοούνται (π.χ. για τις ιδιότητες κ.λπ.), επειδή αυτή η βιβλιοθήκη δεν διαθέτει API για να δουλέψει με αυτά.

Μπορείτε επίσης να φορτώσετε απευθείας ολόκληρο το αρχείο PHP, το οποίο μπορεί να περιέχει οποιονδήποτε αριθμό κλάσεων, συναρτήσεων ή ακόμα και πολλαπλά namespaces:

$file = Nette\PhpGenerator\PhpFile::fromCode(file_get_contents('classes.php'));

Το αρχικό σχόλιο του αρχείου και η δήλωση strict_types φορτώνονται επίσης. Από την άλλη πλευρά, όλος ο υπόλοιπος παγκόσμιος κώδικας αγνοείται.

Αυτό απαιτεί την εγκατάσταση του nikic/php-parser.

Αν πρέπει να χειριστείτε συνολικό κώδικα σε αρχεία ή μεμονωμένες εντολές σε σώματα μεθόδων, είναι προτιμότερο να χρησιμοποιήσετε απευθείας τη βιβλιοθήκη nikic/php-parser.

Χειριστής τάξης

Η κλάση ClassManipulator παρέχει εργαλεία για το χειρισμό κλάσεων.

$class = new Nette\PhpGenerator\ClassType('Demo');
$manipulator = new Nette\PhpGenerator\ClassManipulator($class);

Η μέθοδος inheritMethod() αντιγράφει μια μέθοδο από μια γονική κλάση ή μια διεπαφή που έχει υλοποιηθεί στην κλάση σας. Αυτό σας επιτρέπει να υπερεκτελείτε τη μέθοδο ή να επεκτείνετε την υπογραφή της:

$method = $manipulator->inheritMethod('bar');
$method->setBody('...');

Η μέθοδος inheritProperty() αντιγράφει μια ιδιότητα από μια γονική κλάση στην κλάση σας. Αυτό είναι χρήσιμο όταν θέλετε να έχετε την ίδια ιδιότητα στην κλάση σας, αλλά ενδεχομένως με διαφορετική προεπιλεγμένη τιμή:

$property = $manipulator->inheritProperty('foo');
$property->setValue('new value');

Η μέθοδος implement() υλοποιεί αυτόματα όλες τις μεθόδους και τις ιδιότητες της δεδομένης διεπαφής ή αφηρημένης κλάσης:

$manipulator->implement(SomeInterface::class),
// Τώρα η κλάση σας υλοποιεί το SomeInterface και περιλαμβάνει όλες τις μεθόδους του

Μεταβλητές Dumper

Ο Dumper επιστρέφει μια αναλύσιμη αναπαράσταση συμβολοσειράς PHP μιας μεταβλητής. Παρέχει καλύτερη και σαφέστερη έξοδο από την εγγενή συνάρτηση var_export().

$dumper = new Nette\PhpGenerator\Dumper;

$var = ['a', 'b', 123];

echo $dumper->dump($var); // εκτυπώνει ['a', 'b', 123]

Πίνακας συμβατότητας

Το PhpGenerator 4.1 είναι συμβατό με την PHP 8.0 έως 8.4.

έκδοση: 4.0