PHP arendus. Symfony konsooli komponent - näpunäited ja nipid
See artikkel on loodud eesmärgiga näidata teile kõige kasulikumaid ja kasulikke näpunäiteid ja nippe Symfony konsooli arendamise kohta.

PHP uus versioon on kohe nurga taga. Milliseid uusi rakendusi peaksite teadma? Vaadake seda artiklit, et teada saada!
PHP 8.2 on peatselt ilmumas. Võib-olla on see see versioon, mis muudab PHP 8-ks uuendamise kõigile ahvatlevaks. Räägime sellest, mida arendajad võivad oodata koos PHP 8.2 ja valmistada ette selle uusimat versiooni. Kuid kõigepealt vaatame kiiresti läbi kõik PHP versioonid ja muudatused aastate jooksul.
<?php
klass User {
public int $id;
public string $name;
}
?>
<?php
$faktor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
<?php
klass A {}
class B extends A {}
class Producer {
public function method(): A {}
}
class ChildProducer extends Producer {
public function method(): B {}
}
?>
<?php
$array['key'] ??= computeDefault();
// on ligikaudu samaväärne
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['õun', 'pirn'];
$fruits = ['banaan', 'apelsin', ...$parts, 'arbuus'];
// ['banaan', 'apelsin', 'õun', 'pirn', 'arbuus'];
?>
<?php
// Tagastab massiivi, mis sisaldab objekti kõiki vajalikke olekuandmeid.
public function __serialize(): array;
// Taastab objekti oleku antud andmemassiivist.
public function __unserialize(array $data): void;
?>
2020. aasta novembris välja antud PHP 8.0 tõi meile seni parimad funktsioonid, mille hulka kuuluvad:
htmlspecialchars($string, double_encode: false);
klass PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
klass Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
klass Number {
public function __construct(
private int|float $number
) {}
}
new Number('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Oh ei!",
8.0 => "See on see, mida ma ootasin",
};
//> See on see, mida ma ootasin
$country = $session?->user?->getAddress()?->country;
enum Staatus
{
case Draft;
case Avaldatud;
case Arhiveeritud;
}
function acceptStatus(Status $status) {...}
klass BlogData
{
public readonly Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(...);
klass Teenus
{
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 toob sisse täiendavaid muudatusi, mille eesmärk on muuta arendaja elu lihtsamaks ja optimeerida tema tööd veelgi rohkem. Allpool on esitatud uute funktsioonide loetelu.
Üks suurimaid uuendusi uues versioonis PHP on võimalus luua otse readonly
klass. Selle omadusega kirjeldatud klass levitab seda automaatselt oma muutujate jaoks. DTO-klassid näevad nüüd korralikud ja puhtad välja!
readonly klass InvoiceDTO
{
public function __construct(
public UUID $uuid,
public Väljaandja $issuer,
public DateTime $issuedAt,
) {}
}
Teine suur muudatus on dünaamiliste muutujate kaotamine klassides. Järgmine implementatsioon viskab deprecationi sisse PHP 8.2 ja ErrorException
PHP tulevases versioonis.
klass MyUser
{
public string $name;
}
(...)
$myUser->name = 'Nimi'; // OK
$myUser->surname = 'Surname'; // deprecated / errorexception
Väärib märkimist, et klassid, mis rakendavad __get
ja __set
meetodid ja klassid, mis pärivad otse stdClass
saab endiselt rakendada maagilisi meetodeid ilma takistusteta.
Siinkohal viitan ma teile ka huvitav teema GitHubis, kus PHP-CS arendajad arutavad seda muudatust ja vajadust muuta oma populaarset tööriista keele uue versiooni jaoks.
Lõpuks saate selle käitumise keelata Annotationi kaudu.
#[AllowDynamicProperties]
klass MyUser
{
public string $name;
}
$myUser->surname = 'Surname'; // OK
null
, tõsi
ja vale
Seni olid funktsioonid, mis tagastasid alati tõsi
või vale
väärtust tuli kirjeldada bool
tüüp.
function alwaysTrue(): bool { return true; }
Nüüdsest võime kasutada tõsi
ja vale
lihtsate tüüpidena funktsioonide tagastatud väärtustes.
function alwaysTrue(): true { return true; }
(DNF) on standardne viis boole'i avaldiste organiseerimiseks. Täpsemalt tähendab see boole'i väljenduse struktureerimist OR-ga seotud AND-ide reaks. Kui seda rakendatakse tüüpideklaratsioonidele, võimaldab see standardset viisi kombineeritud Union- ja Intersection-tüüpide kirjutamiseks, mida parser saab käsitleda.
See on suur muudatus, sest nüüd on meil näiteks nullitav lõiketüüp:
function getFullName((HasName&HasSurname)|null $user) { ... }
Ma ei ole traitide kasutamise suur pooldaja ja selline muudatus on minu jaoks puhtalt kosmeetiline, eriti kuna see ei võimalda kasutada traitide väärtusi ilma objekti initsialiseerimata.
tunnus 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';
}
}
}
Üks olulisemaid muudatusi, mida ma ootan. PHP viimases versioonis saame me märkida muutujaid kui SensitiveParameterValue
. Miks me peaksime?
PHP korstnajäljed erandites on väga kasulikud silumiseks, kuid need võimaldavad teil parameetrite väärtuste eelvaadet vaadata. Näiteks kujutame ette, et PDO kood mida kasutatakse andmebaasiga ühendamiseks. Vigade kõrvaldamise jälg näeks välja järgmiselt:
PDOException: SQLSTATE[HY000] [2002] No such file or directory in /var/www/html/test.php:3: SQLSTATE[HY000] [2002] No such file or directory in /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ärast märkuste kasutamist #[SensitiveParameter]
meie virna jälg ei näita enam muutuja väärtust.
funktsioon test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
throw new Exception('Error');
}
test('foo', 'bar', 'baz');
/*
Fataalne viga: Uncaught Exception: Viga failis test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
thrown in test.php on line 8
*/
Nagu autor ütleb
, selle muudatuse peamine motivatsioon on võimaldada nime ja väärtuse omaduste kättesaamist kohtades, kus enum-objektid ei ole lubatud, näiteks massiivi võtmed. Me võiksime töötada massiividega, nii et neid saaks laiendada, et lubada enumide või kõigi objektide võtmetena, kuid enumide omaduste noppimise lubamine on lihtsam.
enum A: string {
case B = 'B';
const C = [self::B->väärtus => self::B];
}
Varem toimisid staatilised meetodid nii:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
Veebilehel PHP 8.2 see muudetakse:
DateTime::createFromImmutable(): staatiline
DateTimeImmutable::createFromMutable(): staatiline
See on murranguline muudatus raamatukogude loojate ja/või kõigi DateTime'i kohandatud rakenduste jaoks.
Need olid kaks funktsiooni, mis ei teeninud seda eesmärki, sest nad ainult konverteeriti vahel ISO-8859-1
ja UTF-8
. PHP käsiraamat soovitab kasutada mb_convert_encoding
selle asemel.
Lokaaltundlikkust kirjeldab kõige paremini RFC autor:
Enne versiooni PHP 8.0 oli PHP asukoha valik määratud keskkonnast. Kui kasutaja installeerib Linuxi, küsitakse, millises keeles soovite seda kasutada. Kasutaja ei pruugi selle otsuse tagajärgi täielikult mõista. See ei määra mitte ainult kasutajaliidese keelt sisseehitatud käskude jaoks, vaid muudab ka läbivalt seda, kuidas stringide käsitlemine C-raamatukogus toimib. Näiteks kasutaja, kes valib Linuxi installimisel "Turkish", avastab, et toupper('i') kutsuvad rakendused saavad punktiirjoonega I (U+0130, "İ").
Standardiseeritud tekstipõhiste protokollide ajastul on loomulik keel juhtumite teisendamise puhul vähemuses. Kuid isegi kui kasutaja sooviks loomulikus keeles suurtähtede teisendamist, ei saavutaks ta tõenäoliselt edu funktsiooni strtolower() abil. Seda seetõttu, et see töötleb stringi üks bait korraga, andes iga baiti C-tööriista tolower()-ile. Kui sisendiks on UTF-8, mis on kaugelt kõige populaarsem kaasaegne valik, moonutab strtolower() stringi, andes väljundiks tavaliselt kehtetu UTF-8.
PHP 8.0 lakkas arvestamast asukoha keskkonnamuutujaid. Seega on lokaaliks alati "C", kui kasutaja ei kutsu selgesõnaliselt funktsiooni setlocale(). See tähendab, et suurem osa tagasiühilduvusest on juba seljataga. Kõik rakendused, mis sõltuvad süsteemi locale'ist, et teha vanade 8-bitiste tähemärkide konverteerimist, oleksid PHP 8.0-ga katki läinud.
See tähendab, et kõik allpool esitatud funktsioonid teevad ASCII-konversiooni alates PHP.8.2:strtolower
, strtoupper
, stristr
, stripos
, strripos
, lcfirst
, ucfirst
, ucwords
, str_ireplace
Meil on PHP-s palju võimalusi muutujate põimimiseks stringidesse:
- Muutujate otsene manustamine ("$foo")
- Klambrid väljaspool muutujat ("{$foo}")
- Klambrid pärast dollarimärki ("${foo}")
- Muutujad ("${expr}", samaväärne (string) ${expr})
Segaduse ja väärkasutuse vältimiseks need enam ei tööta:
"Tere ${maailm}";
Kasutuselt kõrvaldatud: ${} kasutamine stringides on vananenud.
"Tere ${(maailm)}";
Deprecated: ${} (muutujad) kasutamine stringides on taunitud.
Need ei ole kõik muudatused, mis PHP 8.2 pakub meile. Kahjuks ei saanud me ikkagi toetust geneerilistele tüüpidele, Nikita sõnul lisaksid monomorfiseeritud geneerilised tüübid liiga palju jõudluskoormust ja reifitseeritud geneerilised tüübid nõuavad palju muudatusi kogu koodibaasis. Mis on aga märgatav, on distsipliini ja visiooni toode. Keele järjestikustes versioonides tehtud muudatused muutuvad selgemaks ja huvilised märkavad, et PHP liigub õiges suunas nii süntaksi lihtsustamise kui ka uuenduste toetamise osas. Ma eeldan, et juba järgmisel aastal näeme me kutsutav
kehtiva tüübina.