Přechod na PHP 8.5
Zvedněte verzi PHP v composer.json na 8.5 a DressCode přepíše kód na pipe operátor,
array_first(), array_last() a clone() s vlastnostmi. Opraví nebo ohlásí i všechno, co
PHP 8.5 zavrhlo, a výsledek v tomtéž běhu zformátuje podle vašeho standardu.
Jak to vypadá
Třída psaná pro PHP 8.4 v projektu, který teď vyžaduje PHP 8.5. Konfigurace přidává ke standardu sady
modernizations a deprecations a říká, že jmenné prostory projektu žádné vlastní funkce
nedeklarují; cílovou verzi PHP, kterou jinak DressCode vezme z composer.json, tu uvádí klíč
targets:
use:
- perCs
- modernizations
- deprecations
nameResolution: certain
targets:
php: '8.5'
final class Article
{
private string $title = '';
/** @var list<Item> */
private array $items = [];
public function withTitle(string $title): static
{
$clone = clone $this;
$clone->title = $title;
return $clone;
}
public function slug(string $title): string
{
return trim(strtolower(strip_tags($title)));
}
public function newest(): Item
{
return $this->items[array_key_last($this->items)];
}
public function download(string $url): string
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = (string) curl_exec($ch);
curl_close($ch);
return $data;
}
public function count(): int
{
return (integer) count($this->items);
}
}
Po jednom dresscode fix:
final class Article
{
private string $title = '';
/** @var list<Item> */
private array $items = [];
public function withTitle(string $title): static
{
return clone($this, ['title' => $title]);
}
public function slug(string $title): string
{
return $title |> strip_tags(...) |> strtolower(...) |> trim(...);
}
public function newest(): Item
{
return array_last($this->items);
}
public function download(string $url): string
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = (string) curl_exec($ch);
return $data;
}
public function count(): int
{
return (int) count($this->items);
}
}
Každá změna je jedna novinka PHP 8.5: clone() s vlastnostmi, pipe operátor |>, funkce
array_last(), volání curl_close(), které už nic nedělá, a přetypování (integer),
které PHP 8.5 zavrhlo.
Co se přepíše
Sada modernizations přepíše kód na to, co přineslo PHP 8.5. Každá položka je rozhodnutí sekce upgrading, které projekt může zapnout i samotné.
| novinka | před | po | oprava |
|---|---|---|---|
pipe operátor, upgrading.syntax.pipe |
trim(strtolower($s)) |
$s |> strtolower(...) |> trim(...) |
opraví se |
array_first(), array_last(), upgrading.functions.arrayFirstLast |
$a[array_key_last($a)] |
array_last($a) |
opraví se |
clone() s vlastnostmi, upgrading.syntax.cloneWith |
$c = clone $this; $c->title = $title; |
clone($this, ['title' => $title]) |
opraví se; riziková, kde může záležet na tom, že se argument vyhodnotí jednou |
#[\Deprecated] na traitu a konstantě, upgrading.phpdoc.deprecated |
/** @deprecated */ |
#[\Deprecated] |
riziková: zastaralý kód začne hlásit za běhu |
#[\Override] na vlastnosti, upgrading.classes.Override |
public string $name; |
#[\Override] public string $name; |
v žádné sadě, zapněte si ho sami; potřebuje typy |
Každé rozhodnutí ví, ve které verzi PHP jeho konstrukce přišla. Dokud composer.json dovoluje
ještě PHP 8.4, přepisy na 8.5 tiše čekají a dresscode config je vypíše jako bez účinku.
Co PHP 8.5 zavrhlo
Sada deprecations opraví, co má přímou náhradu, a zbytek ohlásí i s verzí, která ho zavrhla. Metody
tříd PHP přepíše jen tam, kde DressCode zná typ objektu, viz Typy
z PHPStanu.
| zavržené | DressCode |
|---|---|
curl_close(), curl_share_close(), finfo_close(),
imagedestroy(), xml_parser_free() |
opraví se: volání zmizí, protože už nic nedělá |
zpětné apostrofy `git log` |
opraví se: shell_exec("git log") |
přetypování (integer), (boolean), (double), (binary) |
opraví se: (int), (bool), (float), (string) |
středník za case |
opraví se: case 1: |
klíč pole null |
opraví se: '' |
SplObjectStorage::contains(), attach(), detach() |
opraví se s typy: offsetExists(), offsetSet(), offsetUnset() |
ReflectionProperty::setAccessible() |
opraví se s typy: volání zmizí |
mysqli_execute(), socket_set_timeout() |
ohlásí se |
DATE_RFC7231, FILTER_DEFAULT, MHASH_* |
ohlásí se |
__sleep(), __wakeup() |
ohlásí se: přepis na __serialize() by změnil formát uložených dat |
Nález jmenuje verzi, která věc zavrhla:
src/Db.php:19:5: error: Function `mysqli_execute()` is deprecated: since PHP 8.5. [upgrading.php.deprecatedApi]
Rizikové opravy
Přepis, který může změnit, co kód dělá, se jen ohlásí a udělá se, až jeho rozhodnutí uvedete ve
fixRisky. Atribut #[\Deprecated] je takový ze své podstaty, protože zastaralý kód začne hlásit
za běhu:
fixRisky:
- upgrading.phpdoc.deprecated
Ve jmenném prostoru může být nekvalifikované strip_tags() funkcí toho jmenného prostoru.
Dokud konfigurace neřekne nameResolution: certain, přepisy takových volání čekají jako rizikové, viz Funkce a konstanty ve jmenných prostorech.
Krok za krokem
- Začněte s čistým pracovním stromem, ať diff ukáže jen to, co udělal DressCode.
- Změřte, kolik práce přechod dá:
dresscode upgrade php 8.5. Uvádí-li projektconfig.platform.php, zvedněte ho na 8.5 předem. - Uložte plán a proveďte ho:
dresscode upgrade php 8.5 --save-plan, pakdresscode upgrade --continue. U kroku Composeru se DressCode zeptá, jestli smí zvednoutrequire.phpna^8.5; zvednout ho můžete i sami a pak pustit--continue. - Přečtěte, co zůstalo pro vás, a pusťte
--continueznovu, dokud běh neskončíUPGRADED. Rizikové opravy, které čekají, rozhodnou typy,nameResolution, nebo vy. - Výsledek commitněte samostatně, bez jiných změn.
Má-li projekt sady modernizations a deprecations v konfiguraci, stačí po zvednutí
require.php obyčejný dresscode fix. Celý postup s testy a commity popisuje Upgrade kódu krok za krokem.
Kam dál
- Přechod na novější PHP, PHP 8.6 a 8.4 i starší verze.
- Typy z PHPStanu, aby se přepsaly i metody tříd PHP.
- Sekce upgrading se všemi rozhodnutími o novějším PHP.