Menu

Domande colloquio PHP con risposte (PHP 8)

24 domande da colloquio PHP con risposte brevi e corrette per PHP 8, da == vs === e isset vs empty ai riferimenti in foreach, self vs static, generatori, SQL injection e hashing delle password. La maggior parte delle risposte ha codice che puoi eseguire e modificare.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Queste sono le domande PHP che compaiono più spesso nei colloqui, con risposte brevi corrette per PHP 8.3 e codice dove il codice chiarisce il punto. Prevedi l'output di ogni blocco prima di premere Run: è proprio ciò che verifica chi ti fa il colloquio.

Domande da colloquio PHP di base

Cos'è PHP e come viene eseguito?

PHP è un linguaggio di scripting lato server. Un server web (Nginx o Apache) passa la richiesta a PHP (di solito PHP-FPM), PHP esegue lo script dall'inizio, e ciò che stampa diventa la risposta, di solito HTML. Ogni richiesta riparte da zero: le variabili non sopravvivono tra una richiesta e l'altra a meno che tu non le salvi in una sessione, in un database o in una cache. PHP esegue anche script dalla riga di comando (php script.php).

Qual è la differenza tra == e ===?

== confronta dopo la conversione di tipo, === confronta valore e tipo senza conversioni. Il riscaldamento qui sopra mostra == al lavoro: le stringhe numeriche vengono confrontate come numeri, quindi '10' == '1e1' è true. Da PHP 8, un numero confrontato con una stringa non numerica viene confrontato come stringa, quindi 0 == 'a' è false (in PHP 7 era true). Tocca le celle per confrontare i due operatori:

Confronto debole (==) e stretto (===)
Point at or tap a cell to read it as PHP.
$a == $btruefalse01"0""1"""null[]"a""10""1e1"
true
false
0
1
"0"
"1"
""
null
[]
"a"
"10"
"1e1"
Every cell computed by PHP 8.3.19.

Usa === di default. in_array() e array_search() usano == a meno che tu non passi true come terzo argomento.

Qual è la differenza tra echo e print?

Entrambi stampano stringhe. echo accetta più argomenti (echo $a, $b;) e non restituisce nulla; print ne accetta uno e restituisce 1, quindi si può usare in un'espressione. Nessuno dei due è una funzione, quindi le parentesi sono facoltative. In pratica tutti usano echo.

Apici singoli o virgolette doppie?

Le stringhe tra virgolette doppie interpolano variabili e sequenze di escape: "Hi $name\n". Le stringhe tra apici singoli sono letterali tranne \' e \\: 'Hi $name\n' stampa esattamente quei caratteri. La differenza di velocità è trascurabile, quindi la scelta riguarda la leggibilità: virgolette doppie quando interpoli, apici singoli quando non lo fai.

Quali sono i tipi di dati in PHP?

Quattro tipi scalari (int, float, string, bool), due tipi composti (array e object) e due speciali (null e resource). callable, iterable, mixed e void esistono solo come dichiarazioni di tipo, mai come tipo di un valore. gettype() e get_debug_type() ti dicono il tipo di un valore a runtime, e var_dump() lo stampa insieme al valore.

Qual è la differenza tra isset, empty e is_null?

isset($x) è true quando la variabile esiste e non è null. empty($x) è true quando la variabile non esiste o è falsy (0, '0', '', [], false, null). is_null($x) è true per null, ma genera un warning su una variabile non definita. isset ed empty non generano mai warning, ed è per questo che si usano sulle chiavi degli array.

isset, empty e is_null per ogni valore di $x
Point at or tap a cell to read it as PHP.
$xissetemptyis_null
null
false
0
"0"
""
" "
[]
"a"
0.0
Every cell computed by PHP 8.3.19.

La riga che si sbaglia è "0": la stringa zero è vuota, mentre " " (uno spazio) non lo è. La pagina su isset ha la tabella completa.

Qual è la differenza tra include e require?

