Från och med 6 December 2018, är den senaste och bästa versionen, PHP 7.3 är här! Med det kommer nya användbara funktioner, avvecklingar, ett bra antal buggfixar och ett uppsving i prestanda. PHP 7.3 är nu också tillgänglig för alla Kinsta-klienter i MyKinsta-panelen. 🤘

Uppdatering: PHP 8.1 (officiell release) finns nu tillgänglig för alla Kinsta-kunder. PHP 7.3 stöds inte längre hos Kinsta. Observera att vi stöder PHP-versionerna 8.0, 8.1, 8.2 och 8.3.

I det här inlägget ger vi en översikt över de funktioner och ändringar som vi personligen anser vara mest relevanta. Men du kan alltid kontrollera den fullständiga listan över funktioner, ändringar och buggfixar i PHP 7.3s uppgraderingsanteckningar och PHP 7.3 Begäran om kommentarer.

Vad är nytt i PHP med PHP 7.3?

I det här inlägget täcker vi följande PHP 7.3-ändringar:

Flexibla Heredoc och Nowdoc Syntaxer

Detta är förmodligen en av de mest relevanta förbättringarna som kommer med PHP 7.3, och vi tycker att den förtjänar lite mer uppmärksamhet. Så, innan vi dyker in i PHP 7.3 heredoc/nowdoc-ändringar, ger vi en snabb översikt över denna användbara kärnfunktion. Om du redan känner dig säker på nowdoc och heredoc, är det bara att hoppa ner till ändringarna i PHP 7.3.

En översikt över heredoc och nowdoc-syntaxer

Heredoc-syntaxen ger ett sätt att lägga till en stor mängd text utan att behöva undvika saker som dubbla citat. En heredoc börjar med <<< följt av en markör och slutar med samma markör följt av ett semikolon. Här är ett exempel:

print <<<EOT
Heredoc text behaves just like a double-quoted string, without the double quotes.
EOT;

En nowdoc beter sig liknande en heredoc, med några undantag:

  • Identifieraren är innesluten i enstaka citattecken (<<<'EOT')
  • Ingen parsning görs inuti en nowdoc

Här är ett exempel på nowdoc:

print <<<'EOT'
Nowdocs are to single-quoted strings what heredocs are to double-quoted strings.
EOT;

Heredocs och nowdocs har samma regler för användningen av stängningsmarkören:

  1. Stängningsmarkören måste börja i radens första kolumn
  2. Markören måste följa samma namnregler som alla andra etiketter i PHP: den måste innehålla endast alfanumeriska tecken och understreck, och måste börja med ett icke-siffrigt tecken eller understreck.

PHP-manualen varnar:

Det är mycket viktigt att notera att raden med stängningsidentifieraren inte får innehålla några andra tecken, förutom ett semikolon (;). Det betyder särskilt att identifieraren inte får vara indragen, och det får inte finnas några mellanslag eller tabbar före eller efter semikolonet. Det är också viktigt att inse att det första tecknet före stängningsidentifieraren måste vara en ny rad enligt hur det definieras av det lokala operativsystemet. Det är \n på UNIX-system, inklusive macOS. Den avslutande avgränsaren måste också följas av en ny rad.

PHP 7.2 ogiltig syntax:

class foo {
    public $bar = <<<EOT
    bar
    EOT;
}
// Identifier must not be indented

PHP 7.2 giltig syntax:

class foo {
    public $bar = <<<EOT
bar
EOT;
}

För att hålla det kort, i PHP 7.2:

  • Får inte stängningsmarkören vara indragen
  • Får inte raden med stängningsmarkören innehålla tecken som mellanslag eller tabbar
  • Måste det första tecknet före stängningsmarkören vara en ny rad
  • Måste stängningsmarkören följas av en ny rad

Det är tillräckligt tydligt att heredoc och nowdoc-syntaxer är ganska restriktiva, men PHP 7.3 kan ändra detta lite med följande förbättringar.

1. Låt stängningsmarkören vara indragen och tillåt att det ledande blanksteget tas bort.

Med PHP 7.3 får vi flytta in stängningsmarkören, och vi kan säkert skriva följande kod:

class foo {
    public $bar = <<<EOT
        bar
    EOT;
}

Indragningen av stängningsmarkören anger mängden blankslag (eller tabbar) som kommer att tas bort från varje rad i kroppen. Men var försiktig: stängningsmarkören bör aldrig vara indragen längre än någon annan rad i kroppen.

Se koden nedan:

class foo {
    public $bar = <<<EOT
    bar
        EOT;
}

Koden ovan skulle ge följande parsningsfel:

Parse error: Invalid body indentation level (expecting an indentation at least ...) in %s on line %d

Att ta bort tabbar och blanksteg låter oss dra in kroppen till heredoc/nowdoc till samma nivå som koden runtomkring dem, och utan onödiga blanksteg före varje rad i kroppen.

Vi kan använda både tabbar och blanksteg för indrag, men vi får inte blanda dem. Det innebär att vi måste använda samma indragningstecken för stängningsmarkören och alla rader i kroppen. Vid olika indragningstecken förväntar vi oss en annan typ av parsefel (ogiltig indrag).

2. Ta bort det avslutande ny rad-kravet från stängningsmarkören

För närvarande måste en ny rad följa markören för att avsluta heredoc/nowdoc. PHP 7.3 skulle ändra detta och skulle tillåta oss att avsluta heredoc/nowdoc på samma rad. Här är ett exempel från RFC:

PHP 7.2 giltig syntax:

$values = [<<<END
a
b
c
END
, 'd e f'];

PHP 7.3 giltig syntax:

$values = [<<<END
a
b
c
END, 'd e f'];

Hur som helst, var försiktig när du väljer namnet på din markör eftersom det ibland kan ske ett fel, om det matchar ett ord du använde i kroppen för heredoc/nowdoc (läs mer om detta på RFC och GitHub).

Båda förslagen antogs med mer än 2/3 röster.

PHP 7.3 RFC

Ytterligare resurser

Tillåt ett avslutande kommatecken i funktionsanrop

Avslutande kommatecken (eller ”slutliga kommatecken”) är kommatecken som läggs till i en lista över element, parametrar eller egenskaper och de kommer till nytta i sammanhang där nya värden läggs till ofta eftersom de förhindrar fel på grund av ett saknat kommatecken. I PHP är avslutande kommatecken tillåtna i arrayer, och från och med PHP 7.2 är de tillåtna i grupperade namnområden.

Från och med PHP 7.3 skulle avslutande kommatecken tillåtas i funktionsdeklarationer. Variadiska funktioner ger ett exempel på sammanhang där avslutande kommatecken är extremt användbara:

foo(
    $bar,
    $baz,
);

Vi kan använda ett avslutande kommatecken när vi skapar en array med compact(), för att returnera en formaterad sträng med sprintf(), eller vid sammanslagning av en array:

$newArray = array_merge(
    $arrayOne,
    $arrayTwo,
    ['foo', 'bar'],
);

Avslutande kommatecken skulle också vara användbara för felsökning:

var_dump(
    $foo,
    $bar,
    $baz,
);

Och de är kraftfulla med unset() och isset():

unset(
    $foo,
    $bar,
    $baz,
);

isset(
    $foo,
    $bar,
    $baz,
);

Avslutande kommatecken kommer också att tillåtas i metodanrop och kapslingar.

Observera: Denna ändring skulle endast påverka funktionsanrop. Syntaxen för funktionsdeklarationer ändras inte. Dessutom kommer fristående kommatecken, flera avslutande kommatecken och ledande kommatecken inte att tillåtas.

Ytterligare exempel finns på RFC-sidan. Denna RFC gick igenom med 30 röster mot 10.

PHP 7.3 RFC

JSON_THROW_ON_ERROR

En av de mest uppskattade funktionerna som kommer med PHP 7.3 är ett nytt sätt att hantera JSON-fel. Detta är inte en kärnfunktion, utan ett tillägg till JSON-tillägget som skulle ändra json_decode() och json_encodes()s felbeteende.

För närvarande returnerar json_decode() null vid fel, men null kan också vara ett giltigt resultat. Detta kan vara förvirrande, eftersom:

Det är bara möjligt att veta om ett fel uppstod genom att anropa json_last_error() eller json_last_error_msg(), som returnerar det globala feltillståndet i maskinläsbara respektive mänskligt läsbara former. – PHP RFC

