lunedì 27 ottobre 2025

Corso di PHP: 2 – Sintassi e Variabili

2 — Sintassi e variabili in PHP

Obiettivo del modulo. Fornire una conoscenza esaustiva della sintassi di base di PHP, del modello di variabili e tipi, delle costanti e degli operatori, con esempi pronti all’uso e un esercizio guidato (calcolo area e perimetro di un rettangolo) implementato in più varianti (script semplice, form web, CLI, versione “robusta” con validazione e test).


Indice

  1. Struttura base di un file PHP

  2. Tag PHP e integrazione HTML

  3. Modalità di esecuzione (CLI / server integrato / server web)

  4. Direttive utili per sviluppo (error reporting, display_errors)

  5. Variabili: binding, naming, scope

  6. Tipi di dato in PHP (primitivi e compound)

  7. Type juggling, casting esplicito e declare(strict_types=1)

  8. Costanti: const vs define()

  9. Operatori (aritmetici, confronto, logici, stringa, bitwise, null coalescing, spaceship, ecc.)

  10. Stringhe: concatenazione, interpolazione, heredoc/nowdoc

  11. Superglobals e input (sicurezza e validazione)

  12. Buone pratiche e anti-pattern

  13. Esercizio completo: Area e perimetro del rettangolo — 4 versioni (snippet + spiegazioni)

  14. Test, logging e error handling (sintesi)

  15. Riferimenti e letture consigliate


1 — Struttura base di un file PHP

Un file PHP è un file di testo con estensione .php che contiene codice PHP racchiuso tra tag di apertura e tag di chiusura. La struttura minima:

<?php
// file: index.php
echo "Hello, World!";

Si possono mescolare HTML e PHP:

<!doctype html>
<html lang="it">
<head><meta charset="utf-8"><title>PHP Demo</title></head>
<body>
<h1><?php echo "Benvenuto"; ?></h1>
<p>Ora sono in HTML</p>
</body>
</html>

Nota: preferire sempre <?php ... ?> per compatibilità. Il short-tag <? è deprecato/oscillante in alcune configurazioni; il short-echo <?= ... ?> è disponibile di default nelle versioni recenti di PHP ed è comodo per l’output rapido.


2 — Tag PHP e integrazione HTML

  • <?php ... ?> blocco PHP standard.

  • <?= expr ?> equivalente a <?php echo expr; ?>. Utile in template.

  • <? short tag (sconsigliato).

  • /* ... */ commento multi-linea, // e # commento single-line.

Esempio di template semplice (separazione logica/presentazione):

<?php
$title = "Prodotti";
$items = ["Pane", "Latte", "Uova"];
?>
<!doctype html><html><head><meta charset="utf-8"><title><?= htmlspecialchars($title) ?></title></head>
<body>
<h1><?= htmlspecialchars($title) ?></h1>
<ul>
<?php foreach ($items as $it): ?>
<li><?= htmlspecialchars($it) ?></li>
<?php endforeach; ?>
</ul>
</body></html>

Usare htmlspecialchars() per prevenire XSS quando si visualizza input utente.


3 — Modalità di esecuzione

  • Server web (Apache / Nginx + PHP-FPM / mod_php): file serviti via http://localhost.

  • Server integrato (dev): php -S localhost:8000 -t public/ per test rapido (non per produzione).

  • CLI: php script.php per strumenti a riga di comando. In CLI sono disponibili $argc, $argv.

Esempio CLI:

php rect_cli.php 3.5 2.1

Dove rect_cli.php legge $argv[1] e $argv[2].


4 — Direttive utili per sviluppo

Nel file o in php.ini per sviluppo impostare:

ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

In produzione disabilitare display_errors e loggare invece gli errori (error_log).


5 — Variabili: binding, naming e scope

Binding

In PHP le variabili iniziano con $ e fanno binding dinamico all’oggetto:

$a = 5; // $a è un int
$a = "ciao"; // ora è una stringa

Regole di naming

  • Iniziano con $ seguito da lettera o underscore.

  • Sensibili a maiuscole/minuscole: $Var$var.

  • Evitare nomi di funzione o parole riservate.

Scope

  • Local (variabili dentro funzione), global (variabili file-scope), superglobals ($_GET, $_POST, $_SERVER, $_SESSION, $_COOKIE, $_FILES, $_ENV, $GLOBALS).

  • Per accedere a una variabile globale dentro una funzione usare $GLOBALS['name'] o global $name;.

  • static all’interno di una funzione mantiene valore tra invocazioni.

Esempi:

$x = 10;
function foo() {
global $x;
echo $x; // stampa 10
}
function bar() {
static $counter = 0;
$counter++;
echo $counter;
}

Variabili variabili (es. $a = 'b'; $$a = 5; → crea $b = 5) — utile ma spesso fonte di confusione e rischi; evitarle o usarle con cautela.


6 — Tipi di dato in PHP

Tipi scalari

  • int (integer), float (double), string, bool (boolean).

  • null rappresenta assenza di valore.

Tipi compound

  • array (vettori e mappe associative), object (istanze di classi), resource (risorse esterne: handle DB, stream).

Tipi speciali

  • callable, iterable (PHP 7+), mixed (PHP 8.0+), e union types (PHP 8+) come int|float.

Funzioni utili

  • gettype($x), var_dump($x), print_r($x), is_int(), is_float(), is_numeric(), is_string(), is_array(), is_null().

Esempio:

$a = "123";
var_dump($a); // string(3) "123"
var_dump((int)$a); // int(123)
is_numeric("12.3"); // true

7 — Type juggling, casting e declare(strict_types=1)

PHP coerce automaticamente tipi quando necessario (type juggling), es.: '5' + 27. Questo può essere comodo ma anche fonte di bug.

Casting esplicito

$int = (int) '3.7'; // 3
$float = (float) '3.7'; // 3.7
$str = (string) 123; // "123"

Tipi stretti per funzioni (PHP 7+)
All’inizio del file:

<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}

Con strict_types attivo, la chiamata add('2','3') genera un TypeError; senza strict_types PHP tenterà coerzione.

Union types (PHP 8)

function foo(int|float $x): float { return (float)$x; }

8 — Costanti: const vs define()

  • const NAME = value; — definizione a compile-time (dentro classi o global scope).

  • define('NAME', value); — definizione a runtime (case-sensitive per default).

Esempio:

const PI = 3.14159;
define('APP_NAME', 'MiaApp');

Dal PHP 7 si possono usare const anche per array.


9 — Operatori

Aritmetici

+ - * / % ** (potenza **).

Assegnamento

=, +=, -=, *=, /=, .= (concatenazione assegnata).

Confronto

  • == (valore), === (valore + tipo), !=, !==, <, >, <=, >=.

  • Operator <=> (spaceship) restituisce -1, 0, 1 — utile per sort comparators (PHP 7+).

Logici

and, or, xor, &&, ||, !. Nota: and/or hanno precedenza inferiore rispetto ad = — preferire && e || in espressioni complesse.

Stringhe

Concatenazione: . operator. Interpolazione nelle stringhe doppie ("valore $v").

Null coalescing

$x = $_GET['p'] ?? 'default'; — ideale per recuperare valori con fallback.

Null coalescing assignment (PHP 7.4+)

$a ??= 'default';

Operator precedence

Attenzione alla precedenza: es. false && true vs false and true e =. Usa parentesi per chiarezza.

Esempi:

$a = 5;
$a += 3; // 8
$s = "a" . "b"; // "ab"
$val = $_GET['x'] ?? 10;

10 — Stringhe: literal, interpolation, heredoc, nowdoc

  • Doppie virgolette: interpreti variabili e sequenze (\n, \t).

  • Single quotes: letterale, migliore performance se non serve interpolation.

  • Heredoc: <<<EOT ... EOT; interpreta variabili.

  • Nowdoc: <<<'EOT' ... EOT; come single quote (no interpolation).

Esempi:

$name = "Luca";
echo "Ciao $name\n"; // interpolation
echo 'Ciao $name\n'; // literal
$text = <<<HTML
<p>Ciao $name</p>
HTML;

11 — Superglobals, input e sicurezza

Superglobals

  • $_GET, $_POST, $_REQUEST, $_COOKIE, $_FILES, $_SESSION, $_SERVER, $_ENV, $GLOBALS.

Input handling e validazione

  • Non fidarsi mai di input utente. Usare filter_input() e filter_var().

Esempio:

$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
if ($age === false) {
echo "Età non valida.";
}

Per stringhe e output HTML usare htmlspecialchars($str, ENT_QUOTES, 'UTF-8').

XSS e escaping

  • Escape sempre output destinato all’HTML.

  • Per SQL usare prepared statements (PDO with prepared statements) per evitare SQL injection.

CSRF

  • Per form sensibili, utilizzare token CSRF memorizzati in $_SESSION.


12 — Buone pratiche e anti-pattern

Consigli

  • Abilitare declare(strict_types=1) nei file di produzione per maggior robustezza (valutare trade-off con interoperabilità).

  • Separare logica e view (template engine: Twig, Blade, ecc.).

  • Usare PDO + prepared statements per DB.

  • Validare e sanificare sempre input.

  • Usare Composer per gestione dipendenze e PSR-12 per coding standard.

Anti-pattern

  • Non usare eval() su input utente.

  • Evitare extract() su $_REQUEST.

  • Evitare @ operator per silenziare errori: nasconde problemi.

  • Non scrivere HTML con echo concatenati estensivamente — preferire template.


13 — Esercizio: script che calcola area e perimetro di un rettangolo

Presenteremo 4 versioni: (A) script semplice, (B) form web minimo, (C) form robusto con validazione e output sicuro, (D) CLI + test.

Versione A — Script PHP minimo (funziona in CLI o web con query string)

rect_simple.php

<?php
// rect_simple.php
$width = isset($_GET['w']) ? (float) $_GET['w'] : 0;
$height = isset($_GET['h']) ? (float) $_GET['h'] : 0;
$area = $width * $height;
$perimeter = 2 * ($width + $height);
header('Content-Type: text/plain; charset=utf-8');
echo "Width: $width\n";
echo "Height: $height\n";
echo "Area: $area\n";
echo "Perimeter: $perimeter\n";

Chiamare: http://localhost/rect_simple.php?w=3.5&h=2.25

Limiti: nessuna validazione, output non escapato (ma numerico).


Versione B — Form web minimo (GET)

rect_form.php

<?php
// rect_form.php
$w = isset($_GET['w']) ? $_GET['w'] : '';
$h = isset($_GET['h']) ? $_GET['h'] : '';
$area = $perimeter = null;
if ($w !== '' && $h !== '') {
$width = (float) str_replace(',', '.', $w);
$height = (float) str_replace(',', '.', $h);
$area = $width * $height;
$perimeter = 2 * ($width + $height);
}
?>
<!doctype html><html><head><meta charset="utf-8"><title>Rettangolo</title></head>
<body>
<form method="get">
Larghezza: <input name="w" value="<?= htmlspecialchars($w) ?>"><br>
Altezza: <input name="h" value="<?= htmlspecialchars($h) ?>"><br>
<button type="submit">Calcola</button>
</form>
<?php if ($area !== null): ?>
<p>Area: <?= htmlspecialchars((string)$area) ?></p>
<p>Perimetro: <?= htmlspecialchars((string)$perimeter) ?></p>
<?php endif; ?>
</body></html>

Versione C — Form robusto con validazione e sicurezza

rect_robust.php

<?php
// rect_robust.php
declare(strict_types=1);
ini_set('display_errors','1'); error_reporting(E_ALL);
function parseDecimal(string $s): ?float {
$s = trim($s);
if ($s === '') return null;
// replace comma with dot for locales like it_IT
$s = str_replace(',', '.', $s);
// use filter to validate numeric string
if (!is_numeric($s)) return null;
return (float)$s;
}
$errors = [];
$width = $height = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$wIn = $_POST['width'] ?? '';
$hIn = $_POST['height'] ?? '';
$width = parseDecimal($wIn);
$height = parseDecimal($hIn);
if ($width === null || $width <= 0) $errors[] = "Larghezza non valida (deve essere > 0).";
if ($height === null || $height <= 0) $errors[] = "Altezza non valida (deve essere > 0).";
if (empty($errors)) {
$area = $width * $height;
$perimeter = 2 * ($width + $height);
// format output with 2 decimal places
$areaStr = number_format($area, 2, ',', '.');
$perimeterStr = number_format($perimeter, 2, ',', '.');
}
}
?>
<!doctype html><html><head><meta charset="utf-8"><title>Rettangolo - Robusto</title></head><body>
<h1>Calcola Area e Perimetro</h1>
<?php if (!empty($errors)): ?>
<ul style="color:red">
<?php foreach ($errors as $e): ?>
<li><?= htmlspecialchars($e) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form method="post" action="">
<label>Larghezza: <input name="width" value="<?= htmlspecialchars($_POST['width'] ?? '') ?>"></label><br>
<label>Altezza: <input name="height" value="<?= htmlspecialchars($_POST['height'] ?? '') ?>"></label><br>
<button type="submit">Calcola</button>
</form>
<?php if (isset($areaStr)): ?>
<h2>Risultati</h2>
<p>Area: <?= $areaStr ?> (unità²)</p>
<p>Perimetro: <?= $perimeterStr ?> (unità)</p>
<?php endif; ?>
</body></html>

