PHP.MySQL


Nei server possono essere archiviate in modo centralizzato molte informazioni di solito non disponibili nei computer personali. Queste informazioni sono spesso organizzate in strutture di dati dette database organizzate secondo precisi protocolli che permettano la facilità di lettura, di aggiornamento e anche di scambio tra protocolli diversi.

In generale un database comprende una o più parti dette tabelle. Ogni tabella è una sequenza ordinata di righe. Ogni riga è un record della tabella. Ogni record comprende uno o più campi. Ogni campo contiene un dato di cui va specificato il tipo: numero, stringa alfanumerica, data o altro. Tutte le righe hanno esattamente lo stesso numero di campi e tutti i campi in posizione uguale sono dello stesso tipo.

PHP è stato arricchito con un complesso di funzioni capaci di gestire istruzioni espresse in linguaggio SQL (Structured Query Language) finalizzate alla gestione dei database.

Questo complesso di funzioni, detto inizialmente PHP.MySQL o semplicemente MySQL, dalla sua origine nel 2001 è stato sottoposto a continui aggiornamenti. Cercando in rete documentazione sulle sue procedure o su esempi applicativi è bene verificare con attenzione le date delle risorse individuate perché molto spesso le informazioni reperite sono dei fossili relativi a versioni superate (deprecated) e probabilmente fuorvianti.
Oracle MySQL, detto pure semplicemente MySQL è invece un sistema di gestione dei database disponibile in phpMyAdmin il cui uso sarà descritto nella prossima pagina.
Questa coincidenza di nomi può renedere complicata la ricerca in rete di documentazione sulle versioni pià recenti dei prodotti.

Le versioni più recenti di Php.MySQL propongono due dialetti:

PDO, orientato agli oggetti ("object oriented"), è il più flessibile perché può gestire databases creati in vari ambienti.

MySQLi può gestire solo databases MySQL e può essere usato in due diverse modalità: procedurale o "object oriented". La modalità "object oriented" appare la più snella e flessibile, per cui nella presente trattazione si userà questa modalità indicata come MySqliOO.

Come semplice esempio introduttivo all'uso di MySqliOO si propone la creazione e la successiva consultazione di un piccolo database denominato DBRegioni che contiene alcune informazioni relative alla 19 regioni italiane e ai loro capoluoghi.

Innanzitutto, per non confondere questo esempio con la serie degli esempi precedenti, è bene creare nella cartella www una nuova cartella DBRegioni, nella quale andranno salvati i sorgenti delle prossime pagine.

Si redige il seguente sorgente.


<‌‌?php

$servername = "localhost";
$root = "root";
$password = "";
$dbname = "DBRegioni";

$conn = new mysqli($servername,$root,$password);
if ($conn->connect_error)
  {
    die("Connection failed: " . $conn->connect_error);
  }

$sql = "DROP SCHEMA IF EXISTS DBRegioni";
$conn->query($sql);

$sql = "CREATE SCHEMA DBRegioni";
$conn->query($sql);
$conn->close();

$conn = new mysqli($servername,$root,$password,$dbname);
if ($conn->connect_error)
  {
    die("Connection failed: " . $conn->connect_error);
  }

$sql = "CREATE TABLE Regioni(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,regione VARCHAR(20) NOT NULL DEFAULT '',capoluogo VARCHAR(20) NOT NULL DEFAULT '')";

if ($conn->query($sql))
  {
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Abruzzo', 'L\'Aquila')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Basilicata', 'Potenza')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Calabria', 'Catanzaro')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Campania', 'Napoli')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Emilia-Romagna', 'Bologna')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Friuli-Venezia Giulia', 'Trieste')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Lazio', 'Roma')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Liguria', 'Genova')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Lombardia', 'Milano')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Marche', 'Ancona')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Molise', 'Campobasso')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Piemonte', 'Torino')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Puglia', 'Bari')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Sardegna', 'Cagliari')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Sicilia', 'Palermo')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Toscana', 'Firenze')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Trentino-Alto Adige', 'Trento')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Umbria', 'Perugia')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Valle d\'Aosta', 'Aosta')";
    $conn->query($sql);
    $sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Veneto', 'Venezia')";
    $conn->query($sql);
    echo "Creato database DBRegioni popolato con 19 regioni.";
  }
else
  echo "Creazione e popolamento di DBRegioni falliti.";

$conn->close();

?>

Salvare questa pagina nella cartella DBRegioni con nome CreaDBRegioni.php e attivarla scrivendo nel browser localhost/DBRegioni/CreaDBRegioni.php. Se non ci sono malfunzionamenti, il server locale contiene il database DBRegioni che potrà essere successivamente interrogato con opportune procedure che verranno proposte in seguito.

L'istruzione

$conn = new mysqli($servername,$root,$password);

genera l'oggetto $conn con una sintassi simile a quella degli oggetti C++. Questo oggetto gestisce la connessione tra la pagina e il database locale. Se la generazione di $conn non ha successo, l'istruzione successiva

if ($conn->connect_error)
  {
    die("Connection failed: " . $conn->connect_error);
  }
emette un messaggio di errore e interrompe l'elaborazione.

Se tutto va bene, le istruzioni successive

$sql = "DROP SCHEMA IF EXISTS DBRegioni";
$conn->query($sql);

dicono al server di eliminare, se esistono, precedenti versioni di DBRegioni: questa precauzione può essere utile se ci sono stati dei malfunzionamenti e permette una redazione aggiornata del database. La variabile $sql è una stringa che descrive l'operazione da eseguire. L'istruzione $conn->query($sql) dice al server di eseguirla.

Le istruzioni

$sql = "CREATE SCHEMA DBRegioni";
$conn->query($sql);
$conn->close();

comandano la creazione di un nuovo database con nome DBRegioni e chiudono provvisoriamente la connessione.

Con l'istruzione

$conn = new mysqli($servername,$root,$password,$dbname);

Si riapre la connessione non solo con il server ma anche con database DBRegioni appena creato in modo da potere agire su di esso. Bisogna infatti che il database, attualmente vuoto, venga riempito di informazioni. Le informazioni saranno contenute in una tabella da generare specificandone la struttura. La struttura della tabella, denominata Regioni è descritta dalla stringa

$sql = "CREATE TABLE Regioni(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,regione VARCHAR(20) NOT NULL DEFAULT '',capoluogo VARCHAR(20) NOT NULL DEFAULT '')";

La tabella Regioni contiene records costituiti da tre campi:

Se l'esecuzione di $sql ha successo, la tabella Regioni è pronta a registrare nei suoi records le informazioni correlate sui nomi delle regioni e dei rispettivi capoluoghi. Questo compito è realizzato dalle 19 istruzioni descritte da $sql tutte simili alla prima

$sql = "INSERT INTO Regioni(regione, capoluogo) VALUES ('Abruzzo', 'L\'Aquila')"

tranne ovviamente per i nomi di regioni e capoluoghi.

Notare che se un valore, descritto da una stringa contenuta da apici, contiene un apostrofo, il carattere di apostrofo va preceduto da una barra inversa, perché l'apostrofo non sia interpretato come un segno di fine stringa.

 


Interrogazione del database.

Una volta creato un database, per estrarne informazioni, è necessario aprire una connessione con il database medesimo, formulare una query e chiedere alla connessione di eseguirla. Si potrebbero scrivere le istruzioni necessarie direttamente in un file PHP, ma, per maggiore chiarezza espositiva, si suddivide l'operazione in due passi:

L'interfaccia HTML può essere la seguente.

<‌‌!DOCTYPE html>
<‌‌html lang="it">

<‌‌head>
  <‌‌title>Query1
  <‌‌meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" >
  <‌‌meta name="viewport" content="width=device-width,minimum-scale=1.0,initial-scale=1.0">
<‌‌/head>

<‌‌body style="background-color:azure">
<‌‌h1 style="color:red; text-align:center"><‌b>Ricerca del capoluogo di regione<‌/b><‌‌/h1>
<‌‌form id="frm" name="frm" action="query1.php" method="get" 
  style="position:relative; left:30%; width:40%; text-align:center; border-style:solid; background-color:cyan" >
<‌‌p>
<‌‌label for="c_reg">Regione? <‌/label>
<‌‌input type="text" id="c_reg" name="c_reg" size="30">
<‌‌/p>
<‌‌p>
<‌‌button type="submit"> trova capoluogo <‌‌/button>
<‌‌button type="reset"> reset <‌‌/button>

<‌‌/form> <‌‌/body> <‌‌/html>

Salvare questo testo nella cartella DBRegioni con nome Query1.html.

query1.gif

La pagina Query1.html a sua volta, se viene cliccato il bottone trova capoluogo, attiva la seguente pagina PHP, da salvare sempre nella cartella DBRegioni con nome query1.php.

<‌‌?php

  echo "<‌!DOCTYPE html>".PHP_EOL;
  echo "<‌html lang='it'>".PHP_EOL;
  echo "<‌head>".PHP_EOL;
  echo "<‌title>";

  $regione = $_REQUEST["c_reg"];

  $manca_input = (strlen($regione)==0);
  if ($manca_input) $regione = "ERRORE";
  echo "regione: ".$regione; 
  echo "<‌/title>".PHP_EOL;
  echo "<‌/head>".PHP_EOL;
  echo "<‌body style='background-color:ivory; color:blue; text-align:center; font-size:120%'>".PHP_EOL;
  if ($manca_input)
    echo "<‌p>ERRORE<‌/p>";
  else
    {
      $conn = new mysqli("localhost","root","","dbregioni");

      if ($conn->connect_error) die("Connection failed: " . $conn->connect_error);
      else
        {
          $sql  = "select * from Regioni where regione = '".$regione."'";
          $records = $conn->query($sql);
          $trovati = $conn->affected_rows;
          if ($trovati==1)
            {
              $riga = $records->fetch_assoc();
              $capoluogo = $riga['capoluogo'];
              echo "<‌p>Il capoluogo della regione ".strtoupper($regione)." è ".$capoluogo."<‌/p>".PHP_EOL;
            }
          else
            echo "<‌p>La regione ".strtoupper($regione)." non esiste.<‌/p>".PHP_EOL;
          $records->free();
        }
      $conn->close();
    }
  echo "<‌/body>".PHP_EOL."<‌/html>";
?>

Ora si può aprire la pagina Query1.html scrivendo nel browser localhost/DBRegioni/Query1.html.

Volendo rintracciare il capoluogo di una regione senza dover scrivere completamente nell'interfaccia HTML il nome della regione, ma solo qualche lettera iniziale, si può sostituire nel sorgente della stessa la specificazione action="query1.php" con action="query2.php" e salvare la questa versione modificata con nome Query2.html. Il sorgente di query2.php è il seguente.


  echo "<‌!DOCTYPE html>".PHP_EOL;
  echo "<‌html lang='it'>".PHP_EOL;
  echo "<‌head>".PHP_EOL;
  echo "<‌title>";

  $regione = $_REQUEST["c_reg"];

  $manca_input = (strlen($regione)==0);

  if ($manca_input) $regione = "ERRORE";
  echo "regione: ".$regione; 
  echo "<‌/title>".PHP_EOL;
  echo "<‌/head>".PHP_EOL;

  echo "<‌body style='background-color:ivory; color:blue; text-align:center; font-size:120%'>".PHP_EOL;

  if ($manca_input)
    echo "<‌p>Input non valido.<‌/p>";
  else
    {
      $conn = new mysqli("localhost","root","","dbregioni");
      if ($conn->connect_error) die("Connection failed: " . $conn->connect_error);
      else
        {
          $sql  = 'select * from regioni where regione like "'.$regione.'%"';
          $records = $conn->query($sql);
          $trovati = $conn->affected_rows;
          switch($trovati)
            {
              case 0:
                echo "<‌p>Nessuna regione comincia con ".strtoupper($regione).".<‌/p>".PHP_EOL;
                break;
              case 1:
                $riga = $records->fetch_assoc();
                $regione = $riga['regione'];
                $capoluogo = $riga['capoluogo'];
                echo "<‌p>Il capoluogo della regione ".strtoupper($regione)." è ".$capoluogo."<‌/p>".PHP_EOL;
                break;
              default:
                echo "<‌p>L'indicazione ".strtoupper($regione)." non è univoca.<‌/p>\n";
            }
          $records->free();
        }
      $conn->close();
    }
  echo "<‌/body>".PHP_EOL."<‌/html>";
?>

Salvare anche query2.php e aprire nel browser localhost/DBRegioni/Query2.html.

Per ricerche più articolate si può preparare una pagina HTML che accetti una qualunque query sul database e la spedisca ad una pagina PHP che la esegua e a sua volta generi una pagina HTML con l'esito dell'elaborazione.

<‌!DOCTYPE html>
<‌html lang="it">
<‌head>
  <‌title>Query
  <‌meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" >
  <‌meta name="viewport" content="width=device-width,minimum-scale=1.0,initial-scale=1.0">
<‌/head>
<‌body style="background-color:azure">
<‌h1 style="color:red; text-align:center">Query sul database DBRegioni
<‌form id="frm" name="frm" action="query.php" method="get" 
  style="position:relative; left:30%; width:40%; text-align:center; border-style:solid; background-color:cyan" >
<‌p>
<‌label for="c_reg">Query <‌/label>
<‌input type="text" id="c_query" name="c_query" size="100">
<‌/p>
<‌p>
<‌button type="submit"> esegui <‌/button>
<‌button type="reset"> reset <‌/button>
<‌/p>
<‌/form>
<‌/body>
<‌/html>

query.png

Salvare questo testo nella cartella DBRegioni con nome Query.html.

Preparare il sorgente del file PHP.

Salvare questo sorgente come query.php e aprire nel browser localhost/DBRegioni/Query.html.

Sperimentare le seguenti query.