Entrambi inseriscono ed eseguono un altro file. Se il file manca, include genera un warning e lo script prosegue, mentre require lancia un Error ("Failed opening required"), che ferma lo script a meno che qualcosa non lo catturi. Le varianti _once (include_once, require_once) saltano un file già caricato, il che evita gli errori "cannot redeclare function". Usa require (o require_once) per i file senza cui lo script non può girare, cioè quasi tutti; l'autoloader di Composer rende superflua la maggior parte degli include manuali.

Qual è la differenza tra GET e POST?

GET invia i dati nella query string dell'URL ($_GET), quindi sono visibili, salvabili nei preferiti e limitati in lunghezza; usalo per leggere, come ricerca e paginazione. POST invia i dati nel corpo della richiesta ($_POST); usalo per tutto ciò che cambia lo stato, come login, salvataggi o pagamenti. Una richiesta GET non deve mai modificare dati, perché i link vengono precaricati e scansionati dai crawler.

Cos'è l'operatore null coalescing?

$a ?? $b restituisce $a se esiste e non è null, altrimenti $b, senza warning per una variabile o una chiave non definita: $page = $_GET['page'] ?? 1;. ??= assegna solo quando il lato sinistro è null o manca. Differisce da ?:, che ripiega su qualsiasi valore falsy, quindi 0 ?: 5 vale 5 ma 0 ?? 5 vale 0.

Domande da colloquio PHP di livello intermedio

Cosa succede quando scorri per riferimento in foreach?

foreach ($arr as &$v) ti permette di modificare gli elementi sul posto, ma dopo il ciclo $v resta un riferimento all'ultimo elemento. Riusare il nome in un secondo ciclo sovrascrive allora quell'elemento:

L'ultimo elemento è 20, non 30: durante il secondo ciclo, a $v (ancora $arr[2]) viene assegnato 10, poi 20, poi se stesso. Togli il // prima di unset($v) ed eseguilo di nuovo. La pagina su foreach tratta i riferimenti in dettaglio.

Qual è la differenza tra una classe astratta e un'interfaccia? E cos'è un trait?

Un'interfaccia è un contratto: firme di metodi (e costanti) senza implementazione, e una classe può implementarne molte. Una classe astratta può contenere proprietà, costruttori e metodi completi, più metodi astratti che le figlie devono scrivere; una classe ne estende una sola. Un trait è un insieme di metodi copiati in una classe con use, per riusare codice tra classi che non hanno un padre comune.

Una risposta breve che piace a chi fa il colloquio: usa un'interfaccia per dire cosa sa fare qualcosa, una classe astratta per condividere come lo fa, e un trait quando classi non correlate hanno bisogno degli stessi pochi metodi.

Qual è la differenza tra self e static?

self si riferisce alla classe in cui il codice è scritto. static si riferisce alla classe effettivamente chiamata a runtime, ed è il cosiddetto late static binding. Conta nei metodi del padre che creano o descrivono "questo tipo di oggetto":

User::createStatic() costruisce uno User. User::createSelf() costruisce un Model, che viola il tipo restituito static, quindi PHP lancia un TypeError. Ecco perché i metodi factory usano new static().

Cosa sono i metodi magici?

Metodi che PHP chiama per te, tutti con due underscore iniziali. I più comuni: __construct() quando un oggetto viene creato, __destruct() quando viene distrutto, __toString() quando viene usato come stringa, __get() e __set() per le proprietà inaccessibili, __call() e __callStatic() per i metodi mancanti, __invoke() quando l'oggetto viene chiamato come una funzione, e __clone() dopo clone.

Qual è la differenza tra array_merge() e l'operatore +?

array_merge() accoda: le chiavi numeriche vengono rinumerate e le chiavi stringa successive sovrascrivono le precedenti. + è un'unione: mantiene l'array di sinistra e aggiunge solo le chiavi mancanti, quindi per una chiave duplicata vince il primo valore.