Punti chiave della versione C

  • declare(strict_types=1) impone controlli più rigorosi sulle tipologie quando usate type hints.

  • parseDecimal() gestisce la virgola come separatore decimale e blocca input non numerici.

  • htmlspecialchars() per evitare XSS.

  • number_format() per output leggibile con formattazione locale.


Versione D — CLI e test rapido

rect_cli.php

<?php
// rect_cli.php
if (php_sapi_name() !== 'cli') {
echo "Questo script è per CLI\n";
exit(1);
}
if ($argc < 3) {
echo "Uso: php rect_cli.php width height\n";
exit(1);
}
$width = (float)$argv[1];
$height = (float)$argv[2];
if ($width <= 0 || $height <= 0) {
echo "Valori devono essere > 0\n";
exit(1);
}
$area = $width * $height;
$perimeter = 2 * ($width + $height);
printf("Area: %.2f\nPerimeter: %.2f\n", $area, $perimeter);

Test semplice (shell):

php rect_cli.php 3.5 2.5

Output:

Area: 8.75
Perimeter: 12.00

14 — Test, logging e error handling

Logging

Usare error_log() per registrare errori lato server o un logger PSR-3 (Monolog):

error_log("Input non valido: width=$width height=$height");

Unit testing

Per test automatici usare PHPUnit. Esempio di test (scheletro):

tests/RectTest.php

<?php
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../rect_functions.php';
class RectTest extends TestCase {
public function testArea() {
$this->assertEquals(6.0, area(2.0, 3.0));
}
public function testPerimeter() {
$this->assertEquals(10.0, perimeter(2.0, 3.0));
}
}

rect_functions.php con funzioni pure da testare:

<?php
function area(float $w, float $h): float { return $w * $h; }
function perimeter(float $w, float $h): float { return 2*($w+$h); }

Error handling

  • Usare eccezioni per casi critici.

  • Validare input e restituire messaggi utente chiari.

  • Non esporre informazioni di debug in produzione.


15 — Riepilogo best practice per il modulo

  • Validazione: ogni input va validato e sanitizzato (filter_input, filter_var).

  • Escaping: htmlspecialchars sempre per output HTML.

  • Typed code: preferire type hints e declare(strict_types=1) nei moduli critici.

  • Separa logica e presentazione: non mischiare troppo echo HTML/procedurale; usare template engine se il progetto cresce.

  • No eval, no extract($_REQUEST), no @ operator.

  • Usa PDO per accesso DB e prepared statements.

  • Gestione errori: log, testing e configurazione ambiente (dev vs prod).


Esempi addizionali e casi limite (quick reference)

  • '5' + '3'8 (coercizione numerica)

  • '05' == 5 → true, '05' === 5 → false

  • 0 == 'abc' → true (attenzione!) — meglio is_numeric() prima di convertire.

  • ?? and ?: differenza: $x = $a ?? 'd' vs $x = $a ?: 'd' (?: considera falsy).


16 — Materiale didattico consigliato e riferimenti

  • Manuale PHP (php.net) — pagine essenziali: Variables, Types, Type Declarations, filter_input, htmlspecialchars, PDO.

  • PSR-12 Coding Style Guide — standard di codice PHP.

  • OWASP PHP Security Cheat Sheet — buone pratiche di sicurezza web.

  • PHPUnit documentation — testing in PHP.


Conclusione e proposte operative (per il docente o il corsista)

  • Per la lezione di 3 ore:

    • 30' teoria (sintassi, tags, error reporting),

    • 45' variabili, tipi e operatori con esercizi rapidi (quiz su cui è vero/falso),

    • 30' stringhe e formattazione,

    • 45' laboratorio (implementare Versione B o C dell’esercizio rettangolo),

    • 30' testing e riflessioni su sicurezza e best-practice.

  • Materiale da consegnare: zip con gli script (rect_simple.php, rect_form.php, rect_robust.php, rect_cli.php), rect_functions.php per unit tests, e README.md con istruzioni per eseguire in dev server (php -S localhost:8000).

Nessun commento:

Posta un commento

Corso Fondamenti di Informatica e Reti: 4 Architettura del computer

  ARCHITETTURA DEL COMPUTER come funziona davvero una macchina Capire un computer non significa solo saperlo accendere o aprire file: die...