json_encode() returnerar FALSE vid fel. Detta är tydligare eftersom det finns ett specifikt felvärde. Hur som helst, båda funktionerna stoppar inte programexekvering vid fel eller ger någon varning.

Med detta sagt, här är förslaget till PHP 7.3:

Denna RFC föreslår istället att lägga till ett nytt alternativ flaggvärde för json_decode() och json_encode(), JSON_THROW_ON_ERROR. När den här flaggan har fått godkänt ändras felbeteendet för dessa funktioner. Det globala feltillståndet lämnas orört, och om ett fel uppstår som annars skulle orsaka det, ger dessa funktioner istället en JsonException med meddelandet och koden inställd på vad json_last_error() respektive json_last_error_msg() annars skulle vara.

Här är ett exempel som visar ett enkelt sätt att visa ett JSON-fel:

try {
    json_decode("{", false, 512, JSON_THROW_ON_ERROR);
}
catch (\JsonException $exception) {
    echo $exception->getMessage(); // echoes "Syntax error"
}

Att orsaka ett undantag vid fel skulle ge flera fördelar som du hittar listade i RFC:n.

Obs! en ogiltig djupparameter som skickas till json_decode() matar ut en varning och returnerar NULL. Detta beteende påverkas inte av JSON_THROW_ON_ERROR. På samma sätt påverkas inte parameterparseringsfel av JSON_THROW_ON_ERROR och fortsätter att producera varningar.

Detta förslag antogs med 23 röster mot 0.

PHP 7.3 RFC

Ytterligare resurser

list() Referenstilldelning

Vad Betyder Referenstilldelning?

Beakta följande rad:

$b = &$a;

Här får $b värdet av $a, men det värdet kopieras inte från $a till $b. I PHP kan vi tilldela ett värde som referens, vilket innebär att två variabler kan peka på samma data, och varje ändring av en variabel påverkar originaldata. Här är ett exempel från PHP-manualen:

<?php
$a = 3;
$b = &$a; // $b is a reference to $a

print "$a\n"; // prints 3
print "$b\n"; // prints 3

Låt oss nu ändra värdet på $a:

$a = 4; // change $a

print "$a\n"; // prints 4
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has been changed

Vad är list()-konstruktionen och hur ändras det med PHP 7.3

Språkkonstruktionen list() kan användas för att ”tilldela variabler som om de var i en array”, men med list() får vi för närvarande inte tilldela variabelvärden genom referens.

PHP 7.3 kommer ändra detta så att vi kan tilldela variabler genom referens även med list()-konstruktionen, som visas i följande exempel:

$array = [1, 2];
list($a, &$b) = $array;

Vilket är detsamma som:

$array = [1, 2];
$a = $array[0];
$b =& $array[1];

Fördelen med detta förslag är att vi nu kan tilldela flera variabler som referens, vilket för närvarande inte är tillåtet. Fler exempel finns på RFC. Detta förslag antogs med 20 röster mot 7.

PHP 7.3 RFC

Ytterligare resurser

is_countable-funktion

En annan användbar funktion som kommer med PHP 7.3 är funktionen is_countable(). Fram till PHP 7.2 får vi ett fel när vi försöker count() något som inte kan räknas. För att undvika en varning är vi av denna anledning tvungna att lägga till följande kod:

if (is_array($foo) || $foo instanceof Countable) {
    // $foo is countable
}

Denna RFC föreslår funktionen is_countable(), som returnerar sant om den givna variabeln är en array eller om det är en räkningsbar variabel, annars falskt. Koden ovan kan då ändras enligt följande:

if (is_countable($foo)) {
    // $foo is countable
}

Detta förslag antogs med 23 röster mot 0.

PHP 7.3 RFC

Ytterligare resurser

array_key_first(), array_key_last()

För närvarande kan vi hämta den första och sista nyckeln i en array med hjälp av funktionerna reset(), end() och key(). Med dessa funktioner finns det tyvärr inget sätt att hämta det första eller sista indexet för en array utan att ändra dess interna tillstånd. Andra alternativ minskar vanligtvis kodläsbarhet och prestanda.
Detta förslag skulle ändra detta scenario genom att lägga till två nya funktioner till PHP-kärnan:

  • array_key_first()
  • array_key_last()