+ è lo strumento giusto per i default: $options + ['timeout' => 30] mantiene ciò che ha passato chi chiama e completa il resto.

Cosa fa declare(strict_types=1)?

Senza, PHP converte gli argomenti scalari nel tipo del parametro dichiarato quando può: passare "5" a un parametro int dà 5. Con declare(strict_types=1); come prima istruzione di un file, le chiamate fatte da quel file devono passare il tipo esatto, altrimenti viene lanciato un TypeError (un int passato a un parametro float è l'unico ampliamento consentito).

Cancella la riga declare ed eseguilo di nuovo: la seconda chiamata restituisce 10 invece di lanciare un errore.

Un cookie viene salvato nel browser e inviato con ogni richiesta, quindi il visitatore può leggerlo e modificarlo. Una sessione salva i dati sul server e tiene solo un id casuale in un cookie (PHPSESSID). Metti in $_SESSION tutto ciò che deve essere affidabile, come l'id dell'utente autenticato; dopo il login, chiama session_regenerate_id(true). La pagina su sessioni e cookie ha il codice.

Come si previene la SQL injection?

Non costruire mai l'SQL concatenando l'input. Usa i prepared statement, così i valori vengono inviati separatamente dalla query:

<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch();

I segnaposto funzionano solo per i valori. Nomi di tabelle, nomi di colonne e ASC/DESC vanno verificati con un elenco consentito prima di entrare nell'SQL. Vedi PDO.

Come si previene l'XSS?

Applica l'escape all'output, non all'input: racchiudi ogni valore stampato nell'HTML in htmlspecialchars($value, ENT_QUOTES, 'UTF-8'), oppure usa un motore di template che lo fa automaticamente (Twig, Blade). Dentro <script>, usa json_encode() con JSON_HEX_TAG. Aggiungi un'intestazione Content-Security-Policy come secondo livello.

Come vanno salvate le password?

Con password_hash($password, PASSWORD_DEFAULT) e verificate con password_verify($password, $hash). Usano bcrypt (o Argon2id) con un salt casuale salvato dentro l'hash e un cost voluto. md5() e sha1() sono sbagliati per le password perché sono veloci e senza salt. Usa password_needs_rehash() al login per aggiornare i vecchi hash.

Domande da colloquio PHP di livello avanzato

Cosa sono i generatori e quando ne useresti uno?

Una funzione che contiene yield restituisce un Generator che produce valori uno alla volta, solo quando vengono chiesti. Ti permette di scorrere una sequenza grande o infinita senza costruire un array in memoria:

Gli usi tipici sono leggere un file grande riga per riga, trasmettere righe di un database e pipeline pigre. I generatori supportano anche le chiavi (yield $key => $value), la delega (yield from) e la ricezione di valori con send().

Cosa sono le closure, e cosa fa use?

Una funzione anonima (function () { ... }) è un oggetto Closure. Non vede le variabili esterne a meno che tu non le elenchi in use, che copia il valore nel momento in cui la closure viene creata; use (&$x) cattura invece per riferimento. Le arrow function (fn ($x) => $x * $factor) catturano automaticamente le variabili esterne, per valore, e contengono una sola espressione.

Qual è la differenza tra abstract, final e readonly?

abstract indica una classe che non può essere istanziata, o un metodo che una figlia deve implementare. final vieta di sovrascrivere un metodo o di estendere una classe. readonly (PHP 8.1) rende una proprietà scrivibile una sola volta, dall'interno della classe, di solito nel costruttore; PHP 8.2 ha aggiunto le classi readonly, in cui ogni proprietà è readonly.

Cos'è Composer, e cos'è PSR-4?

Composer è il gestore di dipendenze di PHP: composer.json elenca i pacchetti, composer.lock fissa le versioni esatte e vendor/autoload.php carica tutto. PSR-4 è lo standard di autoloading che associa un prefisso di namespace a una cartella, quindi App\Mail\Mailer si trova in src/Mail/Mailer.php e viene caricato al primo uso. Spiega install (dal file di lock) contro update (nuove versioni, nuovo file di lock).

Cosa è cambiato in PHP 8?

Le novità principali: nella 8.0, argomenti con nome, match, l'operatore nullsafe ?->, union type, promozione delle proprietà nel costruttore, attributi, str_contains() e un confronto stringa numero più sensato; nella 8.1, enum, proprietà readonly, sintassi first-class callable (strlen(...)) e fiber; nella 8.2, classi readonly e i tipi autonomi null/true/false; nella 8.3, costanti di classe tipizzate, l'attributo #[\Override] e json_validate(); nella 8.4, property hooks, visibilità asimmetrica (public private(set)), array_find() e new Foo()->method() senza parentesi intorno. Molte funzioni inoltre ora lanciano TypeError o ValueError invece di restituire false con un warning.

Come gestisce la memoria PHP?

Ogni valore ha un contatore di riferimenti; quando scende a zero, la memoria viene liberata subito. Gli oggetti che si riferiscono l'uno all'altro in un ciclo non arrivano mai a zero, quindi un raccoglitore di cicli interviene ogni volta che il suo buffer di possibili radici di ciclo si riempie (10.000 voci di default) e li libera (gc_collect_cycles() lo esegue su richiesta). Array e stringhe sono copy-on-write: assegnare $b = $a condivide i dati finché uno dei due non viene modificato. Dato che ogni richiesta inizia e finisce in modo pulito, i memory leak contano soprattutto nei worker di lunga durata e nei consumatori di code.

Come sono implementati gli array PHP?

Un array PHP è una hash map ordinata: mantiene l'ordine di inserimento e associa chiavi int o string a valori, ed è per questo che lo stesso tipo fa da lista, da dizionario e da pila. Le ricerche per chiave (isset($arr[$key])) richiedono in media tempo costante, mentre in_array() scorre ogni valore. Le chiavi stringa che sembrano interi vengono convertite: $a['1'] e $a[1] sono lo stesso elemento.

Esercizi di codice comuni nei colloqui

Brevi esercizi spesso chiesti dal vivo. Ogni funzione è una risposta comune; eseguile, aggiungi i tuoi input (compreso uno vuoto) e preparati a spiegare la complessità temporale, che di solito è ciò che verifica chi fa il colloquio.

Domande frequenti

Come mi preparo a un colloquio da sviluppatore PHP?

Assicurati di saper spiegare e scrivere codice per le basi senza cercarle: confronti e tipi, array e relative funzioni, OOP (interfacce, classi astratte, trait, static), eccezioni e sicurezza (prepared statement, htmlspecialchars, password_hash). Poi conosci un framework (Laravel o Symfony) e Composer abbastanza bene da raccontare un progetto che hai costruito.

Quale versione di PHP devo conoscere per un colloquio?

PHP 8. Chi fa il colloquio si aspetta che tu conosca le funzionalità aggiunte dalla 8.0 alla 8.3: argomenti con nome, match, l'operatore nullsafe ?->, union type, promozione delle proprietà nel costruttore, enum, proprietà readonly e la sintassi first-class callable. Cita il comportamento di PHP 7 solo dove è cambiato, come 0 == "a".

Quali domande PHP vengono fatte ai junior?

Soprattutto le basi del linguaggio: == vs ===, echo vs print, apici singoli vs virgolette doppie, isset vs empty, include vs require, GET vs POST, sessioni vs cookie e semplici esercizi sugli array come invertire, filtrare o contare valori. Aspettati almeno un breve esercizio di codice.

Quali domande PHP vengono fatte agli sviluppatori esperti?

Progettazione e comportamento sotto il cofano: interfacce vs classi astratte, trait, late static binding, riferimenti, generatori e memoria, eccezioni e gestione degli errori, SQL injection e transazioni, caching, autoloading di Composer e come struttureresti o testeresti una funzionalità. Ci si aspetta risposte con pro e contro, non definizioni.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA