Wordpress

Fullkominn leiðarvísir til að flytja PHP kóða

Við kjöraðstæður ættum við að nota PHP 8.0 (nýjustu útgáfuna þegar þetta er skrifað) fyrir allar síður okkar og uppfæra það um leið og ný útgáfa er gefin út. Hins vegar munu verktaki oft þurfa að vinna með fyrri PHP útgáfur, svo sem þegar þeir búa til opinbert viðbót fyrir WordPress eða vinna með eldri kóða sem hindrar uppfærslu á umhverfi vefþjónsins.

Við þessar aðstæður gætum við gefið upp vonina um að nota nýjasta PHP kóðann. En það er betri valkostur: við getum samt skrifað frumkóðann okkar með PHP 8.0 og yfirfært hann í fyrri PHP útgáfu - jafnvel í PHP 7.1.

Í þessari handbók munum við kenna þér allt sem þú þarft að vita um að umbreyta PHP kóða.

Hvað er transpiling?

Transpiling breytir frumkóða úr forritunarmáli í samsvarandi frumkóða sama eða annars forritunarmáls.

Transpiling er ekki nýtt hugtak innan vefþróunar: forritarar við viðskiptavini munu líklega kannast við Babel, transpiler fyrir JavaScript kóða.

Babel breytir JavaScript kóða úr nútíma ECMAScript 2015+ útgáfu í eldri útgáfu sem er samhæft við eldri vafra. Til dæmis, gefið ES2015 örvaaðgerð:

[2, 4, 6].map((n) => n * 2);

…Babel mun breyta því í ES5 útgáfuna sína:

[2, 4, 6].map(function(n) {
  return n * 2;
});

Hvað er að flytja PHP?

Það sem er hugsanlega nýtt innan vefþróunar er möguleikinn á að umbreyta kóða á netþjóni, sérstaklega PHP.

Umritun PHP virkar á sama hátt og að umskrá JavaScript: frumkóða úr nútíma PHP útgáfu er breytt í jafngildan kóða fyrir eldri PHP útgáfu.

Eftir sama dæmi og áður, örvafall frá PHP 7.4:

$nums = array_map(fn($n) => $n * 2, [2, 4, 6]);

... er hægt að umbreyta í samsvarandi PHP 7.3 útgáfu þess:

$nums = array_map(
  function ($n) {
    return $n * 2;
  },
  [2, 4, 6]
);

Örvaföll geta verið umbreytt vegna þess að þau eru setningafræðilegur sykur, þ.e. ný setningafræði til að framleiða núverandi hegðun. Þetta er lágt hangandi ávöxturinn.

Hins vegar eru líka nýir eiginleikar sem skapa nýja hegðun og sem slíkur verður enginn sambærilegur kóði fyrir fyrri útgáfur af PHP. Það er raunin með stéttarfélög, kynntar í PHP 8.0:

function someFunction(float|int $param): string|float|int|null
{
  // ...
}

Í þessum aðstæðum er samt hægt að umbreyta svo framarlega sem nýja eiginleikann er nauðsynlegur fyrir þróun en ekki fyrir framleiðslu. Þá getum við einfaldlega fjarlægt eiginleikann alveg úr yfirfærða kóðanum án alvarlegra afleiðinga.

Eitt slíkt dæmi eru stéttarfélög. Þessi eiginleiki er notaður til að athuga hvort það sé ekkert ósamræmi á milli inntakstegundar og uppgefiðs gildis, sem hjálpar til við að koma í veg fyrir villur. Ef það er árekstur við tegundir verður villa þegar í þróun og við ættum að grípa hana og laga hana áður en kóðinn kemst í framleiðslu.

Þess vegna höfum við efni á að fjarlægja eiginleikann úr kóðanum fyrir framleiðslu:

function someFunction($param)
{
  // ...
}

Ef villan gerist enn í framleiðslu verða villuskilaboðin sem hent eru minna nákvæm en ef við værum með stéttarfélög. Hins vegar vegur þessi hugsanlegi ókostur upp með því að geta notað verkalýðstegundir í fyrsta lagi.

Í fullkomnum heimi ættum við að geta notað PHP 8.0 á öllum síðum okkar og uppfært um leið og ný útgáfa kemur út 😌 En það er ekki alltaf raunin. Lærðu allt sem þú þarft að vita um umskráningu PHP kóða hér 👇Smelltu til að kvak

Kostir þess að flytja PHP kóða

Transpiling gerir manni kleift að kóða forrit með nýjustu útgáfu af PHP og framleiða útgáfu sem virkar einnig í umhverfi sem keyrir eldri útgáfur af PHP.

Þetta getur verið sérstaklega gagnlegt fyrir þróunaraðila sem búa til vörur fyrir eldri efnisstjórnunarkerfi (CMS). WordPress, til dæmis, styður enn opinberlega PHP 5.6 (jafnvel þó það mæli með PHP 7.4+). Hlutfall WordPress vefsvæða sem keyra PHP útgáfur 5.6 til 7.2 - sem eru allar end-of-life (EOL), sem þýðir að þær fá ekki öryggisuppfærslur lengur - stendur í umtalsverðum 34.8%, og þær sem keyra á hvaða PHP útgáfu sem er önnur en 8.0 stendur í heilum 99.5%:

WordPress notkun eftir útgáfu
WordPress notkunartölfræði eftir útgáfu. Uppruni myndar: WordPress

Þar af leiðandi verða WordPress þemu og viðbætur sem miða að alþjóðlegum markhópi mjög líklega kóðaðar með gamalli útgáfu af PHP til að auka mögulega útbreiðslu þeirra. Þökk sé umbreytingu var hægt að kóða þetta með PHP 8.0 og samt vera gefið út fyrir eldri PHP útgáfu, þannig að miða á eins marga notendur og mögulegt er.

Reyndar, hvaða forrit sem þarf að styðja aðra PHP útgáfu en þá nýjustu (jafnvel innan marka þeirra PHP útgáfur sem nú eru studdar) geta notið góðs af.

Þetta er raunin með Drupal, sem krefst PHP 7.3. Þökk sé umbreytingu geta verktaki búið til Drupal einingar sem eru aðgengilegar almenningi með PHP 8.0 og sleppt þeim með PHP 7.3.

Annað dæmi er þegar búið er til sérsniðinn kóða fyrir viðskiptavini sem geta ekki keyrt PHP 8.0 í umhverfi sínu af einni eða annarri ástæðu. Engu að síður, þökk sé umbreytingu, geta verktaki samt kóðað afhendingarefni sín með því að nota PHP 8.0 og keyrt þær á þessum eldri umhverfi.

Hvenær á að flytja PHP

Það er alltaf hægt að yfirfæra PHP kóða nema hann innihaldi einhvern PHP eiginleika sem á sér ekki hliðstæðu í fyrri útgáfu PHP.

Það er hugsanlega raunin með eiginleika, kynntar í PHP 8.0:

#[SomeAttr]
function someFunc() {}

#[AnotherAttr]
class SomeClass {}

Í fyrra dæminu með því að nota örvaaðgerðir gæti kóðann verið færður yfir vegna þess að örvaaðgerðir eru setningafræðilegur sykur. Eiginleikar skapa aftur á móti alveg nýja hegðun. Þessa hegðun væri einnig hægt að endurskapa með PHP 7.4 og nýrri, en aðeins með því að kóða hana handvirkt, þ.e. ekki sjálfkrafa byggt á tóli eða ferli (AI gæti veitt lausn, en við erum ekki þar ennþá).

Eiginleikar sem ætlaðir eru til þróunarnotkunar, svo sem #[Deprecated], er hægt að fjarlægja á sama hátt og stéttarfélög eru fjarlægðar. En eiginleikar sem breyta hegðun forritsins í framleiðslu er ekki hægt að fjarlægja og ekki er heldur hægt að yfirfæra þá beint.

Frá og með deginum í dag getur enginn transpiler tekið kóða með PHP 8.0 eiginleikum og framleitt sjálfkrafa samsvarandi PHP 7.4 kóða. Þar af leiðandi, ef PHP kóðinn þinn þarf að nota eiginleika, þá verður það erfitt eða óframkvæmanlegt að flytja hann.

PHP eiginleikar sem hægt er að yfirfæra

Þetta eru eiginleikarnir frá PHP 7.1 og nýrri sem nú er hægt að yfirfæra. Ef kóðinn þinn notar aðeins þessa eiginleika geturðu notið vissu um að yfirfærða forritið þitt virki. Annars þarftu að meta hvort yfirfærði kóðinn muni valda bilunum.

PHP útgáfaAðstaða
7.1Allt
7.2- object tegund
– breytutegund breikkunar
- PREG_UNMATCHED_AS_NULL flagga inn preg_match
7.3– Tilvísunarverkefni í list() / array destructuring (Nema inni foreach — #4376)
- Sveigjanleg Heredoc og Nowdoc setningafræði
– Kommur á eftir í aðgerðasímtölum
- set(raw)cookie samþykkir $option rök
7.4- Vélritaðir eiginleikar
- Örvaaðgerðir
– Núllsamrunaúthlutunarstjóri
- Að pakka upp inni í fylkjum
– Númerísk bókstafsskilgreinir
- strip_tags() með fjölda merkjanafna
– sambreytilegar ávöxtunargerðir og andstæðar paramgerðir
8.0– Sambandsgerðir
- mixed gervi tegund
- static tegund skila
- ::class töfrafasti á hlutum
- match tjáning
- catch undantekningar eingöngu eftir tegund
– Núll-öruggur rekstraraðili
– Kynning á eignum í flokki byggingaraðila
– Kommur í færibreytu og lokun use listar

PHP Transpilers

Eins og er er eitt tól til að umbreyta PHP kóða: Rektor.

Rector er PHP endurreisnartæki, sem breytir PHP kóða byggt á forritanlegum reglum. Við setjum inn frumkóðann og reglurnar sem á að keyra og rektor mun umbreyta kóðanum.

Rektor er stjórnað í gegnum skipanalínu, uppsett í verkefninu í gegnum Composer. Þegar það er keyrt mun rektor gefa út „diff“ (viðbætur í grænu, fjarlægingar í rauðu) kóðans fyrir og eftir umbreytingu:

„diff“ úttak frá rektor
„diff“ úttak frá rektor

Hvaða útgáfa af PHP á að yfirfæra í

Til að flytja kóða yfir PHP útgáfur verður að búa til samsvarandi reglur.

Í dag inniheldur rektorsafnið flestar reglur um umskráningu kóða á bilinu PHP 8.0 til 7.1. Þess vegna getum við flutt PHP kóðann okkar á áreiðanlegan hátt niður í útgáfu 7.1.

Það eru líka reglur um umbreytingu frá PHP 7.1 til 7.0 og frá 7.0 til 5.6, en þær eru ekki tæmandi. Unnið er að því að ljúka þeim, svo við gætum að lokum flutt PHP kóða niður í útgáfu 5.6.

Transpiling vs Backporting

Bakflutningur er svipaður og umbreytingu, en einfaldari. Bakflutningskóði treystir ekki endilega á nýja eiginleika frá tungumáli. Þess í stað er hægt að útvega sömu virkni í eldri útgáfu tungumálsins einfaldlega með því að afrita/líma/aðlaga samsvarandi kóða úr nýju útgáfunni af tungumálinu.

Til dæmis aðgerðin str_contains var kynnt í PHP 8.0. Auðvelt er að útfæra sömu aðgerðina fyrir PHP 7.4 og hér að neðan á þennan hátt:

if (!defined('PHP_VERSION_ID') || (defined('PHP_VERSION_ID') && PHP_VERSION_ID < 80000)) {
  if (!function_exists('str_contains')) {
    /**
     * Checks if a string contains another
     *
     * @param string $haystack The string to search in
     * @param string $needle The string to search
     * @return boolean Returns TRUE if the needle was found in haystack, FALSE otherwise.
     */
    function str_contains(string $haystack, string $needle): bool
    {
      return strpos($haystack, $needle) !== false;
    }
  }
}

Vegna þess að bakflutningur er einfaldari en flutningur, ættum við að velja þessa lausn hvenær sem bakflutningur virkar.

Varðandi bilið á milli PHP 8.0 til 7.1, þá getum við notað polyfill bókasöfn Symfony:

  • Polyfill PHP 7.1
  • Polyfill PHP 7.2
  • Polyfill PHP 7.3
  • Polyfill PHP 7.4
  • Polyfill PHP 8.0

Þessi bókasöfn styðja eftirfarandi aðgerðir, flokka, fasta og viðmót:

PHP útgáfaAðstaða
7.2Aðgerðir:

  • spl_object_id
  • utf8_encode
  • utf8_decode

Fastar:

  • PHP_FLOAT_*
  • PHP_OS_FAMILY
7.3Aðgerðir:

  • array_key_first
  • array_key_last
  • hrtime
  • is_countable

undantekningar:

  • JsonException
7.4Aðgerðir:

  • get_mangled_object_vars
  • mb_str_split
  • password_algos
8.0tengi:

  • Stringable

Flokkar:

  • ValueError
  • UnhandledMatchError

Fastar:

  • FILTER_VALIDATE_BOOL

Aðgerðir:

  • fdiv
  • get_debug_type
  • preg_last_error_msg
  • str_contains
  • str_starts_with
  • str_ends_with
  • get_resource_id

Dæmi um Transpiled PHP

Við skulum skoða nokkur dæmi um yfirfærðan PHP kóða og nokkra pakka sem eru að fullu umritaðir.

PHP kóða

The match tjáning var kynnt í PHP 8.0. Þessi frumkóði:

function getFieldValue(string $fieldName): ?string
{
  return match($fieldName) {
    'foo' => 'foofoo',
    'bar' => 'barbar',
    'baz' => 'bazbaz',
    default => null,
  };
}

...verður yfirfærður í samsvarandi PHP 7.4 útgáfu með því að nota switch rekstraraðili:

function getFieldValue(string $fieldName): ?string
{
  switch ($fieldName) {
    case 'foo':
      return 'foofoo';
    case 'bar':
      return 'barbar';
    case 'baz':
      return 'bazbaz';
    default:
      return null;
  }
}

Nullsafe rekstraraðilinn var einnig kynntur í PHP 8.0:

public function getValue(TypeResolverInterface $typeResolver): ?string
{
  return $this->getResolver($typeResolver)?->getValue();
}

Yfirfærði kóðinn þarf að úthluta gildi aðgerðarinnar til nýrrar breytu fyrst, til að forðast að framkvæma aðgerðina tvisvar:

public function getValue(TypeResolverInterface $typeResolver): ?string
{
  return ($val = $this->getResolver($typeResolver)) ? $val->getValue() : null;
}

Kynningareiginleikinn fyrir byggingaraðila, einnig kynntur í PHP 8.0, gerir forriturum kleift að skrifa minna kóða:

class QueryResolver
{
  function __construct(protected QueryFormatter $queryFormatter)
  {
  }
}

Þegar það er umbreytt fyrir PHP 7.4 er allt kóðann framleitt:

 class QueryResolver
 {
  protected QueryFormatter $queryFormatter;

  function __construct(QueryFormatter $queryFormatter)
  {
    $this->queryFormatter = $queryFormatter;
  }
}

Yfirfærði kóðinn hér að ofan inniheldur vélritaða eiginleika, sem voru kynntir í PHP 7.4. Að flytja þennan kóða niður í PHP 7.3 kemur í stað þeirra fyrir docblocks:

 class QueryResolver
 {
  /**
   * @var QueryFormatter
   */
  protected $queryFormatter;

  function __construct(QueryFormatter $queryFormatter)
  {
    $this->queryFormatter = $queryFormatter;
  }
}

PHP pakkar

Verið er að flytja eftirfarandi bókasöfn til framleiðslu:

Bókasafn/lýsingKóði/nótur
Rektor
PHP endurreisnartæki sem gerir umbreytingu mögulega
- Kóðinn
- Flyttur kóða
— Skýringar
Auðveldir kóðunarstaðlar
Tól til að láta PHP kóða fylgja settum reglum
- Kóðinn
- Flyttur kóða
— Skýringar
GraphQL API fyrir WordPress
Viðbót sem veitir GraphQL netþjón fyrir WordPress
- Kóðinn
- Flyttur kóða
— Skýringar

Kostir og gallar við að umbreyta PHP

Ávinningi þess að umbreyta PHP hefur þegar verið lýst: það gerir frumkóðann kleift að nota PHP 8.0 (þ.e. nýjustu útgáfuna af PHP), sem verður breytt í lægri útgáfu fyrir PHP til framleiðslu til að keyra í eldra forriti eða umhverfi.

Þetta gerir okkur í raun kleift að verða betri forritarar og framleiða kóða með meiri gæðum. Þetta er vegna þess að frumkóði okkar getur notað sameindagerðir PHP 8.0, vélritaðar eiginleika PHP 7.4 og mismunandi gerðir og gervigerðir sem bætt er við hverja nýja útgáfu af PHP (mixed frá PHP 8.0, object frá PHP 7.2), meðal annarra nútíma eiginleika PHP.

Með því að nota þessa eiginleika getum við betur náð í villur meðan á þróun stendur og skrifað kóða sem er auðveldara að lesa.

Nú skulum við líta á gallana.

Það verður að vera kóðað og viðhaldið

Rektor getur umbreytt kóða sjálfkrafa, en ferlið mun líklega þurfa handvirkt inntak til að það virki með okkar tilteknu uppsetningu.

Einnig þarf að flytja bókasöfn þriðja aðila

Þetta verður vandamál hvenær sem umbreyting þeirra veldur villum þar sem við verðum síðan að kafa ofan í frumkóðann þeirra til að komast að mögulegri ástæðu. Ef hægt er að laga vandamálið og verkefnið er opinn uppspretta, þurfum við að senda inn beiðni um uppdrátt. Ef bókasafnið er ekki opinn uppspretta gætum við lent í vegtálma.

Rektor lætur okkur ekki vita þegar ekki er hægt að yfirfæra kóðann

Ef frumkóði inniheldur PHP 8.0 eiginleika eða annan eiginleika sem ekki er hægt að yfirfæra, getum við ekki haldið áfram. Hins vegar mun rektor ekki athuga þetta ástand, svo við þurfum að gera það handvirkt. Þetta er kannski ekki stórt vandamál varðandi eigin frumkóða þar sem við þekkjum hann nú þegar, en það gæti orðið hindrun varðandi ósjálfstæði þriðja aðila.

Villuleitarupplýsingar nota yfirfærða kóðann, ekki frumkóðann

Þegar forritið framleiðir villuskilaboð með staflaspori í framleiðslu mun línunúmerið benda á yfirfærða kóðann. Við þurfum að breyta til baka úr yfirfærðum kóða í upprunalegan kóða til að finna samsvarandi línunúmer í frumkóðann.

The Transpiled Kóðinn verður einnig að vera forskeyti

Umbreytt verkefni okkar og annað bókasafn sem einnig er sett upp í framleiðsluumhverfinu gætu notað sömu ósjálfstæði þriðja aðila. Þessi ósjálfstæði þriðja aðila verður yfirfærð fyrir verkefnið okkar og geymir upprunalega frumkóðann fyrir hitt bókasafnið. Þess vegna verður yfirfærða útgáfan að vera með forskeyti með PHP-Scoper, Strauss eða einhverju öðru tóli til að forðast hugsanlega árekstra.

Flutningur verður að eiga sér stað meðan á stöðugri samþættingu stendur (CI)

Vegna þess að umskráði kóðinn mun náttúrulega hnekkja frumkóðann, ættum við ekki að keyra umskráningarferlið á þróunartölvum okkar, annars eigum við á hættu að skapa aukaverkanir. Það hentar betur að keyra ferlið meðan á CI keyrslu stendur (meira um þetta hér að neðan).

Hvernig á að flytja PHP

Fyrst þurfum við að setja upp rektor í þróunarverkefninu okkar:

composer require rector/rector --dev

Við búum svo til a rector.php stillingarskrá í rótarskrá verkefnisins sem inniheldur nauðsynlegar reglur. Til að lækka kóða úr PHP 8.0 í 7.1 notum við þessa stillingu:

use RectorSetValueObjectDowngradeSetList;
use SymfonyComponentDependencyInjectionLoaderConfiguratorContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->import(DowngradeSetList::PHP_80);
    $containerConfigurator->import(DowngradeSetList::PHP_74);
    $containerConfigurator->import(DowngradeSetList::PHP_73);
    $containerConfigurator->import(DowngradeSetList::PHP_72);
};