Från och med PHP 7.3 tillåter array_key_first() och array_key_last() hämtning av den första och sista nyckeln i en given array utan att påverka den interna array-pekaren. Dessa nya funktioner skulle göra det möjligt för oss att skriva mindre komplex kod och i vissa fall undvika fel. Se RFC för ytterligare information och flera exempel.

array_key_first() och array_key_last() har godkänts med 18 mot 14 röster.

Obs! den ursprungliga RFC föreslog ytterligare två funktioner, array_value_first() och array_value_last(), som röstades om i en annan omröstning, men de har inte godkänts och kommer inte att bli en del av PHP-kärnan.

PHP 7.3 RFC

Ytterligare resurser

Förbättringar till Argon2 Password Hash

Argon2 är en hashingalgoritm som implementerades i PHP 7.2 som ett alternativ till Bcrypt-algoritmen. PHP 7.2 introducerade PASSWORD_ARGON2I-konstanten, tillgänglig för att användas i password_*-funktioner:

password_hash('password', PASSWORD_ARGON2I);

Sedan dess första implementering har en ny variant av Argon2 lagts till, så i skrivande stund kommer Argon2 i tre varianter:

  • Argon2d maximerar resistens mot GPU cracking-attacker. Det är snabbare och använder data-beroende minnesåtkomst.
  • Argon2i använder data-oberoende minnesåtkomst, vilket är att föredra för lösenord hashing. Det är långsammare eftersom det gör fler passeringar över minnet för att skydda mot tradeoff-attacker.
  • Argon2id är en hybridversion som kombinerar Argon2i-tillvägagångssättet för första passeringen över minnet och Argon2d-tillvägagångssättet för efterföljande passeringar.

Argon2id rekommenderas på Internet, förutom när det finns goda skäl att specifikt föredra en annan variant.

Den nya RFC föreslår införande av Argon2id inom password_* -funktioner med den nya PASSWORD_ARGON2ID-konstanten:

password_hash('password', PASSWORD_ARGON2ID);

Genomförandet är identiskt med Argon2i-implementeringen och kommer att acceptera samma kostnadsfaktorer:

  • En minneskostnad som definierar antalet kb som ska förbrukas under hashing (standardvärdena är 1<<10, eller 1024 kb, eller 1 mb)
  • En tidskostnad som definierar antalet iterationer av hashing-algoritmen (standard 2)
  • En parallellismfaktor, som anger antalet parallella trådar som ska användas under hashing (standard 2)

Se följande kod:

$options = ['memory_cost' => 1<<11, 'time_cost' => 4, 'threads' => 2];
password_hash('password', PASSWORD_ARGON2ID, $options);

Mer information och exempel på RFC.

PHP 7.3 RFC

Ytterligare resurser

Avvecklingar

Följande funktioner kommer att avvecklas med PHP 7.3 och tas bort senast i PHP 8.0.

Avveckla och ta bort image2wbmp()

Funktionen image2wbmp() matar ut eller sparar en WBMP-version av en given bild. Den här funktionen kräver tre argument: en bildresurs, ett filnamn (sökvägen till den sparade filen) och en förgrundsfärg. Från och med PHP 5.0 är det identiskt med imagewbmp(), så denna RFC föreslår att avveckla och ta bort den. Sedan PHP 7.3 skulle varje anrop till image2wbmp() visa en avvecklingsvarning. Efter borttagningen skulle varje anrop ge ett allvarligt fel.

PHP 7.3 RFC

Avveckla och ta bort konstanter som inte är skiftlägeskänsliga

PHP stöder för närvarande både skiftlägeskänsliga och icke-skiftlägeskänsliga konstanter. Icke-skiftlägeskänsliga konstanter stöds men anses riskera inkonsekvenser i funktioner och att vara komplexa att använda.
Detta förslag börjar med följande förutsättningar:

  • klasskonstanter är alltid skiftlägeskänsliga
  • globala konstanter som deklareras med const är alltid skiftlägeskänsliga
  • konstanter som definieras med define() är skiftlägeskänsliga som standard

Dessutom anger PHP Language Reference uttryckligen:

En konstant är skiftlägeskänslig som standard. Vanligtvis är konstantidentifierare alltid i versaler.

Med detta sagt föreslår denna RFC följande ändringar:

  • Avveckla att anropa define() med tredje parametern inställd på sant – PHP 7.3
  • Avveckla åtkomst till icke-skiftlägeskänsliga konstanter med ett skiftläge som skiljer sig från deklarationen (med undantag för sant, falskt och null) – PHP 7.3
  • Ta bort möjligheten att förklara icke-skifteskänsliga konstanter – PHP 8.0
  • Konvertera sant, falskt och null från konstanter med speciella skiftlägen till reserverade sökord – PHP 8.0

PHP 7.3 RFC

Avveckla och ta bort konstanter som inte är skiftlägeskänsliga.

Ytterligare avvecklingar för PHP 7.3

Här är en snabb lista över funktioner som avvecklas i PHP 7.3. Den är inte uttömmande, de är bara de avvecklingsförslag jag personligen anser är mest relevanta. För en fullständig lista över föreslagna avvecklingar, se Avvecklingar för PHP 7.3.

Odokumenterade mbstring-funktionsalias: det finns ett antal odokumenterade mbstring-funktionsalias som är dubbletter av likvärdiga funktioner med mb_-prefix. mbereg är till exempel ett alias för mb_ereg.
Alla dessa funktioner skulle markeras som avvecklade och ett avvecklingsmeddelande skulle visar när de uppstår under kompilering.

Strängsökningsfunktioner med heltalsnål: dessa funktioner opererar vanligtvis på strängnålar. Om en icke-strängnål anges konverteras den till ett heltal och tillämpas som ordningsvärdet för ett tecken (Läs mer i PHP-manualen). Här är ett exempel från RFC:

$str = "There are 10 apples";
var_dump(strpos($str, "10")); // int(10)
var_dump(strpos($str, 10));   // bool(false)

Detta anses vara förvirrande och orsaka oförutsägbara problem eftersom typen kan ändras med användardatans källa. Av denna anledning föreslår RFC en avvecklingsvarning om en icke-strängnål överförs till en av följande funktioner:

  • strpos
  • strrpos
  • stripos
  • strripos
  • strstr
  • strchr
  • strrchr
  • stristr

I PHP 8.0 ska avvecklingsvarningen tas bort och nålarna ska automatiskt omvandlas till strängar.

fgetss()-funktionen och string.strip_tags-strömfilterfgetss() och string.strip_tags-striptaggarna formar en ström när de läses. Både funktionen och filtret exponerar strip_tags()-funktionaliteten vilket gör implementeringen av strip_tags() mer komplex, eftersom en strömtillståndsmaskin krävs. Dessutom påpekar RFC en annan nackdel med dessa funktioner:

Å andra sidan verkar dessa funktioner vara av mycket liten nytta. Själva strip_tags(), på grund av dess begränsningar och kända buggar, har redan mycket få legitima användningar. Det finns inget behov av att ge inbyggt stöd för strömanvändning ovanpå det.

Så RFC föreslår att markera fgetss(), gzgetss() och SplFileObject::fgetss() som avvecklade.

Vad betyder PHP 7.3 för WordPress-användare?

Enligt den officiella WordPress-statistiksidan, har i skrivande stund endast 32,9% av WordPress användare uppgraderat till PHP 7 eller högre. Bara 4% använder PHP 7.2. Du kan se att en stor majoritet av användarna, över 38%, fortfarande kör PHP 5.6. Vad som är ännu läskigare är att över 28,5% av användarna använder PHP-versioner som inte längre stöds. I December 2016 höjde faktiskt WordPress.org sin officiella rekommendation för användare från PHP 5.6 till PHP 7 eller högre.

WordPress PHP-versioner
WordPress PHP-versioner

PHP 7 Prestanda

Siffrorna ovan är särskilt skrämmande från en prestandasynpunkt, eftersom PHP 7 har visat sig vara betydligt snabbare. Här är lite statistik:

  • Officiella PHP-riktmärken visar att PHP 7 tillåter systemet att utföra dubbelt så många förfrågningar per sekund jämfört med PHP 5.6, med nästan hälften så mycket latens.
  • Christian Vigh publicerade också en PHP prestandajämförelse där han fann att PHP 5.2 var 400% långsammare än PHP 7.

Vi körde våra egna PHP prestanda-benchmarks. Och liknande resultaten ovan såg vi att WordPress 5.0 på PHP 7.3 kunde utföra nästan tre gånger så många transaktioner (förfrågningar) per sekund jämfört med PHP 5.6.

WordPress 5.0 PHP benchmarks
WordPress 5.0 PHP benchmarks
  • WordPress 5.0 PHP 5.6 benchmark: 91.64 förfrågningar/s
  • WordPress 5.0 PHP 7.0 benchmark-resultat: 206.71 förfrågningar/s
  • WordPress 5.0 PHP 7.1 benchmark-resultat: 210.98 förfrågningar/s
  • WordPress 5.0 PHP 7.2 benchmark-resultat: 229.18 förfrågningar/s
  • WordPress 5.0 PHP 7.3 benchmark-resultat: 253.20 förfrågningar/s 🏆

Det är också intressant att notera att WordPress 4.9.8 på PHP 7.3 var något snabbare än WordPress 5.0.

WordPress 4.9.8 PHP benchmarks
WordPress 4.9.8 PHP benchmarks
  • WordPress 4.9.8 PHP 5.6 benchmark: 97.59 förfrågningar/s
  • WordPress 4.9.8 PHP 7.0 benchmark-resultat: 221.42 förfrågningar/s
  • WordPress 4.9.8 PHP 7.1 benchmark-resultat: 233.78 förfrågningar/s
  • WordPress 4.9.8 PHP 7.2 benchmark-resultat: 250.36 förfrågningar/s
  • WordPress 4.9.8 PHP 7.3 benchmark-resultat 276.31 förfrågningar/s 🏆

Många är långsamma att uppdatera helt enkelt på grund av den tid som krävs för att testa alla sina tredjeparts plugins och teman för att säkerställa att de fungerar korrekt. Men många gånger handlar det om att de helt enkelt inte satt igång.

Kontrollera Din PHP-Version

Inte säker på vilken version av PHP du kör? Ett av de enklaste sätten att kontrollera är att använda ett verktyg som Pingdom eller Google Chrome Devtools. Den första HTTP-rubriken visar vanligtvis versionen.

Kontrollera PHP-version
Kontrollera PHP-version

Detta bygger på att värden inte ändrar X-Powered-By-rubrikvärdet. Om de gör det kanske du inte ser din PHP-version. I så fall kan du installera ett gratis plugin som Version Info som visar dig grundläggande serverinformation i sidfoten på din WordPress-panel.

Kontrollera PHP-versionen i WordPress
Kontrollera PHP-versionen i WordPress

Alternativt kan du också ladda upp en fil via FTP för att se din PHP-version, eller ta kontakt med din värd och fråga.

Uppdatering till PHP 7.3

Den slutliga versionen av PHP 7.3 är här och du kan börja testa den direkt. Du kan testa din WordPresswebbplats lokalt eller kontrollera dina skript i en miljö som Docker, som låter dig testa olika versioner av PHP från kommandoraden.

Annars kan du använda en stagingmiljö på Kinsta, eftersom detta kommer att likna en live-produktionsplats mycket mer. Skapa en stagingmiljö med några enkla klick i MyKinsta-panelen.

WordPress stagingmiljö
WordPress stagingmiljö

Vi rekommenderar alltid att du testar noggrant innan du använder det på en produktionswebbplats. För att göra det kan du helt enkelt ändra PHP-motorn för staging-webbplatsen under ”Verktyg” och du kan börja testa för att säkerställa kompatibiliteten hos dina tredjeparts plugin och teman.

Byt till PHP 7.3
Byt till PHP 7.3

När du har bekräftat allt fungerar kan du antingen ändra din produktionswebbplats till PHP 7.3 eller om du har gjort några ändringar, tryck också på att ta din staging-webbplats live.

Sammanfattning

Den senaste och bästa versionen av PHP är här. Den ger oss gåvor som flexibla heredocs och nowdocs, avslutande kommatecken i funktionssamtal, list() referenstilldelning och mer. I det här inlägget har vi gett dig en översikt över våra favoritförbättringar och förändringar, men vi skulle också vilja veta vilka dina favoriter är, och på vilka sätt du kommer utnyttja dem. Låt oss veta i kommentarerna nedan! Och glöm inte bort att PHP inte är dött!

Du hittar den fullständiga listan över PHP 7.3-förslag på Begäran om kommentarer-sidan och GitHubs PHP 7.3 Uppgraderingsanteckningar.

Carlo Daniele Kinsta

Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.