PHP Ανάπτυξη. Symfony Console Component - Συμβουλές και κόλπα
Αυτό το άρθρο δημιουργήθηκε με σκοπό να σας δείξει τις πιο χρήσιμες και ανακτήσιμες συμβουλές και κόλπα σχετικά με την ανάπτυξη της κονσόλας Symfony.

Η νέα έκδοση του PHP είναι προ των πυλών. Ποιες είναι οι νέες υλοποιήσεις που πρέπει να γνωρίζετε; Διαβάστε αυτό το άρθρο για να μάθετε!
PHP 8.2 πρόκειται να κυκλοφορήσει. Ίσως είναι η έκδοση που θα κάνει την αναβάθμιση σε PHP 8 να φαίνεται ελκυστική σε όλους. Ας μιλήσουμε για το τι μπορούν να περιμένουν οι προγραμματιστές με το PHP 8.2 και προετοιμαστείτε για την τελευταία του έκδοση. Αλλά πρώτα, ας δούμε γρήγορα όλες τις εκδόσεις και τις αλλαγές του PHP με την πάροδο των ετών.
<?php
class User {
public int $id,
public string $name,
}
?>
<?php
$factor = 10,
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]),
// $nums = array(10, 20, 30, 40),
?>
<?php
class A {}
class B extends A {}
class Producer {
public function method(): A {}
}
class ChildProducer extends Producer {
public function method(): B {}
}
?>
<?php
$array['key'] ??= computeDefault(),
// είναι περίπου ισοδύναμο με
if (!isset($array['key'])) {
$array['key'] = computeDefault(),
}
?>
<?php
$parts = ['apple', 'pear'],
$fruits = ['μπανάνα', 'πορτοκάλι', ...$parts, 'καρπούζι'],
// ['banana', 'orange', 'apple', 'pear', 'watermelon'],
?>
<?php
// Επιστρέφει πίνακα που περιέχει όλη την απαραίτητη κατάσταση του αντικειμένου.
public function __serialize(): array,
// Επαναφέρει την κατάσταση του αντικειμένου από τον δεδομένο πίνακα δεδομένων.
public function __unserialize(array $data): void,
?>
Το PHP 8.0 κυκλοφόρησε τον Νοέμβριο του 2020 και μας έφερε τα καλύτερα χαρακτηριστικά, τα οποία περιλαμβάνουν:
htmlspecialchars($string, double_encode: false);
class PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
class Σημείο {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
κλάση Number {
public function __construct(
private int|float $number
) {}
}
new Number('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Ωχ, όχι!",
8.0 => "Αυτό περίμενα",
};
//> Αυτό περίμενα
$country = $session?->user?->getAddress()?->country,
enum Κατάσταση
{
case Draft,
case Published,
case Αρχειοθετημένο,
}
function acceptStatus(Status $status) {...}
class BlogData
{
public readonly Κατάσταση $status,
public function __construct(Κατάσταση $status)
{
$this->status = $status,
}
}
$foo = $this->foo(...),
$fn = strlen(...),
κατηγορία Υπηρεσία
{
private Logger $logger,
public function __construct(
Logger $logger = new NullLogger(),
) {
$this->logger = $logger,
}
}
function count_and_iterate(Iterator&Countable $value) {
foreach ($value as $val) {
echo $val,
}
count($value),
}
$response = $httpClient->request('https://example.com/'),
print json_decode($response->getBody()->buffer())['code'],
PHP 8.2 εισάγει περαιτέρω αλλαγές που αποσκοπούν στο να κάνουν τη ζωή του προγραμματιστή ευκολότερη και να βελτιστοποιήσουν ακόμη περισσότερο το έργο του. Ακολουθεί ο κατάλογος των νέων χαρακτηριστικών.
Μία από τις μεγαλύτερες βελτιώσεις στη νέα έκδοση του PHP είναι η δυνατότητα άμεσης δημιουργίας ενός readonly
κατηγορία. Μια κλάση που περιγράφεται με αυτό το χαρακτηριστικό θα το διαδώσει αυτόματα για τις μεταβλητές της. Οι κλάσεις DTO θα φαίνονται τώρα τακτοποιημένες και καθαρές!
readonly class InvoiceDTO
{
public function __construct(
public UUID $uuid,
public Issuer $issuer,
public DateTime $issuedAt,
) {}
}
Η δεύτερη τεράστια αλλαγή είναι η κατάργηση των δυναμικών μεταβλητών στις κλάσεις. Η ακόλουθη υλοποίηση θα πετάξει μια κατάπτωση στην PHP 8.2 και ErrorException
στη μελλοντική έκδοση του PHP.
class MyUser
{
public string $name,
}
(...)
$myUser->name = 'Όνομα'; // OK
$myUser->surname = 'Επώνυμο'; // deprecated / errorexception
Αξίζει να αναφερθεί ότι οι κλάσεις που εφαρμόζουν __get
και __set
μεθόδους και κλάσεις που κληρονομούν απευθείας από stdClass
μπορούν ακόμα να εφαρμόσουν μαγικές μεθόδους χωρίς εμπόδια.
Εδώ σας παραπέμπω επίσης σε ένα ενδιαφέρον νήμα στο GitHub, όπου οι προγραμματιστές του PHP-CS συζητούν αυτή την αλλαγή και την ανάγκη τροποποίησης του δημοφιλούς εργαλείου τους για τη νέα έκδοση της γλώσσας.
Τέλος, μπορείτε να απενεργοποιήσετε αυτή τη συμπεριφορά μέσω του Annotation.
#[AllowDynamicProperties]
class MyUser
{
public string $name,
}
$myUser->surname = 'Επίθετο'; // OK
null
, true
, και false
Μέχρι τώρα, οι συναρτήσεις που επέστρεφαν πάντα ένα true
ή false
τιμή έπρεπε να περιγραφεί με ένα bool
τύπου.
function alwaysTrue(): bool { return true; }
Από τώρα και στο εξής, μπορούμε να χρησιμοποιήσουμε true
και false
ως απλοί τύποι στις επιστρεφόμενες τιμές των συναρτήσεων.
function alwaysTrue(): true { return true; }
(DNF) είναι ένας τυπικός τρόπος οργάνωσης των εκφράσεων boolean. Συγκεκριμένα, σημαίνει τη δόμηση μιας έκφρασης boolean σε μια ORed σειρά από ANDs. Όταν εφαρμόζεται σε δηλώσεις τύπων, επιτρέπει έναν τυπικό τρόπο για τη σύνταξη συνδυασμένων τύπων Ένωσης και Διασταύρωσης που μπορεί να χειριστεί ο αναλυτής.
Είναι μια μεγάλη αλλαγή, καθώς τώρα μπορούμε να έχουμε μηδενιζόμενους τύπους διασταύρωσης, για παράδειγμα:
function getFullName((HasName&HasSurname)|null $user) { ... }
Δεν είμαι μεγάλος υποστηρικτής της χρήσης των Traits και μια τέτοια αλλαγή είναι καθαρά αισθητική για μένα, ειδικά από τη στιγμή που δεν σας επιτρέπει να χρησιμοποιήσετε τιμές Trait χωρίς να αρχικοποιήσετε το αντικείμενο.
χαρακτηριστικό Foo {
public const FLAG_1 = 1,
protected const FLAG_2 = 2,
private const FLAG_3 = 2,
public function doFoo(int $flags): void {
if ($flags & self::FLAG_1) {
echo 'Got flag 1',
}
if ($flags & self::FLAG_2) {
echo 'Got flag 2',
}
if ($flags & self::FLAG_3) {
echo 'Got flag 3',
}
}
}
Μια από τις πιο σημαντικές αλλαγές που περιμένω με ανυπομονησία. Στην τελευταία έκδοση του PHP θα μπορούμε να χαρακτηρίζουμε τις μεταβλητές ως SensitiveParameterValue
. Γιατί να το κάνουμε;
Τα ίχνη στοίβας του PHP στις εξαιρέσεις είναι πολύ χρήσιμα για την αποσφαλμάτωση, ωστόσο, σας επιτρέπουν να κάνετε προεπισκόπηση των τιμών των παραμέτρων. Για παράδειγμα, ας φανταστούμε ότι η PDO κωδικός που χρησιμοποιείται για τη σύνδεση σε μια βάση δεδομένων. Το ίχνος εντοπισμού σφαλμάτων θα έχει την ακόλουθη μορφή:
PDOException: SQLSTATE[HY000] [2002] No such file or directory in /var/www/html/test.php:3
Παρακολούθηση στοίβας:
#0 /var/www/html/test.php(3): ...', 'root', 'password')
#1 {main}
Μετά τη χρήση Annotation #[SensitiveParameter]
το ίχνος στοίβας δεν θα δείχνει πλέον την τιμή της μεταβλητής.
function test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
throw new Exception('Error'),
}
test('foo', 'bar', 'baz'),
/*
Μοιραίο σφάλμα: Uncaught Exception: test.php:8
Παρακολούθηση στοίβας:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
thrown in test.php on line 8
*/
Όπως ο συγγραφέας λέει
, το κύριο κίνητρο για αυτή την αλλαγή είναι να επιτραπεί η ανάκτηση των ιδιοτήτων name και value σε θέσεις όπου δεν επιτρέπονται τα αντικείμενα enum, όπως τα κλειδιά του πίνακα. Θα μπορούσαμε να δουλέψουμε πάνω στους πίνακες ώστε να μπορούν να επεκταθούν ώστε να επιτρέπουν enums ή όλα τα αντικείμενα ως κλειδιά, αλλά το να επιτρέπουμε την ανάκτηση ιδιοτήτων των enums είναι απλούστερο.
enum A: string {
case B = 'B',
const C = [self::B->value => self::B],
}
Προηγουμένως οι στατικές μέθοδοι λειτουργούσαν ως εξής:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
Στο PHP 8.2 θα αλλάξει σε:
DateTime::createFromImmutable(): static
DateTimeImmutable::createFromMutable(): static
Αυτή είναι μια σημαντική αλλαγή για τους δημιουργούς βιβλιοθηκών και/ή για όλες τις προσαρμοσμένες υλοποιήσεις της DateTime.
Αυτές ήταν δύο λειτουργίες που δεν εξυπηρετούσαν τον σκοπό τους, καθώς μετατρέπονταν μόνο μεταξύ ISO-8859-1
και UTF-8
. Το εγχειρίδιο PHP προτείνει τη χρήση mb_convert_encoding
αντί.
Η ευαισθησία της τοπικής γλώσσας περιγράφεται καλύτερα από τον συντάκτη του RFC:
Πριν από το PHP 8.0, η τοπική γλώσσα του PHP οριζόταν από το περιβάλλον. Όταν ένας χρήστης εγκαθιστά το Linux, ρωτάει σε ποια γλώσσα θέλετε να είναι. Ο χρήστης μπορεί να μην εκτιμήσει πλήρως τις συνέπειες αυτής της απόφασης. Δεν ορίζει μόνο τη γλώσσα του περιβάλλοντος χρήστη για τις ενσωματωμένες εντολές, αλλά αλλάζει επίσης διάχυτα τον τρόπο με τον οποίο λειτουργεί ο χειρισμός συμβολοσειρών στη βιβλιοθήκη C. Για παράδειγμα, ένας χρήστης που επιλέγει "Turkish" κατά την εγκατάσταση του Linux θα διαπιστώσει ότι οι εφαρμογές που καλούν την toupper('i') θα λαμβάνουν το κεφαλαίο I με τελείες (U+0130, "İ").
Σε μια εποχή τυποποιημένων πρωτοκόλλων βασισμένων σε κείμενο, η φυσική γλώσσα αποτελεί μειοψηφική εφαρμογή για τη μετατροπή περιπτώσεων. Αλλά ακόμη και αν ο χρήστης ήθελε μετατροπή των κεφαλαίων σε φυσική γλώσσα, θα ήταν απίθανο να επιτύχει με την strtolower(). Αυτό συμβαίνει επειδή επεξεργάζεται το αλφαριθμητικό ένα byte τη φορά, τροφοδοτώντας κάθε byte στην tolower() της βιβλιοθήκης της C. Αν η είσοδος είναι UTF-8, μακράν η πιο δημοφιλής σύγχρονη επιλογή, η strtolower() θα παραποιήσει τη συμβολοσειρά, παράγοντας συνήθως άκυρο UTF-8 ως έξοδο.
Το PHP 8.0 σταμάτησε να σέβεται τις μεταβλητές περιβάλλοντος locale. Έτσι, η τοπική γλώσσα είναι πάντα "C", εκτός αν ο χρήστης καλέσει ρητά την setlocale(). Αυτό σημαίνει ότι ο κύριος όγκος της αλλαγής προς τα πίσω συμβατότητας είναι ήδη πίσω μας. Οποιεσδήποτε εφαρμογές που εξαρτώνται από την τοπική γλώσσα του συστήματος για να κάνουν μετατροπή των πεζών χαρακτήρων των παλαιών συνόλων χαρακτήρων των 8-bit θα είχαν καταστραφεί από το PHP 8.0.
Αυτό σημαίνει ότι όλες οι παρακάτω λειτουργίες θα κάνουν μετατροπή της πεζότητας ASCII από το PHP.8.2:strtolower
, strtoupper
, stristr
, stripos
, strripos
, lcfirst
, ucfirst
, ucwords
, str_ireplace
Έχουμε πολλούς τρόπους ενσωμάτωσης μεταβλητών σε συμβολοσειρές στο PHP:
- Άμεση ενσωμάτωση μεταβλητών ("$foo")
- Αγκύλες εκτός της μεταβλητής ("{$foo}")
- Αγκύλες μετά το σύμβολο του δολαρίου ("${foo}")
- Μεταβλητές μεταβλητές ("${expr}", ισοδύναμο με (συμβολοσειρά) ${expr})
Για να αποφευχθεί η σύγχυση και η κατάχρηση, αυτά δεν θα λειτουργούν πλέον:
"Γεια σας ${world}",
Deprecated: Η χρήση ${} σε συμβολοσειρές έχει ξεπεραστεί.
"Hello ${(world)}",
Deprecated: Η χρήση ${} (μεταβλητές μεταβλητές) σε συμβολοσειρές έχει καταργηθεί.
Αυτές δεν είναι όλες οι αλλαγές που PHP 8.2 θα μας προσφέρει. Δυστυχώς, ακόμα δεν έχουμε υποστήριξη για γενικούς τύπους, σύμφωνα με όσα είπε ο Nikita, οι μονομορφικές γενικές θα προσθέσουν πολύ μεγάλο κόστος απόδοσης, και οι επαναπροσδιορισμένες γενικές απαιτούν πολλές αλλαγές σε ολόκληρη την κωδικοποιημένη βάση. Αυτό που είναι αξιοσημείωτο, ωστόσο, είναι η πειθαρχία και το όραμα του προϊόν. Οι αλλαγές που εισάγονται στις διαδοχικές εκδόσεις της γλώσσας γίνονται όλο και πιο σαφείς και οι ενδιαφερόμενοι θα παρατηρήσουν ότι PHP κινείται προς τη σωστή κατεύθυνση τόσο στον τομέα της απλοποίησης του συντακτικού όσο και της υποστήριξης των καινοτομιών. Αναμένω ότι ήδη από το επόμενο έτος θα δούμε callable
ως έγκυρος τύπος.