Til að tryggja að ferlið gangi eins og búist var við getum við keyrt Rector's process skipun í þurrham, framhjá staðsetningu/stöðum til að vinna úr (í þessu tilviki, allar skrár undir möppunni src/):

vendor/bin/rector process src --dry-run

Til að framkvæma umbreytinguna rekum við Rector's process skipun, sem mun breyta skránum á núverandi staðsetningu þeirra:

vendor/bin/rector process src

Vinsamlegast takið eftir: ef við hlaupum rector process í þróunartölvunum okkar verður frumkóðanum breytt á sinn stað, undir src/. Hins vegar viljum við framleiða breytta kóðann á öðrum stað til að hnekkja ekki frumkóðann þegar kóðann er niðurfærður. Af þessum sökum hentar keyrsla ferlisins best við samfellda samþættingu.

Hagræðing á flutningsferlinu

Til að búa til yfirfærða afhendingarvöru fyrir framleiðslu verður aðeins að breyta kóðanum fyrir framleiðslu; Hægt er að sleppa kóða sem þarf aðeins fyrir þróun. Það þýðir að við getum forðast að yfirfæra öll próf (bæði fyrir verkefnið okkar og ósjálfstæði þess) og öll ósjálfstæði fyrir þróun.

Varðandi prófanir munum við nú þegar vita hvar þau fyrir verkefnið okkar eru staðsett - til dæmis undir möppunni tests/. Við verðum líka að komast að því hvar þau fyrir ósjálfstæðin eru - til dæmis undir undirmöppum þeirra tests/, test/ og Test/ (fyrir mismunandi bókasöfn). Síðan segjum við rektor að sleppa því að vinna úr þessum möppum:

return static function (ContainerConfigurator $containerConfigurator): void {
  // ...

  $parameters->set(Option::SKIP, [
    // Skip tests
    '*/tests/*',
    '*/test/*',
    '*/Test/*',
  ]);
};

Varðandi ósjálfstæði, þá veit Composer hverjir eru til þróunar (þeir sem eru undir færslu require-dev in composer.json) og hverjir eru til framleiðslu (þau sem eru undir færslu require).

Til að sækja frá Composer slóðir allra ósjálfstæðna fyrir framleiðslu keyrum við:

composer info --path --no-dev

Þessi skipun mun framleiða lista yfir ósjálfstæði með nafni þeirra og slóð, svona:

brain/cortex                     /Users/leo/GitHub/leoloso/PoP/vendor/brain/cortex
composer/installers              /Users/leo/GitHub/leoloso/PoP/vendor/composer/installers
composer/semver                  /Users/leo/GitHub/leoloso/PoP/vendor/composer/semver
guzzlehttp/guzzle                /Users/leo/GitHub/leoloso/PoP/vendor/guzzlehttp/guzzle
league/pipeline                  /Users/leo/GitHub/leoloso/PoP/vendor/league/pipeline

Við getum dregið út allar slóðir og fóðrað þær inn í rektorsskipunina, sem mun síðan vinna úr verkefninu okkar src/ mappa ásamt þeim möppum sem innihalda allar ósjálfstæði fyrir framleiðslu:

$ paths="$(composer info --path --no-dev | cut -d' ' -f2- | sed 's/ //g' | tr 'n' ' ')"
$ vendor/bin/rector process src $paths

Frekari framför getur komið í veg fyrir að rektor vinni úr þeim ósjálfstæðum sem þegar nota PHP markútgáfuna. Ef bókasafn hefur verið kóðað með PHP 7.1 (eða einhverri útgáfu hér að neðan), þá er engin þörf á að færa það yfir í PHP 7.1.

Til að ná þessu getum við fengið listann yfir bókasöfn sem þurfa PHP 7.2 og nýrri og unnið aðeins úr þeim. Við munum fá nöfn allra þessara bóka í gegnum Composer's why-not skipun, svona:

composer why-not php "7.1.*" | grep -o "S*/S*"

Vegna þess að þessi skipun virkar ekki með --no-dev flagga, til að innihalda aðeins ósjálfstæði fyrir framleiðslu, þurfum við fyrst að fjarlægja ósjálfstæðin fyrir þróun og endurskapa sjálfvirkan hleðslutæki, framkvæma skipunina og bæta þeim svo við aftur:

$ composer install --no-dev
$ packages=$(composer why-not php "7.1.*" | grep -o "S*/S*")
$ composer install

Tónskáld info --path skipun sækir slóðina fyrir pakka, með þessu sniði:

# Executing this command
$ composer info psr/cache --path   
# Produces this response:
psr/cache /Users/leo/GitHub/leoloso/PoP/vendor/psr/cache

Við framkvæmum þessa skipun fyrir alla hluti á listanum okkar til að fá allar leiðir til að umbreyta:

Þarftu hýsingarlausn sem gefur þér samkeppnisforskot? Behmasterer með ótrúlegum hraða, nýjustu öryggi og sjálfvirkri stærðargráðu. Skoðaðu áætlanir okkar

