PHP

Da Skypedia.

PHP è un acronimo ricorsivo che sta per «PHP: Hypertext Preprocessor». PHP è un linguaggio nato per il web ma che all'atto pratico oggi può essere considerato un linguaggio general purpose data la sua evoluzione rapidissima che ha introdotto notevoli cambiamenti nella sintassi e nella grammatica stessa del linguaggio.

Storia

Nato nel 1994 ad opera del danese Rasmus Lerdorf, PHP era in origine una raccolta di script CGI che permettevano una facile gestione delle pagine personali. Per questo motivo il significato originario dell'acronimo pare fosse Personal Home Page (sull'origine dell'acronimo ci sono tuttora alcuni dubbi, alimentati dallo stesso Lerdorf che ha contribuito volontariamente a generare attorno al nome questo alone di mistero). Il pacchetto originario venne in seguito esteso e riscritto dallo stesso Lerdorf in C, aggiungendo funzionalità quali il supporto al database mySQL e prese a chiamarsi PHP/FI, dove FI sta per Form Interpreter (interprete di form), prevedendo la possibilità di integrare il codice PHP nel codice HTML in modo da semplificare la realizzazione di pagine dinamiche. In quel periodo, 50.000 domini Internet annunciavano di aver installato PHP.

A questo punto il linguaggio cominciò a godere di una certa popolarità tra i progetti open source del web, e venne così notato da due giovani programmatori: Zeev Suraski e Andi Gutmans. I due collaborarono nel 1998 con Lerdorf allo sviluppo della terza versione di PHP (il cui acronimo assunse il significato attuale) riscrivendone il motore che fu battezzato Zend da una contrazione dei loro nomi. Le caratteristiche chiave della versione PHP 3.0 frutto del loro lavoro, erano la straordinaria estensibilità, la connettività ai database e il supporto iniziale per il paradigma a oggetti. Verso la fine del 1998 PHP 3.0 era installato su circa il 10% dei server web presenti su Internet.

PHP diventò a questo punto talmente maturo da competere con ASP, linguaggio lato server analogo a PHP sviluppato da Microsoft, e cominciò ad essere usato su larga scala. La versione 4 di PHP venne rilasciata nel 2000 e prevedeva notevoli migliorie. Attualmente siamo alla quinta versione, sviluppata da un team di programmatori, che comprende ancora Lerdorf, oltre a Suraski e Gutmans.

Progettare software con PHP

Con l'avvento del PHP 5 la progettazione del software scritto in questo linguaggio ha subito un cambiamento radicale proprio per l'introduzione del supporto alla programmazione orientata agli oggetti propria di linguaggi di programmazione come C++, Java, Python. Grazie a ciò si possono allora formulare degli stili di programmazione comuni e design pattern applicati a PHP 5.

Accedere ad un database con PHP 5

L'estensione PHP data object (PDO) definisce un'interfaccia per accedere ad un database con PHP.

Include e Require

Include non è una vera funzione ma un costrutto PHP. Ecco perché, proprio come accade per il comando echo, l'uso delle parentesi tonde è facoltativo. Essa non fa altro che "appiccicare" il codice di un altro script su quello corrente. Require si differenzia da include in quanto quando richiamiamo il file da incollare e quest'ultimo non viene trovato l'esecuzione si ferma e viene stampato un errore, mentre con include viene solo segnalato l'errore. include_once e require_once permettono di importare solo una volta uno script php.

Esistono altri tre costrutti PHP che permettono l'inclusione di codice presente in altri files. Sono caratterizzati da un diverso comportamento nel caso in cui il file richiesto non venga trovato e in caso di ripetute inclusioni dello stesso file. La seguente tabella schematizza le loro caratteristiche.

I parametri di default nelle funzioni PHP

Capita spesso di dover chiamare delle funzioni che abbiano dei parametri già definiti di default, ma che possano essere ridefiniti nella chiamata della funzione. Poniamo il caso in cui non volessimo ridefinire un intero header per ogni pagina del nostro sito ma che invece volessimo che tutte le pagine abbiano una sorta di template dell'header. In pratica per ogni pagina web vogliamo una cosa del genere per il nostro header.php da includere:

<?php
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it" dir="ltr">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta name="robots" content="noindex,nofollow" />
		<meta name="keywords" content="PHP,Copyright,PHP" />
		<link rel="shortcut icon" href="/favicon.ico" />
		<link rel="search" type="application/opensearchdescription+xml" href="/wiki/opensearch_desc.php" title="Skypedia (Italiano)" />
		<link title="Creative Commons" type="application/rdf+xml" href="/wiki/index.php?title=PHP&amp;action=creativecommons" rel="meta" />
		<link rel="copyright" href="http://creativecommons.org/licenses/by-sa/3.0/" />

		<title>Skypedia</title>
		<style type="text/css" media="screen, projection">/*<![CDATA[*/
			@import "/wiki/skins/common/shared.css?97";
			@import "/wiki/skins/monobook/main.css?97";
		/*]]>*/</style>
		<link rel="stylesheet" type="text/css" media="print" href="/wiki/skins/common/commonPrint.css?97" />
function inserisci_script($script="") {
               echo '<script type= "text/javascript">'.$script.'</script>';
}

Se io chiamassi, dopo un include_once("header.php"), la funzione inserisci_script senza argomenti essa inserirebbe uno script javascript vuoto. Se invece chiamassi la funzione passando uno script potrei iniettare nell'header lo script voluto. Lo stesso può essere facilmente fatto con i meta. ad esempio.

Array associativi

Un esempio vale più di mille parole:

   1. <?php  
   2. $film = array('titolo' => 'Via col Vento', 'anno' => 1939,'regista' => 'Victor Fleming');  
   3.   
   4. echo 'Titolo film: ' , $film['titolo'];  
   5. echo ' ';  
   6. echo 'Anno: ' , $film['anno'];  
   7. echo ' ';  
   8. echo 'Regista: ' , $film['regista'];  
   9. ?>

La freccia mette a sinistra la chiave e a destra il valore. Per prendere il valore si utilizza la chiave come indice dell'array, se questa non è specificata al momento della creazione dell'array PHP mette il classico indice numerico come C in ordine ascendente a partire dallo zero, cosicché si possano creare array misti con elementi comunque chiave=>valore ma ove essa non fosse specificata verrebbe apposta una key di default che corrisponde alla key di qualsiasi array non associativo. In pratica il PHP tratta tutti gli array come associativi, mascherando la cosa quando non è espressamente richiesta. Se una chiave fosse numerica potremmo anche non mettere gli apici per segnarla ma essa prenderebbe proprio il posto di una chiave di default e PHP continuerebbe ad inserire elementi partendo dall'ultima chiave numerica inserita.

   1. <?php  
   2. $test = array('scheda',  
   3.                 'test'=>'prova',  
   4.                 5=>'full time',  
   5.                 'luna',  
   6.                 'nome'=>'Marco',  
   7.                 1957,  
   8.                 'Rossi',  
   9.                 76=>'impiegato',  
  10.                 234);  
  11.   
  12. print_r($test);  
  13. ?>

Che stampa: Array

(

[0] => scheda

[test] => prova

[5] => full time

[6] => luna

[nome] => Marco

[7] => 1957

[8] => Rossi

[76] => impiegato

[77] => 234

)

Inserimento di nuovi valori in un array

Per inserire nuovi valori in un array ci sono 2 modi:

 1. $nome_array['chiave'] = 'nuovo valore';
 2. array_push($nome_array, 'nuovo valore');

Il secondo metodo è sicuramente più "elegante" in quanto utilizza una funzione builtin ma richiede che l'array esista già.

Una precisazione: è possibile utilizzare il primo o il secondo metodo anche con array associativi (cioè a chiave non numerica):

 1. $nome_array_associativo['chiave_alfanumerica'] = 'nuovo_valore';
 1. array_push($nome_array_associativo, 'chiave_alfanumerica' => 'nuovo_valore');

La funzione list con gli array

Esiste una primitiva, chiamata list, che permette di effettuare assegnamenti multipli a variabili da un array. Funziona come segue:

 1. <?php
 2. $a = array("x", "y", "z");
 3. list($b, $c, $d) = $a;
 4. print "$b $c $d";
 5. => x y z
 6. ?>

Eliminare un elemento da un array in PHP

Per eliminare un elemento da un vettore basta utilizzare la funzione unset($array['chiave']).

Esempio:

 1. <?php
 2. $myarray[0]=‘voluto’;
 3. $myarray[1]=‘NON voluto’;
 4. $myarray[2]=‘voluto’;
 5. unset($myarray[1]);
 6. ?>

Le chiavi risultano così invariate.

Ordinamento di un array

