PHP Ontwikkeling. Symfony Console Component - Tips & Trucs
Dit artikel is gemaakt met het doel om je de nuttigste en handigste tips en trucs over Symfony Console Development te laten zien.

De nieuwe versie van PHP staat voor de deur. Wat zijn de nieuwe implementaties waar je vanaf moet weten? Lees dit artikel om erachter te komen!
PHP 8.2 wordt binnenkort uitgebracht. Misschien wordt dit wel de versie die een upgrade naar PHP 8 voor iedereen aantrekkelijk maakt. Laten we het hebben over waar ontwikkelaars naar uit kunnen kijken met PHP 8.2 en bereiden we ons voor op de nieuwste versie. Maar laten we eerst even alle PHP versies en veranderingen door de jaren heen doornemen.
<?php
Klasse Gebruiker {
openbaar int $id;
openbare string $naam;
}
?>
<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
<?php
klasse A {}
klasse B breidt A uit {}
klasse Producent {
openbare functie methode(): A {}
}
klasse ChildProducer uitbreidt Producer {
openbare functie methode(): B {}
}
?>
<?php
$array['key'] ??= computeDefault();
// is ongeveer gelijk aan
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$fruits = ['appel', 'peer'];
$fruits = ['banaan', 'sinaasappel', ...$parts, 'watermeloen'];
// ['banaan', 'sinaasappel', 'appel', 'peer', 'watermeloen'];
?>
<?php
// Geeft een array terug die alle noodzakelijke toestanden van het object bevat.
publieke functie __serialize(): array;
// Herstelt de objectstatus van de gegeven gegevensarray.
openbare functie __unserialize(array $data): leeg;
?>
PHP 8.0 werd uitgebracht in november 2020 en biedt ons de beste functies tot nu toe:
htmlspecialchars($string, double_encode: false);
klasse BerichtenController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
publieke functie get($id) { /* ... */ }
}
klasse Punt {
publieke functie __construct(
openbare float $x = 0,0,
openbare float $y = 0,0,
openbare float $z = 0,0,
) {}
}
klasse Nummer {
publieke functie __construct(
privé int|float $number
) {}
}
nieuw getal('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Oh nee!",
8.0 => "Dit is wat ik verwachtte",
};
//> Dit is wat ik verwachtte
$country = $session?->user?->getAddress()?->country;
enum Status
{
case Concept;
geval Gepubliceerd;
case Gearchiveerd;
}
functie acceptStatus(Status $status) {...}
klasse BlogData
{
openbare alleen-lezen status $status;
publieke functie __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
Klasse Service
{
privé logger $logger;
openbare functie __construct(
Logger $logger = nieuwe NullLogger(),
) {
$this->logger = $logger;
}
}
functie count_and_iterate(Iterator&Countable $value) {
foreach ($value als $val) {
echo $val;
}
count($value);
}
$response = $httpClient->request('https://example.com/');
print json_decode($response->getBody()->buffer())['code'];
PHP 8.2 introduceert nog meer veranderingen die het leven van de ontwikkelaar makkelijker moeten maken en zijn werk nog meer moeten optimaliseren. Hieronder staat de lijst met nieuwe functies.
Een van de grootste verbeteringen in de nieuwe versie van PHP is de mogelijkheid om direct een alleen-lezen
klasse. Een klasse die beschreven is met deze eigenschap zal dit automatisch propageren voor zijn variabelen. DTO klassen zien er nu netjes en schoon uit!
readonly klasse FactuurDTO
{
openbare functie __construct(
openbare UUID $uuid,
openbare $issuer,
public DateTime $issuedAt,
) {}
}
De tweede grote verandering is de deprecatie van dynamische variabelen in klassen. De volgende implementatie zal een deprecation gooien in PHP 8.2 en ErrorException
in toekomstige versie van PHP.
klasse Mijn gebruiker
{
public string $name;
}
(...)
$myUser->naam = 'Naam'; // OK
$myUser->achternaam = 'Achternaam'; // deprecated / foutmelding
Het is het vermelden waard dat klassen die __get
en __set
methoden en klassen die direct erven van stdClass
kan nog steeds magische methoden implementeren zonder obstakels.
Hier verwijs ik je ook naar een interessante discussie op GitHubwaar de ontwikkelaars van PHP-CS deze verandering bespreken en de noodzaak om hun populaire tool aan te passen voor de nieuwe versie van de taal.
Tot slot kun je dit gedrag uitschakelen via Annotatie.
#[AllowDynamicProperties]
klasse MyUser
{
openbare string $naam;
}
$myUser->achternaam = 'Achternaam'; // OK
nul
, Echt
en vals
Tot nu toe gaven functies die altijd een Echt
of vals
waarde moest worden beschreven met een bool
type.
functie alwaysTrue(): bool { return true; }
Vanaf nu kunnen we Echt
en vals
als eenvoudige types in de geretourneerde waarden van functies.
functie alwaysTrue(): true { return true; }
(DNF) is een standaard manier om booleaanse expressies te organiseren. Specifiek betekent het dat een booleaanse expressie gestructureerd wordt in een ORed reeks ANDs. Wanneer het toegepast wordt op type declaraties, biedt het een standaard manier om gecombineerde Union en Intersection types te schrijven die de parser kan verwerken.
Het is een grote verandering, omdat we nu bijvoorbeeld nullable intersection types kunnen hebben:
functie getFullName((HasName&HasSurname)|null $user) { ... }
Ik ben geen groot voorstander van het gebruik van Traits en zo'n verandering is voor mij puur cosmetisch, vooral omdat het je niet toestaat om Trait-waarden te gebruiken zonder het object te initialiseren.
kenmerk 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 'Heb vlag 1';
}
if ($flags & self::FLAG_2) {
echo 'Heb vlag 2';
}
if ($flags & self::FLAG_3) {
echo 'Heb vlag 3';
}
}
}
Een van de belangrijkste veranderingen waar ik naar uitkijk. In de nieuwste versie van PHP zullen we variabelen kunnen markeren als SensitiveParameterValue
. Waarom zouden we?
PHP's stack traces in excepties zijn erg handig voor het debuggen, echter, ze staan je toe om parameter waarden te bekijken. Stel bijvoorbeeld PDO code gebruikt om verbinding te maken met een database. De debugtrace zou er als volgt uitzien:
PDOException: SQLSTATE[HY000] [2002] Geen bestand of map aanwezig in /var/www/html/test.php:3
Stack trace:
#0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'wachtwoord')
#1 {main}
Na gebruik van Annotatie #[SensitiveParameter]
zal onze stack trace niet langer de waarde van de variabele tonen.
functie test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
gooi nieuw Uitzondering('Fout');
}
test('foo', 'bar', 'baz');
/*
Fatale fout: Uncaught Exception: Fout in test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
gegooid in test.php op regel 8
*/
Als auteur zegt
De primaire motivatie voor deze wijziging is om het ophalen van de naam en waarde eigenschappen toe te staan op plaatsen waar enum objecten niet zijn toegestaan, zoals array sleutels. We zouden aan arrays kunnen werken zodat ze kunnen worden uitgebreid om enums of alle objecten als sleutels toe te staan, maar het is eenvoudiger om toe te staan dat eigenschappen van enums worden opgehaald.
enum A: string {
geval B = 'B';
const C = [self::B->waarde => self::B];
}
Voorheen werkten statische methoden als volgt:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
In PHP 8.2 wordt het veranderd in:
DateTime::createFromImmutable(): statisch
DateTimeImmutable::createFromMutable(): statisch
Dit is een doorbrekende wijziging voor makers van bibliotheken en/of alle aangepaste implementaties van DateTime.
Dat waren twee functies die hun doel niet dienden, omdat ze alleen converteerden tussen ISO-8859-1
en UTF-8
. PHP Handleiding raadt aan om mb_converteer_codering
in plaats daarvan.
Locale gevoeligheid wordt het best beschreven door de auteur van de RFC:
Voorafgaand aan PHP 8.0, werd de locale van PHP ingesteld vanuit de omgeving. Wanneer een gebruiker Linux installeert, wordt er gevraagd in welke taal je het wilt hebben. De gebruiker kan zich niet volledig bewust van de gevolgen van deze beslissing. Het stelt niet alleen de taal van de gebruikersinterface in voor ingebouwde commando's, het verandert ook de manier waarop tekenreeksen in de C bibliotheek worden afgehandeld. Een gebruiker die bijvoorbeeld "Turks" selecteert bij het installeren van Linux, zou merken dat applicaties die toupper('i') aanroepen de gestippelde hoofdletter I (U+0130, "İ") krijgen.
In een tijdperk van gestandaardiseerde tekstgebaseerde protocollen is natuurlijke taal een minderheidstoepassing voor casusconversie. Maar zelfs als de gebruiker hoofdletterconversie in natuurlijke taal zou willen, zou hij waarschijnlijk geen succes hebben met strtolower(). Dit komt omdat het de string één byte per keer verwerkt en elke byte doorgeeft aan tolower() van de C bibliotheek. Als de invoer UTF-8 is, veruit de populairste moderne keuze, dan zal strtolower() de string vervormen en typisch ongeldige UTF-8 als uitvoer produceren.
PHP 8.0 is gestopt met het respecteren van de locale omgevingsvariabelen. Dus de locale is altijd "C" tenzij de gebruiker expliciet setlocale() aanroept. Dit betekent dat het grootste deel van de achterwaarts compatibele verandering al achter ons ligt. Alle toepassingen die afhankelijk zijn van de systeemlocale voor het omzetten van oude 8-bits tekensets naar hoofdletters, zijn op PHP 8.0 kapot.
Dit betekent dat alle onderstaande functies ASCII case conversie doen vanaf PHP.8.2:strtolower
, strtoupper
, stristr
, stripos
, strripos
, lcfirst
, ucfirst
, uc-woorden
, str_ireplace
We hebben veel manieren om variabelen in te sluiten in strings in PHP:
- Variabelen direct insluiten ("$foo")
- accolades buiten de variabele ("{$foo}")
- accolades na het dollarteken ("${foo}")
- Variabele variabelen ("${expr}", gelijk aan (string) ${expr})
Om verwarring en misbruik te voorkomen zullen deze niet meer werken:
"Hallo ${wereld}";
Afgeschreven: Het gebruik van ${} in strings is deprecated
"Hallo ${(wereld)}";
Afgeschreven: Het gebruik van ${} (variabele variabelen) in strings is afgeschreven
Dit zijn niet alle veranderingen die PHP 8.2 ons zal bieden. Helaas hebben we nog steeds geen ondersteuning voor generieke types, volgens wat Nikita zei zouden monomorf generieke types te veel prestatie-overhead toevoegen, en gereïficeerde generieke types vereisen veel wijzigingen in de hele codebase. Wat wel opvalt is de discipline en visie van de product. De veranderingen in de opeenvolgende versies van de taal worden steeds duidelijker, en geïnteresseerden zullen merken dat PHP gaat de goede kant op, zowel op het gebied van syntaxisvereenvoudiging als ondersteuning voor nieuwigheden. Ik verwacht dat we volgend jaar al het volgende zullen zien opvraagbaar
als een geldig type.