for package in $packages
do
  path=$(composer info $package --path | cut -d' ' -f2-)
  paths="$paths $path"
done

Að lokum sendum við rektor þennan lista (auk verkefnisins src/ mappa):

vendor/bin/rector process src $paths

Gildrur sem þarf að forðast þegar kóða er flutt

Að flytja kóða gæti talist list, sem oft þarfnast lagfæringa sem eru sértækar fyrir verkefnið. Við skulum sjá nokkur vandamál sem við gætum lent í.

Fjötraðar reglur eru ekki alltaf unnar

Hlekkjað regla er þegar regla þarf að umbreyta kóðanum sem framleidd er af fyrri reglu.

Til dæmis bókasafn symfony/cache inniheldur þennan kóða:

final class CacheItem implements ItemInterface
{
  public function tag($tags): ItemInterface
  {
    // ...
    return $this;
  }
}

Þegar umbreyting er frá PHP 7.4 í 7.3, virka tag verður að gangast undir tvær breytingar:

  • Skilategundin ItemInterface verður fyrst að breyta í self, vegna reglu DowngradeCovariantReturnTypeRector
  • Skilategundin self verður þá að fjarlægja, vegna reglu DowngradeSelfTypeDeclarationRector

Lokaniðurstaðan ætti að vera þessi:

final class CacheItem implements ItemInterface
{
  public function tag($tags)
  {
    // ...
    return $this;
  }
}

Hins vegar gefur rektor aðeins út millistigið:

final class CacheItem implements ItemInterface
{
  public function tag($tags): self
  {
    // ...
    return $this;
  }
}

Málið er að rektor getur ekki alltaf stjórnað því í hvaða röð reglum er beitt.

Lausnin er að bera kennsl á hvaða hlekkjaðar reglur voru óunnar og framkvæma nýja rektorskeyrslu til að beita þeim.

Til að bera kennsl á keðjureglurnar keyrum við Rector tvisvar á frumkóðann, svona:

$ vendor/bin/rector process src
$ vendor/bin/rector process src --dry-run

Í fyrsta skiptið keyrum við Rector eins og búist var við, til að framkvæma umbreytinguna. Í annað skiptið notum við --dry-run fána til að komast að því hvort enn eigi eftir að gera breytingar. Ef svo er mun skipunin hætta með villukóða og „diff“ úttakið gefur til kynna hvaða reglu(r) er enn hægt að beita. Það myndi þýða að fyrstu keyrslunni væri ekki lokið, þar sem einhver hlekkjað regla væri ekki afgreidd.

Running Rector með --dry-run flag
Running Rector með –dry-run flag

Þegar við höfum borið kennsl á óbeittu keðjuregluna (eða reglurnar), getum við búið til aðra rektor stillingarskrá - til dæmis, rector-chained-rule.php mun framkvæma regluna sem vantar. Í stað þess að vinna fullt sett af reglum fyrir allar skrár undir src/, að þessu sinni getum við keyrt tiltekna reglu sem vantar á tiltekna skrá þar sem það þarf að beita henni:

// rector-chained-rule.php
use RectorCoreConfigurationOption;
use RectorDowngradePhp74RectorClassMethodDowngradeSelfTypeDeclarationRector;
use SymfonyComponentDependencyInjectionLoaderConfiguratorContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
  $services = $containerConfigurator->services();
  $services->set(DowngradeSelfTypeDeclarationRector::class);

  $parameters = $containerConfigurator->parameters();
  $parameters->set(Option::PATHS, [
    __DIR__ . '/vendor/symfony/cache/CacheItem.php',
  ]);
};

Að lokum segjum við rektor í annarri leið sinni að nota nýju stillingarskrána í gegnum inntak --config:

# First pass with all modifications
$ vendor/bin/rector process src

# Second pass to fix a specific problem
$ vendor/bin/rector process --config=rector-chained-rule.php

Tónskáldaháð getur verið ósamræmi

Bókasöfn gætu lýst því yfir að þeir séu ósjálfstæðir fyrir þróun (þ.e. undir require-dev in composer.json), en samt vísað í einhvern kóða frá þeim til framleiðslu (eins og á sumum skrám undir src/, Ekki tests/).

Venjulega er þetta ekki vandamál vegna þess að kóði gæti ekki verið hlaðinn við framleiðslu, þannig að það verður aldrei villa í forritinu. Hins vegar, þegar rektor vinnur frumkóðann og ósjálfstæði hans, staðfestir hann að hægt sé að hlaða öllum tilvísuðum kóða. Rektor mun kasta villu ef einhver skrá vísar til einhvers kóða frá óuppsettu bókasafni (vegna þess að það var lýst yfir að það væri aðeins nauðsynlegt fyrir þróun).

Til dæmis bekk EarlyExpirationHandler frá Symfony's Cache hluti útfærir viðmót MessageHandlerInterface frá Messenger hluti:

class EarlyExpirationHandler implements MessageHandlerInterface
{
    //...
}

Hins vegar, symfony/cache lýst symfony/messenger að vera háður þróun. Síðan, þegar rekur rektor á verkefni sem veltur á symfony/cache, það mun kasta villu:

[ERROR] Could not process "vendor/symfony/cache/Messenger/EarlyExpirationHandler.php" file, due to:             
  "Analyze error: "Class SymfonyComponentMessengerHandlerMessageHandlerInterface not found.". Include your files in "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.
  See https://github.com/rectorphp/rector#configuration".   

Það eru þrjár lausnir á þessu vandamáli:

  1. Í rektor stillingum, slepptu því að vinna úr skránni sem vísar til þess kóða:
return static function (ContainerConfigurator $containerConfigurator): void {
  // ...

  $parameters->set(Option::SKIP, [
    __DIR__ . '/vendor/symfony/cache/Messenger/EarlyExpirationHandler.php',
  ]);
};
  1. Sæktu bókasafnið sem vantar og bættu við slóð þess til að vera sjálfvirkt hlaðið af rektor:
return static function (ContainerConfigurator $containerConfigurator): void {
  // ...

  $parameters->set(Option::AUTOLOAD_PATHS, [
    __DIR__ . '/vendor/symfony/messenger',
  ]);
};
  1. Láttu verkefnið þitt ráðast af bókasafninu sem vantar til framleiðslu:
composer require symfony/messenger

Umbreyting og stöðug samþætting

Eins og fyrr segir, í þróunartölvum okkar verðum við að nota --dry-run fána þegar Rector er keyrt, eða á annan hátt, verður frumkóðann hnekkt með yfirfærða kóðanum. Af þessum sökum er hentugra að keyra raunverulegt umbreytingarferli meðan á samfelldri samþættingu stendur (CI), þar sem við getum snúið upp tímabundnum hlaupurum til að framkvæma ferlið.

Kjörinn tími til að framkvæma umbreytingarferlið er þegar þú býrð til útgáfuna fyrir verkefnið okkar. Til dæmis er kóðinn hér að neðan verkflæði fyrir GitHub Actions, sem skapar útgáfu WordPress tappi:

name: Generate Installable Plugin and Upload as Release Asset
on:
  release:
    types: [published]
jobs:
  build:
    name: Build, Downgrade and Upload Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Downgrade code for production (to PHP 7.1)
        run: |
          composer install
          vendor/bin/rector process
          sed -i 's/Requires PHP: 7.4/Requires PHP: 7.1/' graphql-api.php
      - name: Build project for production
        run: |
          composer install --no-dev --optimize-autoloader
          mkdir build
      - name: Create artifact
        uses: montudor/action-zip@v0.1.0
        with:
          args: zip -X -r build/graphql-api.zip . -x *.git* node_modules/* .* "*/.*" CODE_OF_CONDUCT.md CONTRIBUTING.md ISSUE_TEMPLATE.md PULL_REQUEST_TEMPLATE.md rector.php *.dist composer.* dev-helpers** build**
      - name: Upload artifact
        uses: actions/upload-artifact@v2
        with:
            name: graphql-api
            path: build/graphql-api.zip
      - name: Upload to release
        uses: JasonEtco/upload-to-release@master
        with:
          args: build/graphql-api.zip application/zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Þetta verkflæði inniheldur staðlað ferli til að gefa út WordPress viðbót í gegnum GitHub Actions. Nýja viðbótin, til að umbreyta kóða viðbótarinnar frá PHP 7.4 í 7.1, gerist í þessu skrefi:

      - name: Downgrade code for production (to PHP 7.1)
        run: |
          vendor/bin/rector process
          sed -i 's/Requires PHP: 7.4/Requires PHP: 7.1/' graphql-api.php

Samanlagt framkvæmir þetta verkflæði nú eftirfarandi skref:

  1. Skoðar frumkóðann fyrir WordPress viðbót úr geymslu þess, skrifað með PHP 7.4
  2. Setur upp Composer ósjálfstæði þess
  3. Flytur kóðann frá PHP 7.4 í 7.1
  4. Breytir færslunni „Krefst PHP“ í haus aðalskráar viðbótarinnar frá "7.4" til "7.1"
  5. Fjarlægir ósjálfstæðin sem þarf til þróunar
  6. Býr til .zip skrá viðbótarinnar, án allra óþarfa skráa
  7. Hleður upp .zip skránni sem útgáfueign (og að auki sem grip í GitHub aðgerðina)

Að prófa yfirfærða kóðann

Þegar kóðinn hefur verið færður yfir í PHP 7.1, hvernig vitum við að hann virkar vel? Eða, með öðrum orðum, hvernig vitum við að það hefur verið rækilega breytt og engar leifar af hærri útgáfum af PHP kóða voru skildar eftir?

Svipað og að flytja kóðann, getum við innleitt lausnina í CI ferli. Hugmyndin er að setja upp umhverfi hlauparans með PHP 7.1 og keyra linter á yfirfærða kóðanum. Ef eitthvert stykki af kóða er ekki samhæft við PHP 7.1 (svo sem vélrituð eign frá PHP 7.4 sem var ekki breytt), þá mun linter henda villu.

Linter fyrir PHP sem virkar vel er PHP Parallel Lint. Við getum sett upp þetta bókasafn sem háð þróun í verkefninu okkar, eða látið CI ferlið setja það upp sem sjálfstætt tónskáldaverkefni:

composer create-project php-parallel-lint/php-parallel-lint