Gli array possono essere riordinati in vari modi, a seconda che si voglia mantenere o meno l'associazione tra chiavi e valori.

Primitiva Ordinamento
sort()/rsort()) Riordina gli elementi di un array in ordine ascendente (discendente)
asort()/arsort() Riordina gli elementi in ordine ascendente (discendente) mantenendo l'associazione con gli indici
ksort()/krsort() Riordina gli elementi per chiave in ordine ascendente (discendente).

Esempio:

  1. <?php
  2. $a = array("3", "2", "1", "b" => "B", "c" =>"C", "a" =>"A");
  3. sort($a); 
  4. print "sort(\$a)\n";
  5. foreach( $a as $k => $v) print "$k => $v\n";
  6. 
  7. $a = array("3", "2", "1", "b" => "B", "c" =>"C", "a" =>"A");
  8. asort($a); 
  9. print "asort(\$a)\n";
 10. foreach( $a as $k => $v) print "$k => $v\n";
 11. 
 12. $a = array("3", "2", "1", "b" => "B", "c" =>"C", "a" =>"A");
 13. ksort($a); 
 14. print "ksort(\$a)\n";
 15. foreach( $a as $k => $v) print "$k => $v\n";
 16. ?>

Risultato:

sort($a) 0 => 1 1 => 2 2 => 3 3 => A 4 => B 5 => C asort($a) 2 => 1 1 => 2 0 => 3 a => A b => B c => C ksort($a) 0 => 3 1 => 2 2 => 1 a => A b => B c => C

La programmazione ad oggetti in PHP5

Con il PHP 5 la programmazione ad oggetti ha subito un drastico cambiamento che ha reso possibile una progettazione di alto livello possibile solo con linguaggi OO più blasonati. In pratica vi è stato un netto cambiamento che ha consentito una maggiore flessibilità nell'utilizzo delle caratteristiche del linguaggio per la gestione degli oggetti e dei metodo che li contraddistinguono.


Costruttore

Il costruttore non deve più avere lo stesso nome della classe come accadeva con la versione 4, bensì deve essere dichiarato come __construct. Inoltre si possono anche implementare i metodi distruttori con il metodo __destruct


Modificatori d'accesso

Come per Java si può definire la visibilità dei metodi e degli attributi con le parole chiave:

  • public
  • protected
  • private
 <?php
     class Jab
    {
       public $attributoPubblico;
       private $attributoPrivato;
       protected $attributoProtected;
       /* COSTRUTTORE */   
       public function __construct()
       {
          ...          
       }
   
       /* DISTRUTTORE */
       public function __destruct()
       {
           ...
       } 
     }
 ?>

Si possono definire i metodi e gli attributi statici di classe con la parola chiave static e potranno essere acceduti direttamente tramite il nome della classe con l'operatore ::.


Ereditarietà

E' possibile ereditare tramite la parola chiave extends nel seguente formato

 <?php
    class Figlia extends Jab
    {
       public function __construct()
       {
           parent::construct();
       }
       private function privateFunction(){
           $this->$attributoProtected = 1;
       }
    }
 ?>

Come avrete di certo immaginato $this richiama l'oggetto corrente e parent la classe da cui si eredita.

Modifiche all'ereditarietà in PHP 5.1

7. Cambiamenti nelle regole di ereditarietà

Sotto PHP 5.0 era possibile avere una dichiarazione di funzione in una classe derivata che non combaciava con la dichiarazione della stessa funzione nella classe base, ad es.

    class Base {  
       function &return_by_ref() {  
            $r = 1;  
            return $r;  
        }  
     }  
      
    class Derived extends Base {  
        function return_by_ref() {  
           return 1;  
        }  
    }

Questo codice causerà la generazione di un errore E_STRICT in PHP 5.1.

Interfacce e classi astratte

Sempre come in Java basta utilizzare il modificare per la classe che fa da interfaccia e implements per la classe che intende implementarla. Per le classi con metodi astratti si usera la parola chiave abstract.

 <?php
     interface Interfaccia {
        public function soloPrototipo();
     }
   
     class ClasseCheImplementa implements Interfaccia {
         public function soloPrototipo() {
             $parametro = "stringa";
         }
      }
 
      abstract class ClasseAstratta {
          public function metodoImplementato(){
             $this->metodo2();
          }
          abstract protected function metodo2();
      }
 
      class Classe1 extends ClasseAstratta {
          protected function metodo2() {
            /* fa qualcosa */
          }
       }  
 ?>

