PHP Kehitys. Symfony Console Component - Vinkkejä ja niksejä
Tämä artikkeli on luotu tarkoituksena näyttää sinulle hyödyllisimmät ja hyödyllisimmät vinkit ja niksit Symfony-konsolin kehitykseen liittyen.
Uusi versio PHP:stä on aivan nurkan takana. Mitkä ovat ne uudet toteutukset, joista sinun tulisi tietää? Tutustu tähän artikkeliin ja ota selvää!
PHP 8.2 julkaistaan pian. Ehkä se on versio, joka saa päivityksen PHP 8:aan tuntumaan houkuttelevalta kaikille. Puhutaanpa siitä, mitä kehittäjät voivat odottaa seuraavien versioiden kanssa. PHP 8.2 ja valmistautua sen uusimpaan versioon. Käydään kuitenkin ensin nopeasti läpi kaikki PHP-versiot ja muutokset vuosien varrella.
<?php
luokka User {
public int $id;
public string $name;
}
?>
<?php
$tekijä = 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();
// vastaa suunnilleen
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['omena', 'päärynä'];
$fruits = ['banaani', 'appelsiini', ...$parts, 'vesimeloni'];
// ['banaani', 'appelsiini', 'omena', 'päärynä', 'vesimeloni'];
?>
<?php
// Palauttaa arkin, joka sisältää kaikki objektin tarvittavat tilatiedot.
public function __serialize(): array;
// Palauttaa objektin tilan annetusta datamassasta.
public function __unserialize(array $data): void;
?>
Marraskuussa 2020 julkaistu PHP 8.0 toi meille parhaat ominaisuudet, joihin kuuluvat:
htmlspecialchars($string, double_encode: false);
luokka PostsController
{
#[Route("/api/posts/{id}", methods: ["GET"])]
public function get($id) { /* ... */ }
}
luokka Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
luokka Number {
public function __construct(
private int|float $number
) {}
}
new Number('NaN'); // TypeError
echo match (8.0) {
'8.0' => "Voi ei!",
8.0 => "Tätä minä odotin",
};
//> Tätä minä odotin
$country = $session?->user?->getAddress()?->country;
enum Status
{
case Luonnos;
case Julkaistu;
case Arkistoitu;
}
function acceptStatus(Status $status) {...}
luokka BlogData
{
public readonly Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
}
$foo = $this->foo(...);
$fn = strlen(....);
luokka Service
{
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 sisältää uusia muutoksia, joiden tarkoituksena on helpottaa kehittäjän elämää ja optimoida hänen työtään entisestään. Alla on luettelo uusista ominaisuuksista.
Yksi suurimmista parannuksista PHP:n uudessa versiossa on mahdollisuus luoda suoraan readonly
luokka. Luokka, joka on kuvattu tällä ominaisuudella, levittää sen automaattisesti muuttujiinsa. DTO-luokat näyttävät nyt siisteiltä ja puhtailta!
readonly luokka InvoiceDTO
{
public function __construct(
public UUID $uuid,
public Issuer $issuer,
public DateTime $issuedAt,
) {}
}
Toinen suuri muutos on dynaamisten muuttujien poistaminen luokista. Seuraava toteutus heittää deprecationin osoitteessa PHP 8.2 ja ErrorException
PHP:n tulevassa versiossa.
luokka MyUser
{
public string $name;
}
(...)
$myUser->name = 'Nimi'; // OK.
$myUser->sukunimi = 'Sukunimi'; // deprecated / errorexception
On syytä mainita, että luokat, jotka toteuttavat __get
ja __set
menetelmiä ja luokkia, jotka periytyvät suoraan stdClass
voi silti toteuttaa taikamenetelmiä ilman esteitä.
Viittaan tässä yhteydessä myös mielenkiintoinen säie GitHubissa, jossa PHP-CS:n kehittäjät keskustelevat tästä muutoksesta ja tarpeesta muuttaa suosittua työkalua kielen uutta versiota varten.
Viimeisenä mutta ei vähäisimpänä, voit poistaa tämän käyttäytymisen käytöstä huomautuksen avulla.
#[AllowDynamicProperties]
luokka MyUser
{
public string $name;
}
$myUser->sukunimi = 'Sukunimi'; // OK
null
, true
ja väärä
Tähän asti funktiot, jotka palauttivat aina true
tai väärä
arvo oli kuvattava bool
tyyppi.
function alwaysTrue(): bool { return true; }
Tästä lähtien voimme käyttää true
ja väärä
yksinkertaisina tyyppeinä funktioiden palautetuissa arvoissa.
function alwaysTrue(): true { return true; }
(DNF) on vakiintunut tapa järjestää boolean-lausekkeet. Tarkemmin sanottuna se tarkoittaa boolean-lausekkeen jäsentämistä AND-sarjoiksi. Kun sitä sovelletaan tyyppi-ilmoituksiin, se mahdollistaa standarditavan kirjoittaa yhdistettyjä Union- ja Intersection-tyyppejä, joita jäsentäjä voi käsitellä.
Se on suuri muutos, sillä nyt meillä voi olla esimerkiksi nollattavia leikkaustyyppejä:
function getFullName((HasName&HasSukunimi)|null $user) { ... }
En ole Traitien käytön suuri kannattaja, ja tällainen muutos on minusta puhtaasti kosmeettinen, varsinkin kun se ei salli Trait-arvojen käyttöä ilman objektin alustamista.
ominaisuus 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';
}
}
}
Yksi tärkeimmistä muutoksista, jota odotan innolla. PHP:n uusimmassa versiossa voimme merkitä muuttujat seuraavasti SensitiveParameterValue
. Miksi meidän pitäisi?
PHP:n poikkeusten pinojäljet ovat erittäin hyödyllisiä virheenkorjauksessa, mutta niiden avulla voit kuitenkin esikatsella parametrien arvoja. Kuvitellaan esimerkiksi, että PDO koodi jota käytetään yhteyden muodostamiseen tietokantaan. Vianmääritysjälki näyttää seuraavalta:
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): ...', 'root', 'password').
#1 {main}
Annotationin käytön jälkeen #[SensitiveParameter]
pinojälkemme ei enää näytä muuttujan arvoa.
funktio test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
throw new Exception('Error');
}
test('foo', 'bar', 'baz');
/*
Fatal error: Uncaught Exception: test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz').
#1 {main}
thrown in test.php on line 8
*/
Kuten kirjoittaja sanoo
, tämän muutoksen ensisijainen motivaatio on sallia nimi- ja arvo-ominaisuuksien nouto paikoissa, joissa enum-oliot eivät ole sallittuja, kuten array-avaimissa. Voisimme käsitellä matriiseja niin, että ne voitaisiin laajentaa sallimaan enumien tai kaikkien objektien käyttö avaimina, mutta enumien ominaisuuksien noutaminen on yksinkertaisempaa.
enum A: string {
case B = 'B';
const C = [self::B->arvo => self::B];
}
Aiemmin staattiset menetelmät toimivat näin:
DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable
Osoitteessa PHP 8.2 se muutetaan seuraavasti:
DateTime::createFromImmutable(): staattinen
DateTimeImmutable::createFromMutable(): staattinen
Tämä on rikkova muutos kirjastojen luojille ja/tai kaikille DateTimen mukautetuille toteutuksille.
Ne olivat kaksi toimintoa, jotka eivät palvelleet sitä tarkoitusta, koska ne vain muunnetaan välillä ISO-8859-1
ja UTF-8
. PHP-käsikirja suosittelee käyttämään mb_convert_encoding
sen sijaan.
RFC:n kirjoittaja kuvaa parhaiten paikallisherkkyyttä:
Ennen PHP 8.0:a PHP:n paikallisalue asetettiin ympäristöstä. Kun käyttäjä asentaa Linuxin, se kysyy, millä kielellä haluat sen olevan. Käyttäjä ei ehkä täysin ymmärrä tämän päätöksen seurauksia. Se ei ainoastaan aseta käyttöliittymän kieltä sisäänrakennetuille komennoille, vaan se myös muuttaa läpileikkaavasti sitä, miten merkkijonojen käsittely C-kirjastossa toimii. Esimerkiksi käyttäjä, joka Linuxia asentaessaan valitsee "Turkish" (turkki), huomaa, että sovellukset, jotka kutsuvat toupper('i') -komentoa, saavat tulokseksi pistemäisen ison I-kirjaimen (U+0130, "İ").
Standardoitujen tekstipohjaisten protokollien aikakaudella luonnollinen kieli on vähemmistösovellus tapausten muuntamisessa. Mutta vaikka käyttäjä haluaisikin luonnollisen kielen isojen ja pienten kirjainten muuntamista, hän tuskin onnistuisi siinä strtolower():n avulla. Tämä johtuu siitä, että se käsittelee merkkijonon yksi tavu kerrallaan ja syöttää jokaisen tavun C-kirjaston tolower()-funktiolle. Jos syötteenä on UTF-8, joka on ylivoimaisesti suosituin nykyaikainen valinta, strtolower() vääristää merkkijonon ja tuottaa tulosteeksi yleensä virheellisen UTF-8:n.
PHP 8.0 lakkasi kunnioittamasta locale-ympäristömuuttujia. Lokaalina on siis aina "C", ellei käyttäjä nimenomaisesti kutsu setlocale() -ohjelmaa. Tämä tarkoittaa, että suurin osa taaksepäin yhteensopivista muutoksista on jo takana. Kaikki sovellukset, jotka ovat riippuvaisia järjestelmälokaaleista tehdessään vanhojen 8-bittisten merkistöjen muunnoksia, olisivat menneet rikki PHP 8.0:ssa.
Se tarkoittaa, että kaikki alla olevat toiminnot tekevät ASCII-kirjainten muunnoksen PHP.8.2:sta:strtolower
, strtoupper
, stristr
, stripos
, strripos
, lcfirst
, ucfirst
, ucwords
, str_ireplace
Meillä on PHP:ssä monia tapoja upottaa muuttujia merkkijonoihin:
- Muuttujien suora upottaminen ("$foo")
- Muuttujan ulkopuolella olevat sulkeet ("{$foo}")
- Suluissa dollarimerkin jälkeen ("${foo}").
- Muuttujamuuttujat ("${expr}", vastaa (merkkijonoa) ${expr})
Sekaannusten ja väärinkäytösten välttämiseksi nämä eivät enää toimi:
"Hei ${world}";
Käytöstä poistettu: ${} merkkijonoissa on vanhentunut.
"Hello ${(world)}";
Deprecated: ${} (muuttujan muuttujat) käyttäminen merkkijonoissa on vanhentunut.
Nämä eivät ole kaikki muutokset, jotka PHP 8.2 tarjoaa meille. Valitettavasti emme vieläkään saaneet tukea geneerisille tyypeille, sillä Nikitan sanojen mukaan monomorfisoidut geneeriset tyypit lisäisivät liikaa suorituskykyä, ja reifioidut geneeriset tyypit vaativat monia muutoksia koko koodipohjaan. Huomattavaa on kuitenkin kurinalaisuus ja näkemys, jonka mukaan tuote. Kielen peräkkäisissä versioissa tehdyt muutokset ovat yhä selkeämpiä, ja kiinnostuneet huomaavat, että PHP on menossa oikeaan suuntaan sekä syntaksin yksinkertaistamisen että uutuuksien tukemisen suhteen. Odotan, että jo ensi vuonna näemme seuraavat asiat kutsuttava
kelvolliseksi tyypiksi.