Alltaf þegar kóðinn inniheldur PHP 7.2 og nýrri mun PHP Parallel Lint kasta villu eins og þessari:

Run php-parallel-lint/parallel-lint layers/ vendor/ --exclude vendor/symfony/polyfill-ctype/bootstrap80.php --exclude vendor/symfony/polyfill-intl-grapheme/bootstrap80.php --exclude vendor/symfony/polyfill-intl-idn/bootstrap80.php --exclude vendor/symfony/polyfill-intl-normalizer/bootstrap80.php --exclude vendor/symfony/polyfill-mbstring/bootstrap80.php
PHP 7.1.33 | 10 parallel jobs
............................................................   60/2870 (2 %)
............................................................  120/2870 (4 %)
...
............................................................  660/2870 (22 %)
.............X..............................................  720/2870 (25 %)
............................................................  780/2870 (27 %)
...
............................................................ 2820/2870 (98 %)
..................................................           2870/2870 (100 %)


Checked 2870 files in 15.4 seconds
Syntax error found in 1 file

------------------------------------------------------------
Parse error: layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/graphql-api.php:55
    53|     '0.8.0',
    54|     __('GraphQL API for WordPress', 'graphql-api'),
  > 55| ))) {
    56|     $plugin->setup();
    57| }
Unexpected ')' in layers/GraphQLAPIForWP/plugins/graphql-api-for-wp/graphql-api.php on line 55
Error: Process completed with exit code 1.

Við skulum bæta linter inn í vinnuflæði CI okkar. Skrefin til að framkvæma til að yfirfæra kóða frá PHP 8.0 til 7.1 og prófa hann eru:

  1. Skoðaðu frumkóðann
  2. Láttu umhverfið keyra PHP 8.0, svo rektor geti túlkað frumkóðann
  3. Flytja kóðann yfir í PHP 7.1
  4. Settu upp PHP linter tólið
  5. Skiptu um PHP útgáfu umhverfisins í 7.1
  6. Keyrðu linterinn á yfirfærða kóðanum

Þetta GitHub Action verkflæði vinnur verkið:

name: Downgrade PHP tests
jobs:
  main:
    name: Downgrade code to PHP 7.1 via Rector, and execute tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set-up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.0
          coverage: none

      - name: Local packages - Downgrade PHP code via Rector
        run: |
          composer install
          vendor/bin/rector process

      # Prepare for testing on PHP 7.1
      - name: Install PHP Parallel Lint
        run: composer create-project php-parallel-lint/php-parallel-lint --ansi

      - name: Switch to PHP 7.1
        uses: shivammathur/setup-php@v2
        with:
          php-version: 7.1
          coverage: none

      # Lint the transpiled code
      - name: Run PHP Parallel Lint on PHP 7.1
        run: php-parallel-lint/parallel-lint src/ vendor/ --exclude vendor/symfony/polyfill-ctype/bootstrap80.php --exclude vendor/symfony/polyfill-intl-grapheme/bootstrap80.php --exclude vendor/symfony/polyfill-intl-idn/bootstrap80.php --exclude vendor/symfony/polyfill-intl-normalizer/bootstrap80.php --exclude vendor/symfony/polyfill-mbstring/bootstrap80.php

Vinsamlegast athugaðu að nokkrir bootstrap80.php skrár úr polyfill bókasöfnum Symfony (sem ekki þarf að yfirfæra) verður að útiloka frá linter. Þessar skrár innihalda PHP 8.0, þannig að linter myndi henda villum við vinnslu þeirra. Hins vegar er öruggt að útiloka þessar skrár þar sem þær verða aðeins hlaðnar í framleiðslu þegar PHP 8.0 eða nýrri er keyrt:

if (PHP_VERSION_ID >= 80000) {
  return require __DIR__.'/bootstrap80.php';
}

Hvort sem þú ert að búa til opinbera viðbót fyrir WordPress eða þú ert að uppfæra eldri kóða, þá eru margar ástæður fyrir því að það getur verið ómögulegt að nota nýjustu PHP útgáfuna 👩‍💻 Lærðu hvernig umbreyting getur hjálpað í þessari handbók 👇Smelltu til að kvak

Yfirlit

Þessi grein kenndi okkur hvernig á að umbreyta PHP kóðanum okkar, sem gerir okkur kleift að nota PHP 8.0 í frumkóðann og búa til útgáfu sem virkar á PHP 7.1. Flutningur fer fram í gegnum Rector, PHP endurgerðartæki.

Að flytja kóðann okkar gerir okkur að betri þróunaraðilum þar sem við getum betur náð í villur í þróun og framleitt kóða sem er náttúrulega auðveldara að lesa og skilja.

Transpiling gerir okkur einnig kleift að aftengja kóðann okkar við sérstakar PHP kröfur frá CMS. Við getum nú gert það ef við viljum nota nýjustu útgáfuna af PHP til að búa til almennt aðgengilegt WordPress viðbót eða Drupal mát án þess að takmarka notendagrunn okkar verulega.

Hefur þú einhverjar spurningar eftir um umbreytingu PHP? Láttu okkur vita í athugasemdahlutanum!

tengdar greinar

0 Comments
Inline endurgjöf
Skoða allar athugasemdir
Til baka efst á hnappinn