Adesso si possono anche specificare che oggetti vengono passati alle funzioni così da fare un controllo sul tipo di dato passato.

 <?php
      function prova1(Classe1 $elemento) {
          $elemento->metodo2();
      }
 ?>

Metodi privati astratti

I metodi privati astratti erano supportati tra PHP 5.0.0 e PHP 5.0.4, ma sono stati successivamente aboliti a causa della mutua esclusività dei comportamenti privato e astratto.

Modificatori di accesso nelle interfacce

Sotto PHP 5.0, le dichiarazioni delle funzioni nelle interfacce erano trattate nello stesso modo delle dichiarazioni di funzioni nelle classi. Ciò fino all’Ottobre 2004, quando nella dichiarazione delle funzioni di interfaccia è stato autorizzato solo il modificatore di accesso public. Dall’Aprile 2005 – prima dell’uscita di PH 5.0b1 – anche il modificatore ‘static’ è stato autorizzato. Comunque, i modificatori protected e private non lanceranno un E_ERROR, come farà invece il modificatore abstract. Si noti che questa variazione non dovrebbe interessare il vostro codice esistente, poiché nessuno di questi modificatori ha senso nel contesto delle interfacce. Quindi per le interfacce si possono utilizzare i modificatori:

  • public
  • static


Le costanti di classe

Basta utilizzare la parola chiave const per avere una costante di classe e accedervi con l'operatore ::.

 <?php
    class MaCheNeSo {
       const $COSTANTE;
    }
    
    echo MaCheNeSo::COSTANTE; //stampa la costante di classe
 ?>

La potenza di __autoload

Il PHP adesso richiama automaticamente la funzione __autoload ove non riesca a trovare una definizione di classe nel suo spazio dei nomi

 <?php
 
   function __autoload($nomeDellaClasse)
   {
       echo "Classe richiesta: ".$classname;
      require_once $classname..php;
   }
 
   $classeQualsiasi = new ClasseQualsiasi();
 
 ?>

instanceof, is_a(), is_subclass_of(), catch

In PHP 5.0, is_a() è stato deprecato e rimpiazzato dall’operatore “instanceof”. C’erano alcune questioni aperte dall’iniziale implementazione di “instanceof”, che dipendevano dalla ricerca delle classi mancanti da parte di __autoload(). Se la classe non fosse stata presente, “instanceof” avrebbe lanciato un E_ERROR fatale dovuto al tentativo fallito di __autoload() nel trovare tale classe. Lo stesso accadeva per l’operatore “catch” e la funzione is_subclass_of(), per lo stesso motivo. Nessuna di queste funzioni o operatori chiama __autoload() in PHP 5.1, e l’utilizzo di class_exists() come espediente nel codice scritto per PHP 5.0, benché non crei alcun problema, non è più necessario.

I metodi __set(), __get() e __call()

Un'altra funzionalità molto interessante è la possibilità di definire dei metodi particolari per catturare tutte le richieste in lettura/scrittura alle proprietà e le chiamate ai metodi, nel caso non fossero trovati nell'albero dei simboli di una classe.

 <?php
 
 class Prova
 {
    public $attributoPubblico;
    private $data;
    
    public function __construct()
    {
        $this->data = array();
    }
   
    public function __set($name, $value)
    {
        echo Scritta la proprietà .$name.<br/>;
        $this->data[$name] = $value;
     }
    
    public function __get($name)
    {
        echo Richiesta la proprietà .$name.<br/>;
        return $this->data[$name];
    }
   
    public function test()
    {
        echo test method;
    }
   
    public function __call($name, $args)
    {
        echo Richiamato il metodo .$name. con .count($args). argomenti;
    }
 }
 
 $prova = new Prova;              //istanzio l'oggetto
 $prova->attributoPubblico = 10;
 echo $prova->prova; 
 $prova->ciao = ciao;            //ciao non è un attributo definito e viene richiamato __set()
 echo $prova->ciao;             //chiamata a runtime a __get()
 $prova->metodoInesistente(1, 2, 3, 4, array()); //chiamata a __call()
 
 ?>
  • __call() intercetta la chiamata ad un metodo non definito
  • __set() setta un valore per un attributo che non viene trovato nello spazio dei nomi della classe
  • __get() cerca un valore

Potrebbe essere utile questo articolo [1] che tratta dell'overloading in PHP5 tramite i metodi __set(), __get() e __call().

Risorse