PHP Izstrāde. Symfony konsoles komponente - Padomi un triki
Šis raksts tika izveidots ar mērķi parādīt jums visnoderīgākos un noderīgākos padomus un trikus par Symfony Console izstrādi.
Jaunā PHP versija ir pavisam tuvu. Kādas ir jaunās implementācijas, par kurām jums būtu jāzina? Skatiet šo rakstu, lai to uzzinātu!
PHP 8.2 drīzumā tiks izdots. Iespējams, tā būs versija, kas padarīs PHP 8 atjauninājumu pievilcīgu ikvienam. Parunāsim par to, ko izstrādātāji var sagaidīt ar PHP 8.2 un sagatavoties tās jaunākajai versijai. Bet vispirms ātri aplūkosim visas PHP versijas un izmaiņas gadu gaitā.
<?php
klase Lietotājs {
public int $id;
public string $name;
}
?>
<?php
$faktors = 10;
$nums = array_map(fn($n) => $n * $faktors, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
<?php
klase A {}
klase B paplašina A {}
klase Producer {
public function method(): A {}
}
klase ChildProducer paplašina Producer {
public function method(): B {}
}
?>
<?php
$array['key'] ??= computeDefault();
// ir aptuveni līdzvērtīgs
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$daļas = ['ābols', 'bumbieri'];
$fruits = ['banāns', 'apelsīns', ...$daļas, 'arbūzs'];
// ['banāns', 'apelsīns', 'ābols', 'bumbieris', 'arbūzs'];
?>
<?php
// Atgriež masīvu, kas satur visu nepieciešamo objekta stāvokli.
public function __serialize(): array;
// Atjauno objekta stāvokli no dotā dati masīvs.
publiskā funkcija __unserialize(array $data): void;
?>
Izdots 2020. gada novembrī, PHP 8.0 nesa mums līdz šim labākās funkcijas, tostarp:
htmlspecialchars($string, double_encode: false);
klase PostsController
{
#[Route("/api/posts/{id}", metodes: ["GET"]])]
public function get($id) { /* ... */ }
}
klase Point {
publiskā funkcija __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
klase Number {
publiskā funkcija __construct(
private int|float $number
) {}
}
new Number('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Ak nē!",
8.0 => "Tas ir tas, ko es gaidīju",
};
//> Tas ir tas, ko es gaidīju
$country = $session?->user?->getAddress()?->country;
enum Statuss
{
case Draft;
case Publicēts;
gadījums Archived;
}
function acceptStatus(Status $status) {...}
klase BlogData
{
public readonly Statuss $status;
publiskā funkcija __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
Pakalpojumu klase
{
privātais Logger $logger;
publiskā funkcija __construct(
Logger $logger = new NullLogger(),
) {
$this->logger = $logger;
}
}
funkcija count_and_iterate(Iterator&Countable $value) {
foreach ($value as $val) {
echo $val;
}
count($value);
}
$response = $htttpClient->request('https://example.com/');
print json_decode($response->getBody()->buffer())['code'];
PHP 8.2 ievieš papildu izmaiņas, kuru mērķis ir vēl vairāk atvieglot izstrādātāja dzīvi un optimizēt viņa darbu. Zemāk ir sniegts jauno funkciju saraksts.
Viens no lielākajiem uzlabojumiem jaunajā PHP versijā ir iespēja tieši izveidot tikai lasāms klase. Klase, kas aprakstīta ar šo funkciju, automātiski to pavairo saviem mainīgajiem. DTO klases tagad izskatīsies glīti un tīri!
readonly klase InvoiceDTO
{
public function __construct(
public UUID $uuid,
public Issuer $issuer,
public DateTime $issuedAt,
) {}
}
Otrā lielā izmaiņa ir dinamisko mainīgo atcelšana klasēs. Šāda implementācija izmetīs deprecation in PHP 8.2 un ErrorException nākamajā PHP versijā.
klase MyUser
{
public string $name;
}
(...)
$myUser->name = 'Name'; // OK
$myUser->surname = 'Uzvārds'; // deprecated / errorexception
Ir vērts pieminēt, ka klases, kas īsteno __get un __set metodes un klases, kas tieši manto no stdClass joprojām var īstenot burvju metodes bez jebkādiem šķēršļiem.
Šeit es jūs vēršos arī pie interesants pavediens par GitHub, kurā PHP-CS izstrādātāji apspriež šīs izmaiņas un nepieciešamību pārveidot savu populāro rīku jaunajai valodas versijai.
Visbeidzot, bet ne mazāk svarīgi - šo uzvedību var atspējot, izmantojot anotāciju.
#[AllowDynamicProperties]
klase MyUser
{
public string $name;
}
$myUser->vārds = 'Vārds'; // OK
null, patiess, un viltusLīdz šim funkcijas, kas vienmēr atgrieza patiess vai viltus vērtība bija jāapraksta ar bool tips.
funkcija alwaysTrue(): bool { return true; }
Turpmāk mēs varam izmantot patiess un viltus kā vienkāršus tipus funkciju atgrieztajās vērtībās.
funkcija alwaysTrue(): true { return true; }
(DNF) ir standarta veids, kā sakārtot boola izteiksmes. Konkrēti, tas nozīmē, ka bolu izteiksme tiek strukturēta kā ORed virkne AND. Piemērojot to tipu deklarācijām, tas nodrošina standarta veidu, kā rakstīt kombinētus Union un Intersection tipus, kurus var apstrādāt analizators.
Tā ir liela izmaiņa, jo tagad, piemēram, varam izmantot nulles krustojuma tipus:
funkcija getFullName((HasName&HasSurname)|null $user) { ... }
Es neesmu liels Traits izmantošanas piekritējs, un šādas izmaiņas man šķiet tīri kosmētiskas, jo īpaši tāpēc, ka tās neļauj izmantot Trait vērtības bez objekta inicializēšanas.
iezīme 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';
}
}
}
Viena no svarīgākajām izmaiņām, ko gaidu ar nepacietību. Jaunākajā PHP versijā mēs varēsim atzīmēt mainīgos kā SensitiveParameterValue. Kāpēc mums vajadzētu?
PHP steka pēdas izņēmumos ir ļoti noderīgas atkļūdošanai, tomēr tās ļauj jums priekšskatīt parametru vērtības. Piemēram, iedomāsimies PDO kods izmanto, lai izveidotu savienojumu ar datubāzi. Debug izsekojums izskatās šādi:
PDOizņēmums: Nav šāda faila vai direktorijas /var/www/html/test.php:3
Stack trace:
#0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 {main}
Pēc anotācijas izmantošanas #[SensitiveParameter] mūsu kaudzes trasē vairs netiks parādīta mainīgā vērtība.
funkcija test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
throw new Exception('Error');
}
test('foo', 'bar', 'baz');
/*
Fatāla kļūda: Nepamatota izņēmuma kļūda: Kļūda test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
izmests test.php 8. rindā
*/
Kā autors saka
, šīs izmaiņas galvenais iemesls ir ļaut iegūt nosaukuma un vērtības īpašības vietās, kur enum objekti nav atļauti, piemēram, masīva atslēgas. Mēs varētu strādāt ar masīviem, lai tos varētu paplašināt, atļaujot enumus vai visus objektus kā atslēgas, bet ļaut iegūt enumu īpašības ir vienkāršāk.
enum A: string {
case B = 'B';
const C = [self::B->vērtība => self::B];
}
Iepriekš statiskās metodes darbojās šādi:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
In PHP 8.2 tas tiks mainīts uz:
DateTime::createFromImmutable(): static
DateTimeImmutable::createFromMutable(): static
Šīs ir būtiskas izmaiņas bibliotēku veidotājiem un/vai visām DateTime pielāgojamām implementācijām.
Tās bija divas funkcijas, kas nav kalpoja tā mērķi, jo tie tikai konvertē starp ISO-8859-1 un UTF-8. PHP Rokasgrāmata iesaka izmantot mb_convert_encoding tā vietā.
Vietnes jutīgumu vislabāk raksturo RFC autors:
Pirms PHP 8.0 versijas PHP lokālā valoda tika iestatīta no vides. Kad lietotājs instalē Linux, tas jautā, kādā valodā vēlaties, lai tā būtu. Lietotājs var pilnībā neapzināties šī lēmuma sekas. Tas ne tikai nosaka lietotāja saskarnes valodu iebūvētajām komandām, bet arī visaptveroši maina to, kā darbojas virkņu apstrāde C bibliotēkā. Piemēram, ja lietotājs, instalējot Linux, izvēlētos “Turkish” (turku valodu), konstatētu, ka lietojumprogrammas, kas izsauc toupper(‘i’), iegūtu lielo burtu ar pieturzīmi I (U+0130, “İ”).
Standartizētu uz tekstu balstītu protokolu laikmetā dabiskā valoda ir mazākuma lietojums lietu konvertēšanai. Bet pat ja lietotājs vēlētos dabiskās valodas burtu konversiju, ar strtolower() tas diez vai gūtu panākumus. Tas ir tāpēc, ka tā apstrādā virkni pa vienam baitam, ievadot katru baitu C bibliotēkas tolower(). Ja ieejas kods ir UTF-8, kas ir vispopulārākā mūsdienu izvēle, strtolower() izkropļo virkni, un parasti kā izejas rezultāts tiek iegūts nederīgs UTF-8.
PHP 8.0 pārtrauca ievērot lokālās vides mainīgos. Tāpēc lokale vienmēr ir “C”, ja vien lietotājs skaidri neizsauc setlocale(). Tas nozīmē, ka lielākā daļa atpakaļ nesaderīgo izmaiņu jau ir aiz muguras. Jebkuras lietojumprogrammas, kas ir atkarīgas no sistēmas locale, lai veiktu veco 8 bitu rakstzīmju kopu gadījumu konversiju, PHP 8.0 būs sabojātas.
Tas nozīmē, ka visas turpmāk minētās funkcijas veic ASCII gadījumu konvertēšanu no PHP.8.2:strtolower, strtoupper, stristr, stripos, strripos, lcfirst, ucfirst, ucwords, str_ireplace
Programmā PHP ir daudz veidu, kā ievietot mainīgos virknēs:
- Tiešā mainīgo iestrādāšana (“$foo”)
- Iekavas ārpus mainīgā (“{$foo}”)
- iekavās pēc dolāra zīmes (“${foo}”)
- Mainīgie mainīgie (“${expr}”, līdzvērtīgs (virknei) ${expr})
Lai izvairītos no neskaidrībām un nepareizas lietošanas, tie vairs nedarbosies:
"Sveiki, ${pasaule}";
Novecojis: ${} lietošana virknēs ir novecojusi
"Hello ${(world)}";
Novecojusi: ${} (mainīgo mainīgo) izmantošana virknēs ir atzīta par novecojušu.
Šīs nav visas izmaiņas, kas PHP 8.2 piedāvās mums. Diemžēl mēs joprojām nesaņēmām vispārīgo tipu atbalstu, saskaņā ar Nikitas teikto monomorfizētie vispārīgie tipi palielinātu pārāk daudz pieskaitāmās izmaksas, bet reificētie vispārīgie tipi prasa daudz izmaiņu visā kodubāzē. Tomēr ir pamanāma disciplīna un redzējums par to. produkts. Nākamajās valodas versijās ieviestās izmaiņas kļūst arvien skaidrākas, un interesenti pamanīs, ka. PHP virzās pareizajā virzienā gan sintakses vienkāršošanas, gan jauninājumu atbalsta jomā. Es sagaidu, ka jau nākamgad mēs redzēsim izsaucams kā derīgu tipu.
