PHP udvikling. Symfony-konsolkomponent - tips og tricks
Denne artikel er lavet med det formål at vise dig de mest nyttige og nyttige tips og tricks om Symfony Console Development.
Den nye version af PHP er lige om hjørnet. Hvad er de nye implementeringer, du bør kende til? Tjek denne artikel for at finde ud af det!
PHP 8.2 er ved at blive frigivet. Måske bliver det den version, der får en opgradering til PHP 8 til at virke tiltrækkende for alle. Lad os tale om, hvad udviklere kan se frem til med PHP 8.2 og forberede sig på den nyeste version. Men lad os først hurtigt gennemgå alle PHP-versionerne og ændringerne gennem årene.
<?php
klasse Bruger {
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
klasse A {}
klasse B udvider A {}
klasse Producer {
offentlig funktion method(): A {}
}
class ChildProducer udvider Producer {
offentlig funktion method(): B {}
}
?>
<?php
$array['key'] ??= computeDefault();
// svarer nogenlunde til
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['æble', 'pære'];
$fruits = ['banan', 'appelsin', ...$parts, 'vandmelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>
<?php
// Returnerer et array, der indeholder alle de nødvendige oplysninger om objektet.
offentlig funktion __serialize(): array;
// Gendanner objektets tilstand fra det givne data-array.
public function __unserialize(array $data): void;
?>
PHP 8.0 blev udgivet i november 2020 og gav os de hidtil bedste funktioner, som inkluderer:
htmlspecialchars($string, double_encode: false);
klasse PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
klasse Punkt {
offentlig funktion __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
klasse Tal {
offentlig funktion __construct(
private int|float $number
) {}
}
new Number('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Åh nej!",
8.0 => "Det var det, jeg forventede",
};
//> Dette er, hvad jeg forventede
$country = $session?->user?->getAddress()?->country;
enum Status
{
case Udkast;
case Udgivet;
case Arkiveret;
}
function acceptStatus(Status $status) {...}
klasse BlogData
{
public readonly Status $status;
offentlig funktion __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
klasse Service
{
privat Logger $logger;
offentlig funktion __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 introducerer yderligere ændringer, der har til formål at gøre udviklerens liv lettere og optimere hans arbejde endnu mere. Nedenfor er listen over nye funktioner.
En af de største forbedringer i den nye version af PHP er muligheden for direkte at oprette en kun læsbar
klasse. En klasse, der er beskrevet med denne funktion, vil automatisk udbrede den til sine variabler. DTO-klasser vil nu se pæne og rene ud!
readonly klasse FakturaDTO
{
offentlig funktion __construct(
offentlig UUID $uuid,
public Udsteder 1TP60Udsteder,
public DateTime $issuedAt,
) {}
}
Den anden store ændring er udfasningen af dynamiske variabler i klasser. Følgende implementering vil kaste en deprecation i PHP 8.2 og FejlUdtagelse
i en fremtidig version af PHP.
klasse MyUser
{
public string $name;
}
(...)
$myUser->name = 'Navn'; // OK
$myUser->surname = 'Efternavn'; // deprecated / errorexception
Det er værd at nævne, at klasser, der implementerer __get
og __set
metoder og klasser, der direkte nedarver fra stdClass
kan stadig implementere magiske metoder uden forhindringer.
Her henviser jeg også til en interessant tråd på GitHub, hvor PHP-CS-udviklere diskuterer denne ændring og behovet for at ændre deres populære værktøj til den nye version af sproget.
Sidst, men ikke mindst, kan du deaktivere denne adfærd via Annotation.
#[AllowDynamicProperties]
klasse MyUser
{
public string $name;
}
$myUser->surname = 'Efternavn'; // OK
nul
, ægte
og falsk
Indtil nu har funktioner, der altid har returneret en ægte
eller falsk
værdi skulle beskrives med en bool
type.
function alwaysTrue(): bool { return true; }
Fra nu af kan vi bruge ægte
og falsk
som simple typer i de returnerede værdier af funktioner.
function alwaysTrue(): true { return true; }
(DNF) er en standard måde at organisere boolske udtryk på. Specifikt betyder det, at man strukturerer et boolsk udtryk i en OR-række af AND'er. Når det anvendes på typedeklarationer, giver det mulighed for en standard måde at skrive kombinerede Union- og Intersection-typer på, som parseren kan håndtere.
Det er en stor ændring, da vi nu f.eks. kan have nullable intersection-typer:
function getFullName((HasName&HasSurname)|null $user) { ... }
Jeg er ikke den store tilhænger af at bruge Traits, og sådan en ændring er rent kosmetisk for mig, især fordi den ikke giver mulighed for at bruge Trait-værdier uden at initialisere objektet.
trait Foo {
public const FLAG_1 = 1;
beskyttet const FLAG_2 = 2;
privat const FLAG_3 = 2;
public function doFoo(int $flags): void {
if ($flags & self::FLAG_1) {
echo 'Fik flag 1';
}
if ($flags & self::FLAG_2) {
echo 'Fik flag 2';
}
if ($flags & self::FLAG_3) {
echo 'Fik flag 3';
}
}
}
En af de vigtigste ændringer, jeg ser frem til. I den seneste version af PHP vil vi kunne markere variabler som FølsomParameterVærdi
. Hvorfor skulle vi det?
PHP's stakspor i undtagelser er meget nyttige til fejlfinding, men de giver dig mulighed for at få vist parameterværdier. Lad os for eksempel forestille os PDO Kode bruges til at oprette forbindelse til en database. Fejlfindingssporet ville se ud som følger:
PDOException: SQLSTATE[HY000] [2002] No such file or directory in /var/www/html/test.php:3
Stakspor:
#0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 {main}
Efter brug af Annotation #[SensitiveParameter]
vil vores stakspor ikke længere vise værdien af variablen.
funktion test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
smider en ny Exception('Fejl');
}
test('foo', 'bar', 'baz');
/*
Skæbnesvanger fejl: Uncaught Exception: Fejl i test.php:8
Stakspor:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
smidt i test.php på linje 8
*/
Som siger forfatteren
Den primære motivation for denne ændring er at gøre det muligt at hente navne- og værdiegenskaber på steder, hvor enum-objekter ikke er tilladt, som f.eks. array-nøgler. Vi kunne arbejde på arrays, så de kunne udvides til at tillade enum'er eller alle objekter som nøgler, men det er enklere at tillade hentning af enum'ers egenskaber.
enum A: string {
case B = 'B';
const C = [self::B->value => self::B];
}
Tidligere fungerede statiske metoder sådan her:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
I PHP 8.2 vil det blive ændret til:
DateTime::createFromImmutable(): statisk
DateTimeImmutable::createFromMutable(): statisk
Dette er en afgørende ændring for biblioteksskabere og/eller alle brugerdefinerede implementeringer af DateTime.
Det var to funktioner, der ikke tjente deres formål, da de kun konverterede mellem ISO-8859-1
og UTF-8
. PHP Manual foreslår at bruge mb_convert_encoding
i stedet.
Locale-følsomhed beskrives bedst af forfatteren af RFC'en:
Før PHP 8.0 blev PHP's locale indstillet fra miljøet. Når en bruger installerer Linux, spørger den, hvilket sprog den skal være på. Brugeren er måske ikke helt klar over konsekvenserne af denne beslutning. Det indstiller ikke kun brugergrænsefladesproget for indbyggede kommandoer, det ændrer også gennemgribende, hvordan strenghåndtering i C-biblioteket fungerer. For eksempel vil en bruger, der vælger "tyrkisk", når han installerer Linux, opdage, at programmer, der kalder toupper('i'), vil få det prikkede store I (U+0130, "İ").
I en tid med standardiserede tekstbaserede protokoller er naturligt sprog en minoritetsapplikation for konvertering af store og små bogstaver. Men selv hvis brugeren ønskede konvertering af store og små bogstaver på naturligt sprog, ville det være usandsynligt, at de ville få succes med strtolower(). Det skyldes, at den behandler strengen én byte ad gangen og sender hver byte til C-bibliotekets tolower(). Hvis input er UTF-8, som er langt det mest populære moderne valg, vil strtolower() maltraktere strengen og typisk producere ugyldig UTF-8 som output.
PHP 8.0 holdt op med at respektere locale-miljøvariablerne. Så locale er altid "C", medmindre brugeren udtrykkeligt kalder setlocale(). Det betyder, at størstedelen af den bagudkompatible ændring allerede er bag os. Alle programmer, der er afhængige af systemets locale til at konvertere store og små bogstaver i ældre 8-bit tegnsæt, ville være blevet ødelagt af PHP 8.0.
Det betyder, at alle nedenstående funktioner vil konvertere ASCII-kasus fra PHP.8.2:strtolower
, strtoupper
, stristr
, Stripoer
, strripos
, Første gang
, ucfirst
, uc-ord
, str_ireplace
Vi har mange måder at indlejre variabler i strenge på i PHP:
- Direkte indlejring af variabler ("$foo")
- Parenteser uden for variablen ("{$foo}")
- Parenteser efter dollartegnet ("${foo}")
- Variable variabler ("${expr}", svarende til (streng) ${expr})
For at undgå forvirring og misbrug fungerer de ikke længere:
"Hej ${verden}";
Forældet: Brug af ${} i strenge er forældet
"Hej ${(verden)}";
Forældet: Brug af ${} (variable variabler) i strenge er forældet
Dette er ikke alle de ændringer, der PHP 8.2 vil tilbyde os. Desværre fik vi stadig ikke understøttelse af generiske typer, for ifølge Nikita ville de monomorfiserede generiske typer tilføje for meget performance-overhead, og de reificerede generiske typer kræver mange ændringer på tværs af hele kodebasen. Hvad der dog er bemærkelsesværdigt, er disciplinen og visionen hos produkt. De ændringer, der er indført i de forskellige sprogversioner, bliver tydeligere, og de interesserede vil bemærke, at PHP bevæger sig i den rigtige retning både med hensyn til forenkling af syntaks og understøttelse af nyheder. Jeg forventer, at vi allerede næste år vil se kaldbar
som en gyldig type.