Manuale PHP

Stig Sæther Bakken
Alexander Aulbach
Egon Schmid
Jim Winstead
Lars Torben Wilson
Rasmus Lerdorf
Andrei Zmievski
Jouni Ahto

A cura di

Luca Perugini
Simone Cortesi
Marco Cucinato
Darvin Andrioli
Tradotto con la collaborazione di:
Massimo Colombo
Marco De Nittis
Fabio Gandola
Sergio Marchesini
Alan D'Angelo
Giacomo Tesio
Marco Spisto
Gabriele Scaroni
Mariano Calandra
Rocco Curcio
Luca Costantino
Fernando Fusano
Andrea Paramithiotti

17-07-2004

Copyright

Questo manuale è © Copyright 1997-2004 del Gruppo di Documentazione PHP. Questo manuale può essere redistribuito secondo i termini e le condizioni indicate dalla Open Publication License, v1.0 o successive (l'ultima versione è disponibile a http://www.opencontent.org/openpub/).

La distribuzione di versioni modificate di questo manuale è proibita senza l'esplicito consenso dei detentori del copyright.

La distribuzione di parte o di derivati da parti del manuale in qualsiasi forma di libro standard (cartaceo) è proibita senza un preventivo permesso ottenuto dai detentori del copyright.

I membri del gruppo di Documentazione PHP (PHP Documentation Group) sono elencati nella pagina iniziale di questo manuale. In caso si desideri contattare il gruppo, scrivere a phpdoc@lists.php.net.

La sezione 'Estendere PHP 4.0' di questo manuale è copyright © 2000 della Zend Technologies, Ltd. Questo materiale può essere distribuito solo secondo i termini e le condizioni della Open Publication License, v1.0 o successiva (la versione più recente è al momento disponibile qui http://www.opencontent.org/openpub/).


Sommario
Prefazione
I. Guida Rapida
1. Introduzione
2. Una semplice introduzione
3. Installazione
4. Runtime Configuration
II. Struttura del Linguaggio
5. Sintassi Fondamentale
6. Types
7. Variables
8. Costanti
9. Expressions
10. Operatori
11. Strutture di controllo
12. Funzioni
13. Classi e Oggetti
14. Classes and Objects (PHP 5)
15. Spiegazioni sui riferimenti
III. Security
16. Security
IV. Caratteristiche
17. Autenticazione HTTP usando PHP
18. Cookies
19. Dealing with XForms
20. Caricare file
21. Utilizzo di file remoti
22. Gestione della connessione
23. Connessioni Persistenti ai Database
24. Modalità sicura (Safe mode)
25. Utilizzo di PHP da linea di comando
V. Guida Funzioni
I. Funzioni Apache
II. Funzioni di Array
III. Funzioni Aspell [deprecated]
IV. Funzioni Matematiche BCMath a precisione arbitraria
V. Funzioni di compressione Bzip2
VI. Funzioni Calendar
VII. Funzioni API CCVS [deprecate]
VIII. Funzioni di supporto COM per Windows
IX. Funzioni per Classi/Oggetti
X. Funzioni ClibPDF
XI. Funzioni di Crack
XII. Funzioni CURL, Client URL Library
XIII. Funzioni di pagamento Cybercash
XIV. Funzioni di amministrazione Cyrus IMAP
XV. Funzioni di tipo dei caratteri
XVI. Database (dbm-style) Abstraction Layer Functions
XVII. Funzioni di Data e Ora
XVIII. Funzioni dBase
XIX. Funzioni DBM
XX. dbx Functions
XXI. DB++ Functions
XXII. Funzioni per l'IO diretto
XXIII. Funzioni per le directory
XXIV. DOM Functions
XXV. Funzioni DOM XML
XXVI. Funzioni .NET
XXVII. Funzioni di gestione degli errori e di logging
XXVIII. File Alteration Monitor Functions
XXIX. FrontBase Functions
XXX. Funzioni filePro
XXXI. Filesystem functions
XXXII. Funzioni Forms Data Format
XXXIII. Funzioni FriBiDi
XXXIV. Funzioni FTP
XXXV. Function Handling Functions
XXXVI. Gettext
XXXVII. Funzioni GMP
XXXVIII. Funzioni HTTP
XXXIX. Hyperwave Functions
XL. Hyperwave API Functions
XLI. funzioni iconv
XLII. Funzioni per le immagini
XLIII. IMAP, POP3 and NNTP Functions
XLIV. Informix Functions
XLV. Funzioni InterBase
XLVI. ID3 Functions
XLVII. Ingres II Functions
XLVIII. IRC Gateway Functions
XLIX. PHP / Java Integration
L. LDAP Functions
LI. LZF Functions
LII. Funzioni di Mail
LIII. mailparse Functions
LIV. Funzioni Matematiche
LV. Multibyte String Functions
LVI. MCAL Functions
LVII. Mcrypt Encryption Functions
LVIII. MCVE Payment Functions
LIX. Memcache Functions
LX. Mhash Functions
LXI. Mimetype Functions
LXII. Funzioni per Microsoft SQL Server
LXIII. Ming functions for Flash
LXIV. Miscellaneous Functions
LXV. mnoGoSearch Functions
LXVI. mSQL Functions
LXVII. MySQL Functions
LXVIII. Improved MySQL Extension
LXIX. Mohawk Software Session Handler Functions
LXX. muscat Functions
LXXI. Funzioni di rete
LXXII. Ncurses Terminal Screen Control Functions
LXXIII. Lotus Notes Functions
LXXIV. NSAPI-specific Functions
LXXV. Funzioni ODBC Unificate
LXXVI. Object Aggregation/Composition Functions
LXXVII. Funzioni Oracle 8
LXXVIII. OpenSSL Functions
LXXIX. Funzioni Oracle
LXXX. Ovrimos SQL Functions
LXXXI. Output Control Functions
LXXXII. Proprietà object e method call overloading
LXXXIII. PDF functions
LXXXIV. Verisign Payflow Pro Functions
LXXXV. PHP Opzioni&Informazioni
LXXXVI. Funzioni POSIX
LXXXVII. Funzioni PostgreSQL
LXXXVIII. Process Control Functions
LXXXIX. Funzioni per l'esecuzione di programmi
XC. Funzioni per le Stampanti
XCI. Pspell Functions
XCII. GNU Readline
XCIII. GNU Recode Functions
XCIV. Funzioni per le espressioni regolari (Perl compatibili)
XCV. Funzioni qtdom
XCVI. Funzioni per le espressioni regolari (POSIX estesa)
XCVII. Funzioni per i semafori, la memoria condivisa ed IPC
XCVIII. SESAM Database Functions
XCIX. Funzioni di gestione della sessione
C. Funzioni relative alla memoria condivisa
CI. SimpleXML functions
CII. SOAP Functions
CIII. SQLite
CIV. Shockwave Flash Functions
CV. Funzioni per SNMP
CVI. Funzioni relative ai Socket
CVII. Standard PHP Library (SPL) Functions
CVIII. Stream Functions
CIX. Stringhe
CX. Sybase Functions
CXI. TCP Wrappers Functions
CXII. Tidy Functions
CXIII. Tokenizer Functions
CXIV. URL Functions
CXV. Funzioni di Variabili
CXVI. Funzioni vpopmail
CXVII. Funzioni W32api
CXVIII. WDDX Functions
CXIX. Funzioni relative al parser XML
CXX. Funzioni XMLRPC
CXXI. xdiff Functions
CXXII. XSL functions
CXXIII. Funzioni XSLT
CXXIV. YAZ Functions
CXXV. YP/NIS Functions
CXXVI. Funzioni per File Zip (Accesso di Sola Lettura)
CXXVII. Funzioni di compressione Zlib
VI. Zend API
26. Overview
27. Extension Possibilities
28. Source Layout
29. PHP's Automatic Build System
30. Creating Extensions
31. Using Extensions
32. Troubleshooting
33. Source Discussion
34. Accepting Arguments
35. Creating Variables
36. Duplicating Variable Contents: The Copy Constructor
37. Returning Values
38. Printing Information
39. Startup and Shutdown Functions
40. Calling User Functions
41. Initialization File Support
42. Where to Go from Here
43. Reference: Some Configuration Macros
44. API Macros
VII. PHP API: Interfacce per gli autori di estensioni
45. Streams API for PHP Extension Authors
VIII. FAQ: Frequently Asked Questions (domande e risposte ricorrenti)
46. Informazioni Generali
47. Mailing list
48. Ottenere PHP
49. Database issues
50. Installazione
51. Problemi di installazione
52. Using PHP
53. PHP and HTML
54. PHP e COM
55. PHP e gli altri linguaggi di programmazione
56. Migrazione da PHP 2 a PHP 3
57. Migrazione da PHP 3 a PHP 4
58. Domande varie
IX. Appendici
A. History of PHP and related projects
B. Migrating from PHP 4 to PHP 5
C. Migrating from PHP 3 to PHP 4
D. Migrazione da PHP/FI 2 a PHP 3
E. Debugging PHP
F. Extending PHP 3
G. Configure options
H. List of core php.ini directives
I. Lista dei sinonimi delle funzioni PHP
J. Parole riservate nel PHP
K. List of Resource Types
L. List of Supported Protocols/Wrappers
M. List of Available Filters
N. List of Supported Socket Transports
O. PHP type comparison tables
P. List of Parser Tokens
Q. Informazioni sul manuale
R. Open Publication License
S. Indice delle Funzioni
T. Informazioni mancanti

Prefazione

PHP, che significa "PHP: Hypertext Preprocessor", è un linguaggio di scripting general-purpose Open Source molto utilizzato, è specialmente indicato per lo sviluppo Web e può essere integrato nell'HTML. La sua sintassi è basata su quella di C, Java e Perl, ed è molto semplice da imparare. L'obiettivo principale del linguaggio è quello di permettere agli sviluppatori web di scrivere velocemente pagine web dinamiche, ma con PHP si possono fare molte altre cose.

Questo manuale consiste principalmente in un elenco commentato di funzioni, ma contiene anche una guida al linguaggio, la spiegazione di alcune delle principali caratteristiche e altre informazioni aggiuntive.

Il manuale è fornito in diversi formati qui: ???. Maggiori informazioni su come questo manuale viene sviluppato possono essere trovate nell'appendice 'Informazioni sul Manuale'.

Vedere anche: Storia del PHP.


Capitolo 1. Introduzione

Che cos'è il PHP?

PHP (acronimo ricorsivo per "PHP: Hypertext Preprocessor") è un linguaggio di scripting general-purpose Open Source molto utilizzato, è specialmente indicato per lo sviluppo Web e può essere integrato nell'HTML.

Risposta banale, ma che cosa significa? Un esempio:

Esempio 1-1. Un esempio introduttivo

<html>
    <head>
        <title>Esempio</title>
    </head>
    <body>

        <?php 
        echo "Ciao, sono uno script PHP!"; 
        ?>

    </body>
</html>

Notate come questo esempio è differente da uno script scritto in altri linguaggi tipo Perl o C -- invece di scrivere un programma con parecchi comandi per produrre HTML, si scrive in HTML con qualche comando immerso per ottenere dei risultati (in questo semplice esempio, la visualizzazione di una frase). Il codice PHP è delimitato da speciali start ed end tag che ne indicano l'inizio e la fine e che consentono di passare dal modo HTML al modo PHP.

Ciò che distingue PHP da altri linguaggi di scripting del tipo client-side JavaScript è che il codice viene eseguito nel server. Per avere uno script simile a quello sopra nel vostro server, il client dovrebbe ricevere il risultato ottenuto con lo script, senza sapere mai quali sono le funzioni eseguite. Potete persino configurare il vostro web server per processare tutte i vostri file HTML con PHP ed allora non ci sarebbe realmente alcun modo per gli utenti di sapere cosa avete sul vostro server.

La cosa più interessante nell'uso di PHP è che si tratta di un linguaggio estremamente semplice per il neofita, ma che, tuttavia, offre molte prestazioni avanzate al programmatore di professione. Non lasciatevi impressionare dalla lunga lista delle potenzialità di PHP. In poco tempo potrete iniziare a creare velocemente semplici scripts.

Sebbene lo sviluppo di PHP abbia come obiettivo lo scripting server-side, si può fare molto di più con esso. Leggete, e consultate la sezione Che cosa può fare PHP?.


Che cosa può fare PHP?

Qualsiasi cosa. PHP ha come obiettivo principale lo scripting server-side, per cui può fare tutto ciò che può fare un qualunque programma CGI, come raccogliere dati da un form, generare pagine dai contenuti dinamici, oppure mandare e ricevere cookies. Ma PHP può fare molto di più.

Esistono tre campi principali in cui vengono usati gli scripts PHP.

  • Lo scripting server-side. Questo è il campo più tradizionale ed il maggiore obiettivo del PHP. Per fare questo lavoro occorrono tre cose. Il parser PHP (CGI o server module), un webserver ed un browser web. Occorre avviare il server web con un'installazione di PHP attiva. Si può accedere all'output del programma PHP con un browser web e vedere la pagina PHP tramite il server. Consultate la sezione Istruzioni per l'installazione per ulteriori informazioni.

  • Lo scripting di righe di comando. Si può creare uno script PHP da usare senza alcun server o browser. Per usarlo in questo modo, l'unica cosa necessaria è un parser PHP. Questo tipo di utilizzo è ideale per gli scripts eseguiti con cron (task scheduler di Windows) o per tasks di solo testo. Vedere la sezione Uso di righe di comando in PHP per maggiori informazioni.

  • La creazione di applicazioni client-side GUI. Probabilmente PHP non è il linguaggio più adatto per scrivere applicazioni windowing, ma, se lo si conosce molto bene, e se se ne vogliono usare delle caratteristiche avanzate in applicazioni client-side, si può anche adoperare PHP-GTK per scrivere questo tipo di pogrammi. Allo stesso modo, c'è anche la possibilità di scrivere applicazioni cross-platform. PHP-GTK è un'estensione di PHP non reperibile nella grande distribuzione. Se vi interessa, visitate il sito web.

PHP può essere usato su tutti i principali sistemi operativi, inclusi Linux, molte varianti di Unix (compresi HP-UX, Solaris e OpenBSD), Microsoft Windows, MacOS X, MacOS Xserver, RISC OS, e probabilmente altri. Inoltre supporta anche la maggior parte dei server web esistenti. Ciò comprende Apache, Microsoft Internet Information Server, Personal Web Server, i servers Netscape ed iPlanet, Oreilly Website Pro Server, Caudium, Xitami, OmniHTTPd, e molti altri. Per la maggioranza dei servers PHP ha un modulo, per gli altri che supportano lo standard CGI, può funzionare come un processore CGI.

Pertanto, con PHP si ha la libertà di scegliere praticamente qualsiasi sistema operativo e qualsiasi server web. Inoltre, si può anche scegliere se fare uso di una programmazione procedurale oppure orientata agli oggetti, o una combinazione di entrambe. Sebbene non tutte le caratteristiche standard di OOP siano realizzate dalla versione corrente di PHP, molte librerie di codice e grandi applicazioni (compresa PEAR library) sono state scritte usando codice OOP.

Con PHP non siete limitati soltanto ad un output in HTML. Le possibilità di PHP, infatti, includono l'abilità di generare immagini, files PDF e perfino filmati Flash al volo (utilizzando libswf e Ming). Sarete in grado di generare facilmente qualsiasi testo, come XHTML e qualsiasi altro file XML. PHP può autogenerare questi file, e salvarli nel file system, piuttosto che eseguire un printing esterno, o creare server-side cache per contenuti dinamici.

Una delle caratteristiche più importanti e significative di PHP è la possibilit` di supportare una completa gamma di databases. Scrivere una pagina web collegata ad un database è incredibilmente semplice. Attualmente sono supportati i seguenti database:

Adabas DIngresOracle (OCI7 and OCI8)
dBaseInterBaseOvrimos
EmpressFrontBasePostgreSQL
FilePro (read-only)mSQLSolid
HyperwaveDirect MS-SQLSybase
IBM DB2MySQLVelocis
InformixODBCUnix dbm

Esiste anche un'estensione DBX database abstraction extension, che vi permette di usare in modo trasparente qualsiasi database da essa supportato. Inoltre PHP supporta ODBC, lo standard di collegamento con i database, pertanto è possibile collegarsi con qualsiasi database che supporti questo standard mondiale.

PHP fa anche da supporto per dialogare con altri servizi utilizzando i protocolli del tipo LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (in Windows) e innumerevoli altri. Potete anche aprire network sockets ed interagire usando qualsiasi altro protocollo. Inoltre supporta l'interscambio di dati complessi WDDX tra, virtualmente, tutti i linguaggi di programmazione web. A proposito di interconessioni, PHP supporta l'installazione dei JavaObjects e l'utilizzo di questi come oggetti PHP in modo trasparente. Si può anche usare la nostra estensione CORBA per accedere ad oggetti remoti.

PHP possiede alcune caratteristiche molto utili per la gestione del testo, da POSIX Extended o Perl regular expressions al parsing di documenti XML. Per fare il parsing ed accedere ai documenti XML, supportiamo gli standard SAX e DOM. Si può usare la nostra estensione XSLT per trasformare i documenti XML.

Se si usa PHP nel campo dell'E-commerce, si avranno a disposizione funzioni utili per i programmi di pagamento online, come: Cybercash, CyberMUT, Verysign Payflow Pro e CCVS.

L'ultimo, ma di non poca importanza, PHP ha molte altre estensioni interessanti, come funzioni per motori di ricerca mnoGoSearch, le funzioni IRC Gateway, molte utilità di compressione (gzip, bz2), conversione dei calendari, traduzione...

Come si può notare, questa pagina non è sufficiente per elencare tutte le funzioni che PHP offre. Per approfondire il discorso sulle suddette caratteristiche, consultate le sezioni Installazione di PHP, e function reference


Capitolo 2. Una semplice introduzione

Di seguito, in una breve e semplice introduzione, vorremmo mostrare alcuni esempi per l'utilizzo di PHP. Essi sono relativi soltanto alla creazione dinamica di pagine web, anche se PHP non ha funzionalità limitate esclusivamente alla creazione delle sole pagine web. Fare riferimento alla sezione intitolata Cosa può fare PHP per avere ulteriori informazioni.

Le pagine web create con PHP vengono trattate come normali pagine HTML e possono essere create e modificate nello stesso modo in cui si sviluppano normali pagine HTML.


Di cosa ho bisogno?

In questo tutorial assumiamo che il vostro server abbia il suporto PHP attivato e che tutti i file con estensione .php vengano gestiti da questo. Quasi in tutti i server questa è l'estensione di default per i file PHP., ma consultatevi col vostro system administrator per sicurezza. Se il vostro server supporta PHP, allora, non è necessario fare nulla. Semplicemente create i vostri file .php e scaricateli nella vostra directory web, il server le analizzerà e le eseguirà magicamente. Non è necessario compilare nulla nè installare strumenti aggiuntivi. Si pensi ai file PHP come a dei semplici file HTML con una intera famiglia aggiuntiva di magici tags che consentono di fare ogni sorta di cose.


La prima pagina PHP

Creare un file con nome ciao.php nella directory del web server che abbia il seguente contenuto:

Esempio 2-1. Il nostro primo script PHP: ciao.php

<html>
 <head>
  <title>Test PHP</title>
 </head>
 <body>
 <?php echo "Hello World!<p>"; ?>
 </body>
</html>

L'output di questo script sarà:
<html>
 <head>
  <title>Test PHP</title>
 </head>
 <body>
Hello World!<p>
 </body>
</html>

Si noti che questo file non è come uno script CGI. Il file non necessita in alcun modo di essere eseguibile o speciale in alcuna maniera. Si pensi ad esso come ad un normale file HTML nel quale sono contenuti uno speciale set di tags che permettono di eseguire una moltitudine di cose interessanti.

Questo programma è molto semplice e sicuramente non era necessario fare ricorso a PHP per creare una pagina come quella. Tutto ciò che essa fa è di visualizzare: Hello World! usando la funzione echo() di PHP.

Se si è provato questo esempio e non ha dato alcun output, o è apparso un pop-up che chiedeva se scaricare la pagina, o se è apparso il file come testo, probabilmente che il server su cui si stanno effettuando le prove non ha abilitato PHP. Provare a chiedere al proprio amministratore di sistema di abilitarlo per voi usando il capitolo del manuale dedicato all'Installazione. Se si vogliono sviluppare in locale script PHP, fare riferimento alla sezione download. Si può sviluppare senza problemi sul proprio Sistema Operativo in locale, è bene installare anche un web server.

L'obiettivo dell'esempio è quello di mostrare il formato speciale dei tag PHP. In questo esempio abbiamo usato <?php per indicare l'inizio di un tag PHP. Quindi abbiamo scritto la funzione PHP e abbiamo lasciato la modalità PHP usando il tag di chiusura, ?>. All'interno di un file HTML si può entrare ed uscire dalla modalità PHP quante volte si desidera.

Nota riguardo gli editor di testo: Esistomo molti editor di testo e Integrated Development Environment (IDE) che possono essere usati per creare, modificare e gestire file PHP. Una lista parziale di questi strumenti è disponibile qui: PHP Editor's List. Se si desidera suggerire un nuovo programma, visitare la pagina sopra e chiedere al curatore di aggiungerlo alla lista.

Nota riguardo i Word Processor: Word processor quali StarOffice Writer, Microsoft Word e Abiword non sono una buona scelta per modificare i file PHP.

Se si vogliono provare comunque per scrivere questo script di test, ci si deve assicurare di salvare il file come SOLO TESTO, altrimenti PHP non sarà in grado di leggerlo e quindi non riuscirà ad eseguire lo script.

Nota riguardo Blocco Note di Windows: Se si scrive codice usando l'applicazione di Windows Blocco Note, occorre assicurarsi che i file vengano salvati con estensione .php. (Blocco Note aggiunge automaticamente l'estensione .txt ai file, a meno che non si intraprenda uno dei passi descritti di seguito.)

Quando si salva il file e viene chiesto il nome da assegnargli, scrivere il nome fra virgolette (ad esempio: "ciao.php").

In alternativa, si può cliccare sul menu a tendina 'Documenti di Testo' nella finestra di salvataggio e cambiare l'impostazione in "Tutti i File". A quel punto si può inserire il nome del file, senza usare le virgolette.


Qualcosa di utile

Andiamo a fare qualcosa di leggermente più utile. Andremo a controllare che tipo di browser sta utilizzando la persona che visita le nostre pagine. Per fare questo si andrà a controllare la stringa dell'user agent che il browser invia come parte della richiesta HTTP. Quest'informazione viene inviata in una variabile. Le Variabili iniziano sempre con il simbolo di dollaro $ in PHP. La variabile alla quale ci riferiamo adesso è $_SERVER["HTTP_USER_AGENT"].

Note sulle variabili Autoglobali di PHP: $_SERVER è una variabile speciale riservata a PHP la quale contiene tutte le informazioni relative al Web Server. È conosciuta come Variabile autoglobale (o Superglobale). Per maggiori informazioni è possibile vedere la pagina del manuale relativa alle Variabili Autoglobali. Questo tipo di variabili sono state introdotte nella versione 4.1.0 di PHP. Nelle versioni precedenti abbiamo utilizzato le ormai vecchie $HTTP_SERVER_VARS, oggi in disuso, anche se queste continuano ad esistere. (Potete guardare nelle note del vecchio codice.)

Per visualizzare questa variabile, dobbiamo semplicemente:

Esempio 2-2. Stampare video una variable (elemento d'Array)

<?php echo $_SERVER["HTTP_USER_AGENT"]; ?>

L'output (risultato) di questo script potrebbe essere:
Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)

Ci sono molti types (tipi) di variabili disponibili in PHP. Nell'esempio di sopra abbiamo stampato un elemento di un Array. Gli Array possono essere molto utili.

$_SERVER è soltanto una variabile che automaticamente viene resa diponibile da PHP. È possibile visualizzare una lunga lista nella sezione Variabili riservate del manuale oppure ottenere la lista completa creando un file php nella seguente forma:

Esempio 2-3. Mostrare tutte le variabili predefinite di PHP con phpinfo()

<?php phpinfo(); ?>

Se caricate questo documento da un browser riceverete una pagina piena d'informazioni circa PHP, così come la lista di tutte le variabili disponibili.

Potete mettere dichiarazioni multipli di PHP all'interno di un tag di PHP e generare piccoli blocchi di codice che fanno di più di un singolo echo. Per esempio, se desiderassimo controllare per vedere se l'utente usa Internet Explorer potremmo fare qualcosa come questo:

Esempio 2-4. Esempi usando le strutture di controllo e le funzioni

<?php
if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE")) {
	echo "Stai usando Internet Explorer<br />";
}
?>

L'output di esempio di questo script potrebbe essere:
Stai usando Internet Explorer<br />

Qui introduciamo una coppia di nuovi concetti. Abbiamo la dichiarazione if (se). Se avete una conoscenza con la sintassi di base usata dal linguaggio C questo dovrebbe sembrare logico per voi. Se non conoscete abbastanza C od un altro linguaggio che utilizza la sintassi qui sopra descritta, dovreste probabilmente prendere qualsiasi libro introduttivo di PHP e leggere i primi capitoli, o leggere la parte del manuale relativa ai Riferimenti del Linguaggio. Potete trovare una lista dei libri di PHP su http://www.php.net/books.php.

Il secondo concetto che abbiamo introdotto era la chiamata alla funzione strstr(). Questa è una funzione sviluppata in PHP che cerca una stringa all'interno di un'altra stringa. In questo caso abbiamo cercato "MSIE" all'interno della stringa $_SERVER["HTTP_USER_AGENT"]. Se la stringa viene trovata, la funzione restituisce TRUE altrimenti, FALSE. Se restituisce TRUE, la dichiarazione if viene valuta come TRUE ed il codice all'interno dei relativi {braces} (sostegni) sarà eseguito. Altrimenti, non esegue altro. Sentitevi liberi di generare esempi simili, con if, else (altrimenti) ed altre funzioni quali strtoupper() e strlen(). Ogni pagina del manuale, relativa a queste funzioni contiene anche degli esempi pratici.

Possiamo fare un passo avanti e mostrarvi come potete entrare ed uscite dal modo PHP anche dall' interno di un blocco PHP:

Esempio 2-5. Intercalare i modi PHP e HTML

<?php
if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE")) {
?>
<h3>strstr dovrebbe ritornare true</h3>
<center><b>Stai usando Internet Explorer</b></center>
<?php
} else {
?>
<h3>strstr dovrebbe ritornare false</h3>
<center><b>Non stai usando Internet Explorer</b></center>
<?php
}
?>

L'output di esempio di questo script potrebbe essere:
<h3>strstr dovrebbe ritornare true</h3>
<center><b>Stai usando Internet Explorer</b></center>

Invece di usare la dichiarazione echo per fare l'output di qualcosa, saltiamo fuori dal modo PHP inviando soltanto HTML puro. Il punto importante da notare qui è che il flusso logico dello script rimane intatto. Solo uno dei blocchi di di HTML finirà per essere inviato come risposta, dipendendo se strstr() ritorna TRUE o FALSE in altre parole, se la stringa MSIE viene trovata o meno.


Trattare con i Form

Una delle caratteritiche più forti di PHP è il modo in cui gestisce i form. Il concetto da comprendere principalmente è che qualsiasi elemento di un form sarà automaticamente disponibile per i vostri script PHP. Per maggiori informazioni ed esempi relativi all'utilizzo dei form consultate la sezione del manuale che si riferisce a le Variabili al di fuori di PHP. A seguire un esempio di un form HTML:

Esempio 2-6. Un semplice form HTML

<form action="action.php" method="POST">
 Il tuo Nome: <input type="text" name="name" value="" />
 La tua et&agrave;: <input type="text" name="age" value ="" />
 <input type="submit">
</form>

Questo form non ha niente di speciale. È un semplice form in HTML che non presenta nessun tipo di tags particolari. Quando l'utente riempie questo form e preme il pulsante submit, viene richiamata la pagina action.php. In questo file il risultato sarà qualcosa di simile:

Esempio 2-7. La stampa video di dati dal nostro form

Ciao <?php echo $_POST["name"]; ?>.
La tua età è di <?php echo $_POST["age"]; ?> anni.

Ecco un possibile output di questo script:
Ciao Joe.
La tua et&agrave; &egrave; di 22 anni.

Ciò che avviene dovrebbe risultare ovvio. Non c' è altro da aggiungere. Le variabili $_POST["name"] e $_POST["age"] vengono impostate automaticamente dal PHP. Prima avevamo usato la variabile autoglobal $_SERVER, ora invece abbiamo introdotto la variabile autoglobal $_POST che contiene tutti i dati di tipo POST. Notate che il metodo del nostro form è il POST. Se usassimo il metodo GET le informazioni ricavate dal nostro form si troverebbero invece in $_GET. Si può anche usare la variabile $_REQUEST se la provenienza dei dati richiesti non ci interessa. Questa variabile contiene un misto di dati GET, POST, COOKIE e FILE. Vedere anche la funzione import_request_variables().


L' uso di vecchi codici con le nuove versioni di PHP

Da quando il PHP è divenuto un linguaggio di scripting popolare, esistono più fonti che producono listati di codice che si possono adoperare nei propri scripts. La maggioranza degli sviluppatori del PHP ha cercato di renderlo compatibile con le versioni precedenti, perciò uno script creato per una vecchia versione del PHP dovrebbe girare senza modifiche (in teoria) in una più recente, ma in pratica spesso possono servire delle correzioni.

Ecco due delle più importanti modifiche apportate al vecchio codice:

  • Il disuso dei vecchi arrays $HTTP_*_VARS (che devono essere dichiarati global quando vengano adoperati all' interno di una funzione o di un metodo). L' introduzione in PHP 4.1.0 dei seguenti autoglobal arrays: $_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_REQUEST, and $_SESSION. I vecchi arrays $HTTP_*_VARS quali $HTTP_POST_VARS, invece, continuano ad essere adoperati fin da PHP3.

  • Le variabili esterne non vengono più registrate nel global scope per default. In altre parole, da PHP 4.2.0 la direttiva PHP register_globals è off per default in php.ini. Il metodo consigliato per accedere a questi valori è quello che fa uso degli arrays autoglobali suddetti. Scripts, libri e tutorials più vecchi devono attenersi a queste direttive. Se, per esempio, qualcuno potesse usare $id dall'URL http://www.example.com/foo.php?id=42. La variabile, $_GET['id'] sarebbe disponibile indifferentemente del fatto che sia on od off.

Per ulteriori dettagli su queste innovazioni, vedere la sezione sulle variabili predefinite ed i links ad essa connessi.


E poi?

Con quello che sapete ora dovreste essere in grado di comprendere la maggior parte del manuale ed anche i vari scripts di esempio reperibili nelle raccolte di esempi. Inoltre potete trovarne altri sui siti web di php.net nella sezione links: http://www.php.net/links.php.


Capitolo 3. Installazione


Considerazioni generali sull'installazione

Prima di installare, occorre sapere che cosa dsi desidera fare con il PHP. Esistono tre campi principali in cui utilizzare il PHP, come descritto nella sezione Cosa può fare il PHP?:

  • Scripting Server-side

  • Scripting da linea di comando

  • Applicazioni GUI Client-side

Per il primo, e più comune utilizzo, occorrono tre cose: il PHP, un server web ed un browser web. Probabilmente si possiede già un browser web, e, in base alla configurazione del sistema operativo, si potrebbe anche avere un server web (es. Apache su Linux, oppure IIS su Windows). Si potrebbe anche affittare dello spazio web da una azienda. In Questo caso non si ha nulla da impostare, ma soltanto scrivere gli script PHP, scaricarli sul server che si è affittato, e vedere il risultato.

Nel caso si decida di attivare web ed PHP in autonomia, si hanno due metodologie per collegare il PHP al server web. Per molti server il PHP ha un modulo apposito (chiamato anche SAPI). Tra questi: Apache, Microsoft Internet Information Server, Netscape e iPlanet servers. Diversi altri server hanno il supporto per ISAPI, il modulo d'interfaccia Microsoft (OmniHTTPd ad esempio). Se il PHP non ha un modulo per il server web prescelto, si può sempre utilizzare il PHP come CGI. Ciò significa configurare il server per eseguirà la versione da linea di comando di PHP (php.exe su Windows) per processare tutti i file PHP richiesti al server.

Se si è interessati ad utilizzare PHP da linea di comando (es. sviluppare script che producano immagini offline, o che elaborino file di testo in base a parametri passati), occorre avere l'eseguibile per la linea di comando. Per maggiori dettagli, leggere la sezione su scrivere applicazioni PHP da linea di comando. In questo caso non occorre ne il serve web, ne il browser.

Con il PHP si possono anche scrivere applicazioni grafiche client-side utlizzando l'estensione PHP-GTK. In questo caso si ha un approccio completamente differente rispetto a scrivere una pagina web, dato che non si produce codice HTML, ma si gestiscono finestre e oggetti all'interno di queste. Per maggiori dettagli su PHP-GTK, visitare il sito dedicato a questa estensione. PHP-GTK non è incluso nella distribuzione ufficiale di PHP.

Da questo punto in poi, questo capitolo tratterà come settare il PHP con vari server web sia su Unix sia su Windows con i moduli per i server oppure come CGI.

Si può scaricare i sorgenti e gli eseguibili per Windows da http://www.php.net/downloads.php. Si suggerisce di utilizzare il mirror più vicino per scaricare le distribuzioni.


Installazione su Unix/HP-UX

Questa sezione contiene note e suggerimenti per l'installazione di PHP su sistemi HP-UX. (Contributo di paul_mckay at clearwater-it dot co dot uk).

Nota: Queste note sono state scritte per PHP 4.0.4 e Apache 1.3.9.

  1. Occorre gzip, scaricare l'eseguibile da http://hpux.connect.org.uk/ftp/hpux/Gnu/gzip-1.2.4a/gzip-1.2.4a-sd-10.20.depot.Z decomprimere il file e installarlo con swinstall.

  2. Serve gcc, scaricare la distribuzione con l'eseguibile da http://gatekeep.cs.utah.edu/ftp/hpux/Gnu/gcc-2.95.2/gcc-2.95.2-sd-10.20.depot.gz. decomprimere il file e installare gcc con swinstall.

  3. Occorrono le binutils GNU, si possono scaricare da http://hpux.connect.org.uk/ftp/hpux/Gnu/binutils-2.9.1/binutils-2.9.1-sd-10.20.depot.gz. decomprimere il file e installare le binutils con swinstall.

  4. A questo punto serve bison, scaricare la distribuzione con l'eseguibile da http://hpux.connect.org.uk/ftp/hpux/Gnu/bison-1.28/bison-1.28-sd-10.20.depot.gz, installare come i precedenti

  5. Ora serve flex, occorre scaricare il sorgente da uno dei mirror di http://www.gnu.org. Si trova in una directory non GNU del sito ftp. Scaricare il file, gunzip, quindi tar -xvf. Entrare nella directory di flex appena creata ed eseguire ./configure, seguito da make, e quindi make install.

    Se si verifica un errore, probabilmente è dovuto al fatto che gcc o uno degli altri eseguibili non si trovano in PATH, pertanto aggiungerli in PATH.

  6. Scaricare i sorgenti di PHP e Apache.

  7. Eseguire gunzip e tar -xvf. Ora dobbiamo modificare un paio di file in modo da poterli compilare.

  8. Per primo il file configure, occorre modificarlo perchè sembra che perda traccia del fatto di essere su una macchina hpux, esistono metodi migliori per fare ciò, ma il più semplice consiste nel mettere lt_target=hpux10.20 alla linea 47286 di configure.

  9. Quindi occorre intervenire sul file di Apache GuessOS. Nella directory apache_1.3.9/src/helpers cambiare la linea 89 da echo "hp${HPUXMACH}-hpux${HPUXVER}"; exit 0 a: echo "hp${HPUXMACH}-hp-hpux${HPUXVER}"; exit 0

  10. Non si può installare il PHP come oggetto condiviso in HP-UX, pertanto occorre compilarlo come statico, basta seguire le istruzioni alla pagina di Apache.

  11. PHP e Apache dovrebbero essersi compilati correttamente, ma Apache non parte. Occorre creare un nuovo utente per Apache, es www, o apache. Quindi cambiare le linee 252 e 253 del file conf/httpd.conf di Apache in questo modo:

    User nobody 
    Group nogroup

    si dovrebbe avere qualcosa tipo

    User www 
    Group sys

    Questo perchè non si può eseguire Apache come utente nobody in HP-UX. A questo punto Apache e PHP dovrebbero funzionare.


Installazione su Unix/Linux

Questa sezione contiene note e suggerimenti specifici dell'installazione di PHP su distribuzioni Unix.


Uso dei pacchetti

Diverse distribuzioni Linux hanno un qualche metodo per installare i pacchetti tipo RPM. Questo può aiutare nell'impostare una configurazione standard, ma se si desidera avere delle caratteristiche differenti (tipo un server sicuro, driver per database differenti) occorre compilare il PHP e/o il server web. Se non si è pratici nella compilazione del software, potrebbe essere conveniente cercare qualcuno che abbia già pacchettizzato una versione di PHP con le caratteristiche desiderate.


Unix/Mac OS X installs

This section contains notes and hints specific to installing PHP on Mac OS X Server.


Using Packages

There are a few pre-packaged and pre-compiled versions of PHP for Mac OS X. This can help in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your web server yourself. If you are unfamiliar with building and compiling your own software, it's worth checking whether somebody has already built a packaged version of PHP with the features you need.


Compiling for OS X server

There are two slightly different versions of Mac OS X, client and server. The following is for OS X Server.

Mac OS X server install.

  1. Get the latest distributions of Apache and PHP.

  2. Untar them, and run the configure program on Apache like so.
    ./configure --exec-prefix=/usr \
    --localstatedir=/var \
    --mandir=/usr/share/man \
    --libexecdir=/System/Library/Apache/Modules \
    --iconsdir=/System/Library/Apache/Icons \
    --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \
    --enable-shared=max \
    --enable-module=most \
    --target=apache

  3. If you want the compiler to do some optimization., you may also want to add this line:
    setenv OPTIM=-O2

  4. Next, go to the PHP 4 source directory and configure it.
    ./configure --prefix=/usr \
        --sysconfdir=/etc \
        --localstatedir=/var \
        --mandir=/usr/share/man \
        --with-xml \
        --with-apache=/src/apache_1.3.12
    If you have any other additions (MySQL, GD, etc.), be sure to add them here. For the --with-apache string, put in the path to your apache source directory, for example /src/apache_1.3.12.

  5. Type make and make install. This will add a directory to your Apache source directory under src/modules/php4.

  6. Now, reconfigure Apache to build in PHP 4.
    ./configure --exec-prefix=/usr \
    --localstatedir=/var \
    --mandir=/usr/share/man \
    --libexecdir=/System/Library/Apache/Modules \
    --iconsdir=/System/Library/Apache/Icons \
    --includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \
    --enable-shared=max \
    --enable-module=most \
    --target=apache \
    --activate-module=src/modules/php4/libphp4.a
    You may get a message telling you that libmodphp4.a is out of date. If so, go to the src/modules/php4 directory inside your apache source directory and run this command: ranlib libmodphp4.a. Then go back to the root of the apache source directory and run the above configure command again. That'll bring the link table up to date. Run make and make install again.

  7. Copy and rename the php.ini-dist file to your bin directory from your PHP 4 source directory: cp php.ini-dist /usr/local/bin/php.ini or (if your don't have a local directory) cp php.ini-dist /usr/bin/php.ini.


Compiling for MacOS X client

Those tips are graciously provided by Marc Liyanage.

The PHP module for the Apache web server included in Mac OS X. This version includes support for the MySQL and PostgreSQL databases.

NOTE: Be careful when you do this, you could screw up your Apache web server!

Do this to install:

  1. Open a terminal window.

  2. Type wget http://www.diax.ch/users/liyanage/software/macosx/libphp4.so.gz, wait for the download to finish.

  3. Type gunzip libphp4.so.gz.

  4. Type sudo apxs -i -a -n php4 libphp4.so

  5. Now type sudo open -a TextEdit /etc/httpd/httpd.conf. TextEdit will open with the web server configuration file. Locate these two lines towards the end of the file: (Use the Find command)
    #AddType application/x-httpd-php .php 
    #AddType application/x-httpd-php-source .phps
    Remove the two hash marks (#), then save the file and quit TextEdit.

  6. Finally, type sudo apachectl graceful to restart the web server.

PHP should now be up and running. You can test it by dropping a file into your Sites folder which is called test.php. Into that file, write this line: <?php phpinfo() ?>.

Now open up 127.0.0.1/~your_username/test.php in your web browser. You should see a status table with information about the PHP module.


Unix/OpenBSD installs

This section contains notes and hints specific to installing PHP on OpenBSD 3.4.


Using Binary Packages

Using binary packages to install PHP on OpenBSD is the recommended and simplest method. The core package has been separated from the various modules, and each can be installed and removed independently from the others. The files you need can be found on your OpenBSD CD or on the FTP site.

The main package you need to install is php4-core-4.3.3.tgz, which contains the basic engine (plus gettext and iconv). Next, take a look at the module packages, such as php4-mysql-4.3.3.tgz or php4-imap-4.3.3.tgz. You need to use the phpxs command to activate and deactivate these modules in your php.ini.

Esempio 3-1. OpenBSD Package Install Example

# pkg_add php4-core-4.3.3.tgz
# /usr/local/sbin/phpxs -s
# cp /usr/local/share/doc/php4/php.ini-recommended /var/www/conf/php.ini
  (add in mysql)
# pkg_add php4-mysql-4.3.3.tgz
# /usr/local/sbin/phpxs -a mysql
  (add in imap)
# pkg_add php4-imap-4.3.3.tgz
# /usr/local/sbin/phpxs -a imap
  (remove mysql as a test)
# pkg_delete php4-mysql-4.3.3
# /usr/local/sbin/phpxs -r mysql
  (install the PEAR libraries)
# pkg_add php4-pear-4.3.3.tgz

Read the packages(7) manual page for more information about binary packages on OpenBSD.


Using Ports

You can also compile up PHP from source using the ports tree. However, this is only recommended for users familiar with OpenBSD. The PHP 4 port is split into two sub-directories: core and extensions. The extensions directory generates sub-packages for all of the supported PHP modules. If you find you do not want to create some of these modules, use the no_* FLAVOR. For example, to skip building the imap module, set the FLAVOR to no_imap.


Common Problems

  • The default install of Apache runs inside a chroot(2) jail, which will restrict PHP scripts to accessing files under /var/www. You will therefore need to create a /var/www/tmp directory for PHP session files to be stored, or use an alternative session backend. In addition, database sockets need to be placed inside the jail or listen on the localhost interface. If you use network functions, some files from /etc such as /etc/resolv.conf and /etc/services will need to be moved into /var/www/etc. The OpenBSD PEAR package automatically installs into the correct chroot directories, so no special modification is needed there. More information on the OpenBSD Apache is available in the OpenBSD FAQ.

  • The OpenBSD 3.4 package for the gd extension requires XFree86 to be installed. If you do not wish to use some of the font features that require X11, install the php4-gd-4.3.3-no_x11.tgz package instead.


Older Releases

Older releases of OpenBSD used the FLAVORS system to compile up a statically linked PHP. Since it is hard to generate binary packages using this method, it is now deprecated. You can still use the old stable ports trees if you wish, but they are unsupported by the OpenBSD team. If you have any comments about this, the current maintainer for the port is Anil Madhavapeddy (avsm at openbsd dot org).


Unix/Solaris installs

This section contains notes and hints specific to installing PHP on Solaris systems.


Required software

Solaris installs often lack C compilers and their related tools. Read this FAQ for information on why using GNU versions for some of these tools is necessary. The required software is as follows:

  • gcc (recommended, other C compilers may work)

  • make

  • flex

  • bison

  • m4

  • autoconf

  • automake

  • perl

  • gzip

  • tar

  • GNU sed

In addition, you will need to install (and possibly compile) any additional software specific to your configuration, such as Oracle or MySQL.


Using Packages

You can simplify the Solaris install process by using pkgadd to install most of your needed components.


Installation on Unix systems

This section will guide you through the general configuration and installation of PHP on Unix systems. Be sure to investigate any sections specific to your platform or web server before you begin the process.

Prerequisite knowledge and software:

  • Basic Unix skills (being able to operate "make" and a C compiler, if compiling)

  • An ANSI C compiler (if compiling)

  • flex (for compiling)

  • bison (for compiling)

  • A web server

  • Any module specific components (such as gd, pdf libs, etc.)

There are several ways to install PHP for the Unix platform, either with a compile and configure process, or through various pre-packaged methods. This documentation is mainly focused around the process of compiling and configuring PHP.

The initial PHP setup and configuration process is controlled by the use of the commandline options of the configure script. This page outlines the usage of the most common options, but there are many others to play with. Check out the Complete list of configure options for an exhaustive rundown. There are several ways to install PHP:


Apache Module Quick Reference

PHP can be compiled in a number of different ways, but one of the most popular is as an Apache module. The following is a quick installation overview.

Esempio 3-2. Quick Installation Instructions for PHP 4 (Apache Module Version)

1.  gunzip apache_1.3.x.tar.gz
2.  tar xvf apache_1.3.x.tar
3.  gunzip php-x.x.x.tar.gz
4.  tar xvf php-x.x.x.tar
5.  cd apache_1.3.x
6.  ./configure --prefix=/www
7.  cd ../php-x.x.x
8.  ./configure --with-mysql --with-apache=../apache_1.3.x --enable-ftp
9.  make
10. make install
11. cd ../apache_1.3.x
12. ./configure --activate-module=src/modules/php4/libphp4.a
13. make
14. make install
15. cd ../php-x.x.x
16. cp php.ini-dist /usr/local/lib/php.ini
17. Edit your httpd.conf or srm.conf file and add: 
      AddType application/x-httpd-php .php

18. Use your normal procedure for restarting the Apache server. (You must
    stop and restart the server, not just cause the server to reload by
    use a HUP or USR1 signal.)

Building

When PHP is configured, you are ready to build the CGI executable. The command make should take care of this. If it fails and you can't figure out why, see the Problems section.


Installation on Windows systems

This section applies to Windows 98/Me and Windows NT/2000/XP. PHP will not work on 16 bit platforms such as Windows 3.1 and sometimes we refer to the supported Windows platforms as Win32. Windows 95 is no longer supported as of PHP 4.3.0.

There are two main ways to install PHP for Windows: either manually or by using the InstallShield installer.

If you have Microsoft Visual Studio, you can also build PHP from the original source code.

Once you have PHP installed on your Windows system, you may also want to load various extensions for added functionality.


Windows InstallShield

The Windows PHP installer is available from the downloads page at http://www.php.net/downloads.php. This installs the CGI version of PHP and, for IIS, PWS, and Xitami, configures the web server as well.

Nota: While the InstallShield installer is an easy way to make PHP work, it is restricted in many aspects, as automatic setup of extensions for example is not supported. The whole set of supported extensions is only available by downloading the zip binary distribution.

Install your selected HTTP server on your system and make sure that it works.

Run the executable installer and follow the instructions provided by the installation wizard. Two types of installation are supported - standard, which provides sensible defaults for all the settings it can, and advanced, which asks questions as it goes along.

The installation wizard gathers enough information to set up the php.ini file and configure the web server to use PHP. For IIS and also PWS on NT Workstation, a list of all the nodes on the server with script map settings is displayed, and you can choose those nodes to which you wish to add the PHP script mappings.

Once the installation has completed the installer will inform you if you need to restart your system, restart the server, or just start using PHP.

Avvertimento

Be aware, that this setup of PHP is not secure. If you would like to have a secure PHP setup, you'd better go on the manual way, and set every option carefully. This automatically working setup gives you an instantly working PHP installation, but it is not meant to be used on online servers.


Manual Installation Steps

This install guide will help you manually install and configure PHP on your Windows webserver. The original version of this guide was compiled by Bob Silva, and can be found at http://www.umesd.k12.or.us/php/win32install.html. You need to download the zip binary distribution from the downloads page at http://www.php.net/downloads.php.

PHP 4 for Windows comes in three flavours - a CGI executable (php.exe), a CLI executable (sapi/php.exe) and some other SAPI modules:

php4apache.dll - Apache 1.3.x module
php4apache2.dll - Apache 2.0.x module
php4isapi.dll - ISAPI Module for ISAPI compliant webservers like IIS 4.0/PWS 4.0 or newer.
php4nsapi.dll - Netscape/iPlanet module

The latter form is new to PHP 4, and provides significantly improved performance and some new functionality. The CLI version is designed to use PHP for command line scripting. More information about CLI is available in the chapter about using PHP from the command line

Avvertimento

The SAPI modules have been significantly improved in the 4.1 release, however, you may find that you encounter possible server errors or other server modules such as ASP failing, in older systems.

DCOM and MDAC requirements: If you choose one of the SAPI modules and use Windows 95, be sure to download and install the DCOM update from the Microsoft DCOM pages. If you use Microsoft Windows 9x/NT4 download the latest version of the Microsoft Data Access Components (MDAC) for your platform. MDAC is available at http://msdn.microsoft.com/data/.

The following steps should be performed on all installations before any server specific instructions.

  • Extract the distribution file to a directory of your choice, c:\ is a good start. The zip package expands to a foldername like php-4.3.1-Win32 which is assumed to be renamed to php. For the sake of convenience and to be version independent the following steps assume your extracted version of PHP lives in c:\php. You might choose any other location but you probably do not want to use a path in which spaces are included (for example: C:\Program Files\PHP is not a good idea). Some web servers will crash if you do. The structure of your directory you extracted the zip file will look like:

c:\php
   |
   +--cli
   |  |
   |  |-php.exe           -- CLI executable - ONLY for commandline scripting
   |
   |
   +--dlls                -- support dlls for extensions --> Windows system directory
   |  |
   |  |-expat.dll
   |  |
   |  |-fdftk.dll
   |  |
   |  |-...
   |
   +--extensions          -- extension dlls for PHP
   |  |
   |  |-php_bz2.dll
   |  |
   |  |-php_cpdf.dll
   |  |
   |  |-..
   |
   +--mibs                -- support files for SNMP
   |
   |
   +--openssl             -- support files for Openssl
   |
   |
   +--pdf-related         -- support files for PDF
   |
   |
   +--sapi                -- SAPI dlls
   |  |
   |  |-php4apache.dll
   |  |
   |  |-php4apache2.dll
   |  |
   |  |-php4isapi.dll
   |  |
   |  |-..
   |
   |-install.txt
   |
   |-..
   |
   |-php.exe              -- CGI executable
   |
   |-..
   |
   |-php.ini-dist
   |
   |-php.ini-recommended
   | 
   |-php4ts.dll           -- main dll --> Windows system directory
   | 
   |-...

The CGI binary - c:\php\php.exe -, the CLI binary - c:\php\cli\php.exe -, and the SAPI modules - c:\php\sapi\*.dll - rely on the main dll c:\php\php4ts.dll. You have to make sure, that this dll can be found by your PHP installation. The search order for this dll is as follows:

The same directory from where php.exe is called. In case you use a SAPI module the same directory from where your webserver loads the dll (e.g. php4apache.dll).
Any directory in your Windows PATH environment variable.

  • The best bet is to make php4ts.dll available, regardless which interface (CGI or SAPI module) you plan to use. To do so, you have to copy this dll to a directory on your Windows path. The best place is your Windows system directory:

    C:\Windows\System for Windows 9x/ME
    C:\WINNT\System32 for Windows NT/2000 or C:\WINNT40\System32 for NT/2000 server
    C:\Windows\System32 for Windows XP

    If you plan to use a SAPI module from c:\php\sapi and do not like to copy dlls to your Windows system directory, you have the alternative choice to simply copy php4ts.dll to the sapi folder of your extracted zip package, c:\php\sapi.

  • The next step is to set up a valid configuration file for PHP, php.ini. There are two ini files distributed in the zip file, php.ini-dist and php.ini-recommended. We advise you to use php.ini-recommended, because we optimized the default settings in this file for performance, and security. Read this well documented file carefully and in addition study the ini settings and set every element manually yourself. If you would like to achieve the best security, then this is the way for you, although PHP works fine with these default ini files. Copy your chosen ini-file to a directory where PHP is able to find and rename it to php.ini. By default PHP searches php.ini in your Windows directory:

    On Windows 9x/ME/XP copy your chosen ini file to your %WINDIR%, which is typically C:\Windows.
    On Windows NT/2000 copy your chosen ini file to your %WINDIR% or %SYSTEMROOT%, which is typically C:\WINNT or C:\WINNT40 for NT/2000 servers.

  • If you're using NTFS on Windows NT, 2000 or XP, make sure that the user running the webserver has read permissions to your php.ini (e.g. make it readable by Everyone).

The following steps are optional.

  • Edit your new php.ini file. If you plan to use OmniHTTPd, do not follow the next step. Set the doc_root to point to your webservers document_root. For example:

    doc_root = c:\inetpub        // for IIS/PWS
    
    doc_root = c:\apache\htdocs // for Apache

  • Choose which extensions you would like to load when PHP starts. See the section about Windows extensions, about how to set up one, and what is already built in. Note that on a new installation it is advisable to first get PHP working and tested without any extensions before enabling them in php.ini.

  • On PWS and IIS, you can set the browscap configuration setting to point to: c:\windows\system\inetsrv\browscap.ini on Windows 9x/Me, c:\winnt\system32\inetsrv\browscap.ini on NT/2000, and c:\windows\system32\inetsrv\browscap.ini on XP.

Following this instructions you are done with the basic steps to setup PHP on Windows. The next step is to choose a webserver and enable it to run PHP. Installation instructions for the following webservers are available:


Building from source

Before getting started, it is worthwhile answering the question: "Why is building on Windows so hard?" Two reasons come to mind:

  1. Windows does not (yet) enjoy a large community of developers who are willing to freely share their source. As a direct result, the necessary investment in infrastructure required to support such development hasn't been made. By and large, what is available has been made possible by the porting of necessary utilities from Unix. Don't be surprised if some of this heritage shows through from time to time.

  2. Pretty much all of the instructions that follow are of the "set and forget" variety. So sit back and try follow the instructions below as faithfully as you can.


Requisiti

To compile and build PHP you need a Microsoft Development Environment. Microsoft Visual C++ 6.0 is recommended. To extract the downloaded files you need a extraction utility (e.g.: Winzip). If you don't already have an unzip utility, you can get a free version from InfoZip.

Before you get started, you have to download...

Finally, you are going to need the source to PHP 4 itself. You can get the latest development version using anonymous CVS, a snapshot or the most recent released source tarball.


Putting it all together

After downloading the required packages you have to extract them in a proper place.

  • Create a working directory where all files end up after extracting, e.g: C:\work.

  • Create the directory win32build under your working directory (C:\work) and unzip win32build.zip into it.

  • Create the directory bindlib_w32 under your working directory (C:\work) and unzip bindlib_w32.zip into it.

  • Extract the downloaded PHP source code into your working directory (C:\work).

Following this steps your directory structure looks like this:

+--c:\work
|  |
|  +--bindlib_w32
|  |  |
|  |  +--arpa
|  |  |
|  |  +--conf
|  |  |
|  |  +--...
|  |
|  +--php-4.x.x
|  |  |
|  |  +--build
|  |  |
|  |  +--...
|  |  |
|  |  +--win32
|  |  |
|  |  +--...
|  |
|  +--win32build
|  |  |
|  |  +--bin
|  |  |
|  |  +--include
|  |  |
|  |  +--lib

Create the directories c:\usr\local\lib. Copy bison.simple from c:\work\win32build\bin to c:\usr\local\lib.

Nota: Cygwin users may omit the last step. A properly installed Cygwin environment provides the mandatory files bison.simple and bison.exe.


Configure MVC ++

The next step is to configure MVC ++ to prepare for compiling. Launch Microsoft Visual C++, and from the menu select Tools => Options. In the dialog, select the directories tab. Sequentially change the dropdown to Executables, Includes, and Library files. Your entries should look like this:

  • Executable files: c:\work\win32build\bin, Cygwin users: cygwin\bin

  • Include files: c:\work\win32build\include

  • Library files: c:\work\win32build\lib


Build resolv.lib

You must build the resolv.lib library. Decide whether you want to have debug symbols available (bindlib - Win32 Debug) or not (bindlib - Win32 Release). Build the appropriate configuration:

  • For GUI users, launch VC++, and then select File => Open Workspace, navigate to c:\work\bindlib_w32 and select bindlib.dsw. Then select Build=>Set Active Configuration and select the desired configuration. Finally select Build=>Rebuild All.

  • For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands:

    • msdev bindlib.dsp /MAKE "bindlib - Win32 Debug"

    • msdev bindlib.dsp /MAKE "bindlib - Win32 Release"

At this point, you should have a usable resolv.lib in either your c:\work\bindlib_w32\Debug or Release subdirectories. Copy this file into your c:\work\win32build\lib directory over the file by the same name found in there.


Compiling

The best way to get started is to build the CGI version.

  • For GUI users, launch VC++, and then select File => Open Workspace and select c:\work\php-4.x.x\win32\php4ts.dsw . Then select Build=>Set Active Configuration and select the desired configuration, either php4ts - Win32 Debug_TS or php4ts - Win32 Release_TS. Finally select Build=>Rebuild All.

  • For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands from the c:\work\php-4.x.x\win32 directory:

    • msdev php4ts.dsp /MAKE "php4ts - Win32 Debug_TS"

    • msdev php4ts.dsp /MAKE "php4ts - Win32 Release_TS"

    • At this point, you should have a usable php.exe in either your c:\work\php-4.x.x.\Debug_TS or Release_TS subdirectories.

It is possible to do minor customization to the build process by editing the main/config.win32.h file. For example you can change the default location of php.ini, the built-in extensions, and the default location for your extensions.

Next you may want to build the CLI version which is designed to use PHP from the command line. The steps are the same as for building the CGI version, except you have to select the php4ts_cli - Win32 Debug_TS or php4ts_cli - Win32 Release_TS project file. After a successful compiling run you will find the php.exe in either the directory Release_TS\cli\ or Debug_TS\cli\.

Nota: If you want to use PEAR and the comfortable command line installer, the CLI-SAPI is mandatory. For more information about PEAR and the installer read the documentation at the PEAR website.

In order to build the SAPI module (php4isapi.dll) for integrating PHP with Microsoft IIS, set your active configuration to php4isapi-whatever-config and build the desired dll.


Installation of Windows extensions

After installing PHP and a webserver on Windows, you will probably want to install some extensions for added functionality. You can choose which extensions you would like to load when PHP starts by modifying your php.ini. You can also load a module dynamically in your script using dl().

The DLLs for PHP extensions are prefixed with 'php_' in PHP 4 (and 'php3_' in PHP 3). This prevents confusion between PHP extensions and their supporting libraries.

Nota: In PHP 4.3.1 BCMath, Calendar, COM, Ctype, FTP, MySQL, ODBC, Overload, PCRE, Session, Tokenizer, WDDX, XML and Zlib support is built in. You don't need to load any additional extensions in order to use these functions. See your distributions README.txt or install.txt or this table for a list of built in modules.

The default location PHP searches for extensions is c:\php4\extensions. To change this setting to reflect your setup of PHP edit your php.ini file:

  • You will need to change the extension_dir setting to point to the directory where your extensions lives, or where you have placed your php_*.dll files. Please do not forget the last backslash. For example:

    extension_dir = c:/php/extensions/

  • Enable the extension(s) in php.ini you want to use by uncommenting the extension=php_*.dll lines in php.ini. This is done by deleting the leading ; form the extension you want to load.

    Esempio 3-3. Enable Bzip2 extension for PHP-Windows

    // change the following line from ...
    ;extension=php_bz2.dll
    
    // ... to
    extension=php_bz2.dll

  • Some of the extensions need extra DLLs to work. Couple of them can be found in the distribution package, in the c:\php\dlls\ folder but some, for example Oracle (php_oci8.dll) require DLLs which are not bundled with the distribution package. Copy the bundled DLLs from c:\php\dlls folder to your Windows PATH, safe places are:

    c:\windows\system for Windows 9x/Me
    c:\winnt\system32 for Windows NT/2000
    c:\windows\system32 for Windows XP

    If you have them already installed on your system, overwrite them only if something doesn't work correctly (Before overwriting them, it is a good idea to make a backup of them, or move them to another folder - just in case something goes wrong).

Nota: If you are running a server module version of PHP remember to restart your webserver to reflect your changes to php.ini.

The following table describes some of the extensions available and required additional dlls.

Tabella 3-1. PHP Extensions

ExtensionDescriptionNotes
php_bz2.dllbzip2 compression functionsNone
php_calendar.dllCalendar conversion functionsBuilt in since PHP 4.0.3
php_cpdf.dllClibPDF functionsNone
php_crack.dllCrack functionsNone
php3_crypt.dllCrypt functionsunknown
php_ctype.dllctype family functionsBuilt in since PHP 4.3.0
php_curl.dllCURL, Client URL library functionsRequires: libeay32.dll, ssleay32.dll (bundled)
php_cybercash.dllCybercash payment functionsPHP <= 4.2.0
php_db.dllDBM functionsDeprecated. Use DBA instead (php_dba.dll)
php_dba.dllDBA: DataBase (dbm-style) Abstraction layer functionsNone
php_dbase.dlldBase functionsNone
php3_dbm.dllBerkeley DB2 libraryunknown
php_dbx.dlldbx functions 
php_domxml.dllDOM XML functions PHP <= 4.2.0 requires: libxml2.dll (bundled) PHP >= 4.3.0 requires: iconv.dll (bundled)
php_dotnet.dll.NET functionsPHP <= 4.1.1
php_exif.dllRead EXIF headers from JPEGNone
php_fbsql.dllFrontBase functionsPHP <= 4.2.0
php_fdf.dllFDF: Forms Data Format functions.Requires: fdftk.dll (bundled)
php_filepro.dllfilePro functionsRead-only access
php_ftp.dllFTP functionsBuilt-in since PHP 4.0.3
php_gd.dllGD library image functions Removed in PHP 4.3.2. Also note that truecolor functions are not available in GD1, instead, use php_gd2.dll.
php_gd2.dllGD library image functionsGD2
php_gettext.dllGettext functions PHP <= 4.2.0 requires gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll, iconv.dll (bundled).
php_hyperwave.dllHyperWave functionsNone
php_iconv.dllICONV characterset conversionRequires: iconv-1.3.dll (bundled), PHP >=4.2.1 iconv.dll
php_ifx.dllInformix functionsRequires: Informix libraries
php_iisfunc.dllIIS management functionsNone
php_imap.dllIMAP POP3 and NNTP functionsPHP 3: php3_imap4r1.dll
php_ingres.dllIngres II functionsRequires: Ingres II libraries
php_interbase.dllInterBase functionsRequires: gds32.dll (bundled)
php_java.dllJava functionsPHP <= 4.0.6 requires: jvm.dll (bundled)
php_ldap.dllLDAP functions PHP <= 4.2.0 requires libsasl.dll (bundled), PHP >= 4.3.0 requires libeay32.dll, ssleay32.dll (bundled)
php_mbstring.dllMulti-Byte String functionsNone
php_mcrypt.dllMcrypt Encryption functionsRequires: libmcrypt.dll
php_mhash.dllMhash functionsPHP >= 4.3.0 requires: libmhash.dll (bundled)
php_mime_magic.dllMimetype functionsRequires: magic.mime (bundled)
php_ming.dllMing functions for FlashNone
php_msql.dllmSQL functionsRequires: msql.dll (bundled)
php3_msql1.dllmSQL 1 clientunknown
php3_msql2.dllmSQL 2 clientunknown
php_mssql.dllMSSQL functionsRequires: ntwdblib.dll (bundled)
php3_mysql.dllMySQL functionsBuilt-in in PHP 4
php3_nsmail.dllNetscape mail functionsunknown
php3_oci73.dllOracle functionsunknown
php_oci8.dllOracle 8 functionsRequires: Oracle 8.1+ client libraries
php_openssl.dllOpenSSL functionsRequires: libeay32.dll (bundled)
php_oracle.dllOracle functionsRequires: Oracle 7 client libraries
php_overload.dllObject overloading functionsBuilt in since PHP 4.3.0
php_pdf.dllPDF functionsNone
php_pgsql.dllPostgreSQL functionsNone
php_printer.dllPrinter functionsNone
php_shmop.dllShared Memory functionsNone
php_snmp.dllSNMP get and walk functionsNT only!
php_sockets.dllSocket functionsNone
php_sybase_ct.dllSybase functionsRequires: Sybase client libraries
php_tokenizer.dllTokenizer functionsBuilt in since PHP 4.3.0
php_w32api.dllW32api functionsNone
php_xmlrpc.dllXML-RPC functionsPHP >= 4.2.1 requires: iconv.dll (bundled)
php_xslt.dllXSLT functions PHP <= 4.2.0 requires sablot.dll, expat.dll (bundled). PHP >= 4.2.1 requires sablot.dll, expat.dll, iconv.dll (bundled).
php_yaz.dllYAZ functionsRequires: yaz.dll (bundled)
php_zip.dllZip File functionsRead only access
php_zlib.dllZLib compression functionsBuilt in since PHP 4.3.0


Servers-CGI/linea di comando

Per default il PHP viene compilato come programma CGI. Ciò crea un interprete di linea di comando che può essere utilizzato sia per elaborazioni CGI sia per script non connessi con il web. Se si utilizza un server web il PHP ha dei moduli atti allo scopo, questa dovrebbe essere la soluzione preferenziale per ragioni di performance. Tuttavia la versione CGI permette agli utenti di Apache di eseguire pagine PHP sotto differenti user id. Se si desidera utilizzare il PHP come CGI è opportuno leggere con attenzione il capitolo Security chapter

Dalla versione 4.3.0 di PHP sono state inserite nuove caratteristiche. Una nuova SAPI, chiamata CLI, è stata aggiunta è ha lo stesso nome dell'eseguibile CGI. Che cosa si installa nella directory {PREFIX}/bin/php dipende dalla line di configurazione, ciò è descritto dettagliatamente nel capitolo Uso del PHP da linea di comando . Per maggiori dettagli leggere quel capitolo del manuale.


Testing

Se si ha compilato il PHP come programma CGI, si può testare l'eseguibile eseguendo make test. E' sempre una buona norma testare l'eseguibile che si è appena compilato. In questo modo si possono intercettare immediatamente eventuali problemi relativi alla piattaforma e non impazzire in una fase successiva.


Benchmarking

Se si compila il PHP 3 come programma CGI, si possono eseguire dei banchmark digitando make bench. Occorre notare che se si è abilitato il safe mode il benchmark non è in grado di concludersi correttamente se richiede più di 30 secondi. Questo perchè la funzione safe mode non può utilizzare la funzione set_time_limit(). Utilizzare il parametro max_execution_time per impostare il tempo massimo di esecuzione di uno script. Il comando make bench ignora il file di configurazione.

Nota: make bench è soltanto disponibile per PHP 3.


Utilizzo delle variabili

Alcuni server passano delle variabili d'ambiente che non sono definite nelle specifiche CGI/1.1. Soltanto le seguenti variabili sono standard, tutte le altre sono da considerarsi come estensioni del fornitore: AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE, GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING, REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD, SCRIPT_NAME, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL e SERVER_SOFTWARE


Server-Apache

Questa sezione contiene note e suggerimenti specifici dell'installazione di PHP con server Apache, sia per le versioni Unix sia per le versioni Windows. Esiste, inoltre, una pagina separata per le istruzioni e note su Apache 2.


Dettagli sull'installazione di PHP con Apache su Unix

Si possono selezionare gli argomenti da aggiungere al comando configure di linea 10 dalla Lista completa delle opzioni di configurazione. In queste note viene omesso il numero di versione per evitare di avere istruzioni non corrette. Nella realtà occorre sostituire 'xxx' con i valori di versione corretti.

Esempio 3-4. Istruzioni per l'installazione (versione di Apache con modulo condiviso) di PHP 4.

1.  gunzip apache_xxx.tar.gz
2.  tar -xvf apache_xxx.tar
3.  gunzip php-xxx.tar.gz
4.  tar -xvf php-xxx.tar
5.  cd apache_xxx
6.  ./configure --prefix=/www --enable-module=so
7.  make
8.  make install
9.  cd ../php-xxx
10. Ora configuriamo il PHP. In questa fase si personalizza il PHP
    agendo sulle varie opzioni, tipo quali estensioni abilitare, Eseguire
    ./configure --help per avere una lista delle opzioni disponibili. Nell'esempio seguente si illustra 
    una semplice configurazione per il supporto di Apache 1 e MySQL. Il percorso a
    apxs nella vostra installazione può differire rispetto all'esempio.

    ./configure --with-mysql --with-apxs=/www/bin/apxs
10. ./configure --with-mysql --with-apxs=/www/bin/apxs
11. make
12. make install

  Se si decide di cambiare le opzioni di configurazione dopo l'installazione
  occorre ripere gli ultimi tre passi. Per attivare il nuovo modulo occorre
  riavviare Apache. Non è richiesta la ricompila di Apache.

  Nota: a meno di non avere dato indicazioni differenti, 'make install' installa anche PEAR,
  vari tools PHP tipo phpize e PHP CLI.

13. Configurazione del php.ini:
 
   cp php.ini-dist /usr/local/lib/php.ini

  Si può modificare il file .ini per impostare le opzioni di PHP.
  Se si desidera avere questo file in un'altra directory, utilizzare
  --with-config-file-path=/percorso al punto 10.

  Se si preferisce utilizzare php.ini-recommended, verificare l'elenco delle differenze rispetto 
  al php.ini e come queste influiscano sul comportamento del PHP.

14.  Modificare httpd.conf per caricare il modulo PHP.
     Il percorso nel lato destro dell'struzione LoadModule deve puntare  al percorso
     del modulo PHP nel sistema. Make install potrebbe averlo già aggiunto, 
     verificare per sicurezza.
  
     Con PHP 4:
       LoadModule php4_module libexec/libphp4.so

     Con PHP 45
       LoadModule php5_module libexec/libphp5.so

15. Nella sezione AddModule di httpd.conf, aggiungere sotto
    ClearModuleList:

    For PHP 4:  
      AddModule mod_php4.c
 
    For PHP 5: 
       AddModule mod_php5.c

16. Indicare ad Apache to considerare alcune estensioni tipo PHP.
    Si possono avere più estensioni interpretate come PHP aggiungendole alla riga usando 
    uno spazio tra una estensione e l'altra. Nell'esempio si aggiungerà l'estensione
    .phtml

        AddType application/x-httpd-php .php .phtml

    E' comune, inoltre, aggiungere l'estensione phps per visualizzare
    il codice PHP colorato. Ciò può essere fatto con:

        AddType application/x-httpd-php-source .phps

17. Utilizzare le normali procedure per avviare il server Apache. (Occorre
    riavviare il server, e non forzare una ricarica tramite i segnali
    HUP o USR1.)

In base all'installazione di Apache e al tipo di Unix, esistono vari modi per fermare e avviare il server. Di seguito saranno illustrati alcuni metodi tipici per riavviare il server in differenti configurazioni di Apache/unix. Si deve sostituire /path/to/ con il percorso in cui risiedono queste applicazioni nel sistema.

Esempio 3-5. Esempio della sequenza di comandi per riavviare Apache

1. Diverse varianti di Linux e SysV:
/etc/rc.d/init.d/httpd restart

2. Utilizzando apachectl:
/path/to/apachectl stop
/path/to/apachectl start

3. httpdctl e httpsdctl (tramite OpenSSL), simile a apachectl:
/path/to/httpsdctl stop
/path/to/httpsdctl start

4. Usando mod_ssl, o un'altro server SSL, si può fermare e riavviare
   il server manualmente:
/path/to/apachectl stop
/path/to/apachectl startssl

La directory degli eseguibili apachectl e http(s)dctl spesso varia. Se nel sistema esistono i comandi locate oppure whereis oppure which, si possono utilizzare per localizzare i programmi di controllo del server.

Di seguito saranno illustrati differenti esempi di compila di PHP per Apache:

./configure --with-apxs --with-pgsql

Questo crea la libreria condivisa libphp4.so che è il modulo caricato da Apache tramite la linea LoadModule del file httpd.conf. Il supporto a PostgreSQL è compreso nella libreria libphp4.so.

./configure --with-apxs --with-pgsql=shared

Questo crea la libreria condivisa libphp4.so per Apache, ma crea anche una libreria condivisa pgsql.so che viene caricata in PHP o tramite le direttive del php.ini o caricata direttamente dallo script tramite la funzione dl().

./configure --with-apache=/path/to/apache_source --with-pgsql

Questo crea una libreria libmodphp4.a, un file mod_php4.c e altri file di contorno e li copia nella directory src/modules/php4 nell'albero dei sorgenti di Apache. Quindi si può compilare Apache utilizzando --activate-module=src/modules/php4/libphp4.a e quindi il sistema di compila di Apache creerà il file libphp4.a e lo includerà staticamente nell'eseguibile httpd. Il supporto per PostgreSQL verrà incluso direttamente in questo httpd, pertanto si avrà un unico eseguibile httpd comprendente tutto Apache e tutto il PHP.

./configure --with-apache=/path/to/apache_source --with-pgsql=shared

Come l'istruzione precedente, tranne che invece di includere PostgreSQL direttamente nel file finale httpd, si avrà una libreria condivisa pgsql.so che può essere caricata in PHP o tramite le direttive del php.ini o direttamente dallo script tramite la funzione dl().

Quando si compila il PHP nei differenti modi, si dovrebbe considerare i vantaggi e gli svantaggi di ciascun metodo. Compilarlo come libreria condivisa permette di compilare Apache separatamente, e quindi non si ha la necessità di ricompilarlo ogni volta che si desideri cambiare il PHP. Compilare il PHP all'interno di Apache (in modo statico) permette al PHP di essere caricato ed eseguito più velocemente. Per maggiori dettagli vedere la pagian di Apache sul supporto DSO.

Nota: Attaulmente il file httpd.conf fornito di default contiene una sezione come la seguente:

User nobody
Group "#-1"

A meno che non venga cambiata in "Group nogroup" o qualcosa di simile (è anche comune l'uso di "Group daemon") il PHP non sarà in grado di aprire i file.

Nota: Accertarsi di avere specificato la versione di apxs installate quando si usa --with-apxs=/path/to/apxs. NON usare la versione di apxs presente nei sorgenti di Apache, ma quella installata nel sistema.


Installazione di PHP su Windows con Apache 1.3.x

Esistono due metodi per installare PHP e Apache 1.3.x in Windows. Uno consiste nell'utilizzare l'eseguibile CGI (php.exe), la seconda consiste nell'usare il modulo DLL per Apache. In entrambi i casi occorre fermare il server Apache, editare il file httpd.conf per indicare ad Apache di utilizzare PHP.

Occorre notare che ora il modulo SAPI sotto Windows è stato reso molto più stabile, noi raccomandiamo l'uso di questo piuttosto che l'eseguibile CGI poichè è molto più trasparente e sicuro.

Sebbene vi possano essere alcune varianti nella configurazione di PHP con Apache, queste sono abbastanza semplici da essere utilizzate dai neofiti. Consultare la documentazione di Apache per maggiori dettagli sulle direttive di configurazione.

Se si decomprime il pacchetto PHP nella directory c:\php\ come descritto nella sezione Passi per l'installazione manuale, occorre inserire queste linee nella configurazione di Apache per attivare l'eseguibile CGI:

  • ScriptAlias /php/ "c:/php/"

  • AddType application/x-httpd-php .php .phtml

  • Action application/x-httpd-php "/php/php.exe"

Occorre rilevare che la seconda riga può essere presente nelle nuove versioni di httpd.conf, ma è commentata. Ricordarsi, inoltre, di sostituire c:/php/ con la corretta directory del PHP.

Avvertimento

Utilizzando la configurazione CGI, il server è aperto a possibili attacchi. Leggere il capitolo CGI security per imparare a difendersi da questi attacchi.

Se si desidera utilizzare PHP come modulo di Apache, occorre copiare php4ts.dll nella directory windows/system (per Windows 9x/Me), winnt/system32 (per Windows NT/2000) o windows/system32 (per Windows XP) sostituendo ogni vecchio file. Quindi si deve aggiungere le seguenti linee al file httpd.conf

  • Aprire httpd.conf con l'editor preferito e localizzare la direttiva LoadModule e aggiungere la seguente linea alla fine dell'elenco: LoadModule php4_module c:/php/sapi/php4apache.dll, oppure per il PHP 5 LoadModule php5_module "c:/php/sapi/php5apache.dll".

  • Si può rilevare che, dopo l'uso dell'installatore di Apache, occorre definire la direttiva AddModule per mod_php4.c. Questa è particolarmente importante se viene definita la direttiva ClearModuleList, che può essere trovata più sotto di qualche riga. Quando si troverà l'elenco delle istruzioni AddModule, aggiungere la seguente linea alla fine dell'elenco: AddModule mod_php4.c Per il PHP 5 utilizzare: AddModule mod_php5.c

  • Cercare una frase simile a # AddType allows you to tweak mime.types. Si troverà alcune righe tipo AddType, aggiungere la seguente linea alla fine dell'elenco: AddType application/x-httpd-php .php. Si può scegliere qualsiasi estensione si desideri elaborare tramite PHP. Da parte nostra suggeriamo .php. Si può anche includere .html e .php3 per avere compatibilità con il passato.

Dopo avere cambiato il file di configurazione, ricordarsi di riavviare il server, ad esempio, NET STOP APACHE seguito da NET START APACHE, se si esegue Apache come servizio di Windows, oppure utilizzare le opportune icone.

Esistono due metodi per attivare la funzionalità di visualizzazione del sorgente; tuttavia il loro funzionamento dipende dall'installazione. Se si ha configurato Apache per utilizzare PHP come modulo SAPI, allora aggiungendo la seguente linea al file httpd.conf (nello stesso punto in cui si è inserito AddType application/x-httpd-php .php) si può attivare questa caratteristica: AddType application/x-httpd-php-source .phps.

Se si è scelto di configurare Apache per utilizzare PHP come eseguibile CGI, allora occorre utilizzare la funzione show_source(). Per ottenere ciò creare uno script PHP e aggiungere questa riga: <?php show_source ("original_php_script.php"); ?>. Sostituire original_php_script.php con il nome del file di cui si vuole vedere il sorgente.

Nota: Nella versione Windows di Apache tutti i backslash nelle righe con percorsi tipo "c:\directory\file.ext", devono essere sostituiti con lo slash, tipo "c:/directory/file.ext".


Server-Apache 2.0

Questa sezione contiene note e suggerimenti specifici per l'installazione di PHP, con Apache 2.0, sia per sistemi Unix sia per sistemi Windows.

Avvertimento

Non utilizzare Apache 2.0 e PHP in ambienti di produzione sia con Unix sia con Windows.

Riteniamo sia opportuno dare uno sguardo alla Documentazione di Apache per avere le nozioni di base per comprendere Apache 2.0.


Note di compatibilità tra PHP e Apache 2.0

Se seguente versioni di PHP funzionano correttamente con le ultime versioni di Apache 2.0:

Queste versioni di PHP sono compatibili con Apache 2.0.40 e successive.

Nota: Il supporto tramite SAPI ad Apache 2.0 è cominciato da 4.2.0. PHP 4.2.3 funziona con Apache 2.0.39, non utilizzare nessuna altra versione di Apache con PHP 4.2.3. Tuttavia si raccomanda di utilizzare il PHP 4.3.0, o successivo, con la più recente versione di Apache2.

Tutte le versioni di PHP menzionate, lavorano con Apache 1.3.x.


PHP e Apache 2 su Linux

Scaricare la più recente versione di Apache 2.0 e la versione di PHP dai siti menzionati in precendenza. Questa guida rapida copre soltanto le basi per partire con Apache 2.0 e PHP. Per maggiori dettagli leggere la documentazione di Apache. In questo esempio è stata omesso il numero di versione per evitare problemi nelle istruzioni presentate. Nell'installazione reale occorre sostituire 'NN' con il corretto numero della versione installata.

Esempio 3-6. Istruzioni per l'installazione (Apache 2 con modulo condiviso)

1.  gzip -d httpd-2_0_NN.tar.gz
2.  tar xvf httpd-2_0_NN.tar
3.  gunzip php-NN.tar.gz
4.  tar -xvf php-NN.tar
5.  cd httpd-2_0_NN
6.  ./configure --enable-so
7.  make
8.  make install

    A questo punto si ha Apache 2.0 disponibile in /usr/local/apache2,
    configurato con il supporto dei moduli caricabili.
    Per testare l'installazione utilizzare la solita procedura per attivare il
    server Apache, es.:
    /usr/local/apache2/bin/apachectl start
    e quindi fermare il server per attivare la configurazione con PHP:
    /usr/local/apache2/bin/apachectl stop.

9.  cd ../php4-NN
10. ./configure --with-apxs2=/usr/local/apache2/bin/apxs
11. make
12. make install
13. cp php.ini-dist /usr/local/lib/php.ini

    Modificare il php.ini per impostare le opzioni di PHP.
    Se si desidera pozionare questo file in altra directory, utilizzare
    --with-config-file-path=/path al passo 10.

14. Modificare httpd.conf e verificare la presenza delle seguenti
    linee:
  
   LoadModule php4_module modules/libphp4.so
   AddType application/x-httpd-php .php

  Si può segliere qualsiasi estensione di desideri. Il nostro suggerimento
  è di utilizzare .php.

  Il percorso indicato nel lato destro della riga LoadModule deve puntare 
  al percorso in cui si trova il modulo PHP. L'esempio illustrato è coerente
  con i parametri sin qui impostati. 

15. Utilizzare la solita procedura per avviare Apache, es.:
   /usr/local/apache2/bin/apachectl start

Seguendo i passi illustrati si ottiene un server Apache 2.0 funzionante con il supporto PHP come modulo SAPI. Ovviamente esistono molte altre opzioni di configurazione sia per Apache sia per PHP. Per maggiori dettagli utilizzare ./configure --help nei sorgenti di ciascun prodotto. Nel caso si desideri compilare la versione multithread di Apache 2.0 occorre sovrascrivere il modulo MPM standard prefork con worker o con perchild. Per ottenere ciò accodare alla linea di configurazione indicata nel passo 6 l'opzione --with-mpm=worker o --with-mpm=perchild. Occorre essere consapevoli delle conseguenze di ciò che si sta facendo. Per maggiori dettagli leggere la documenatzione di Apache sul modulo MPM.

Nota: Per potere compilare la versione multithread di Apache occorre che il sistema supporti i thread. Questo implica la compila di PHP con il modulo sperimentale Zend Thread Safety (ZTS). Pertanto non tutte le estensioni potranno essere disponibili. Si raccomanda, quindi, di compilare Apache con il modulo MPM standard prefork.


PHP e Apache 2.0 su Windows

Si consideri di leggere le note specifiche per Windows di Apache 2.0.

Avvertimento

Apache 2.0 è concepito per essere eseguito su Windows NT 4.0, Windows 2000 oppure Windows XP. In questo momento il supporto per Windows 9x è incompleto. Al momento non ci si aspetta che Apache 2.0 funzioni su quest'ultime piattaforme.

Scaricare la più recente versione di Apache 2.0 e la versione di PHP dai siti menzionati in precendenza. Seguire i passi per l'installazione manuale e tornare a questo pagina per integrare il PHP con Apache.

Esistono due metodi per configurare PHP e Apache 2.0 su Windows. Uno consiste nell'uso dell'eseguibile CGI, l'altro consiste nell'utilizzo del modulo DLL per Apache. In entrambi i casi occorre fermare Apache, modificare il file httpd.conf per configurare Apache.

Occorre inserire queste tre linee nel file di configurazione httpd.conf di Apache per impostare l'eseguibile CGI:

Esempio 3-7. PHP con Apache 2.0 come CGI

ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php.exe"

Se si desidera utilizzare il PHP come modulo di Apache 2.0, occorre copiare php4ts.dll nella directory winnt/system32 (per Windows NT/2000) o windows/system32 (per Windows XP), sovrascrivendo gli eventuali vecchi file. Quindi occorre inserire queste due righe nel file di configurazione di Apache httpd.conf per impostare il modulo PHP

Esempio 3-8. PHP su Apache 2.0 come Modulo

LoadModule php4_module "c:/php/sapi/php4apache2.dll"
AddType application/x-httpd-php .php

Nota: Nei precedenti esempi ricordarsi di sostituire c:/php/ con il percorso alPHP. Prestare attenzione di avere impostato php4apache2.dll nella direttiva LoadModule e nonphp4apche.dll. Quest'ultimo è utilizzato per Apache 1.3.x.

Avvertimento

Non mischiare i file dll da differenti versioni di PHP. Si ha solo la possibilità di utilizzare le dll e le estensioni fornite con la versione scaricata.


Server-Caudium

Il PHP 4 può essere compilato come module Pike per il server web Caudium. Attenzione: non è supportato dal Php 3. Seguire le seguenti istruzioni per installare il PHP 4 con Caudium.

Esempio 3-9. Istruzioni di installazione per Caudium

1.  Essere certi di avere installato Caudium prima di installare
    il PHP 4. Il Php per potere funzionare ha bisogno di Pike
    versione  7.0.268 o successive. Per praticità di illustrazione
    in questo esempio assumeremo che Caudium sia installato in
    /opt/caudium/server/.
2.  Posizionarsi nella directory php-x.y.z (dove x.y.z è il numero di versione).
3.  ./configure --with-caudium=/opt/caudium/server
4.  make
5.  make install
6.  Riavviare Caudium se è attivo.
7.  Entrare nell'interfaccia grafica di configurazione e andare 
    nella sezione virtual server da dove si inserirà il PHP.
8.  Cliccare su Add Module localizzare e aggiungere il modulo PHP 4 Script Suppor.
9.  Se la documentazione informa che 'PHP 4 interpreter isn't
    available', verificare di avere riavviato il server. Se lo si è
    fatto, cercare nel file /opt/caudium/logs/debug/default.1
    la presenza di errori collegati a <filename>PHP4.so</filename>.
    Verificare anche la presenza del file 
    <filename>caudium/server/lib/[pike-version]/PHP4.so</filename>.
10. Configurare il modulo PHP Script Support se necessario..

Si può compilare il modulo per Caudium con il supporto dei vari moduli disponibili per PHP 4, Vedere la lista completa delle opzioni di configurazione options per maggiori informazioni.

Nota: Quando si compila il PHP con il supporto a MySQL occorre essere certi di utilizzare il normale client di MySQL. Altrimenti si possono verificare del conflitti se Pike supporta MySQL. Per fare ciò occorre specificare la directory di installazione di MySQL nell'opzione --with-mysql.


Servers-fhttpd

Per compilare il PHP come modulo fhttpd, rispondere "yes" alla domanda "Build as an fhttpd module?" (l'opzione di configurazione --with-fhttpd=DIR) e specificare la directory base dei sorgenti di fhttpd. Per default la directory è /usr/local/src/fhttpd. Se si usa fhttpd, compilare il PHP come modulo da la possibilità di avere prestazioni migliori e la capacità dell'esecuzione remota.

Nota: Il supporto per fhttpd non è più disponibile a partire da PHP 4.3.0.


Server IIS/PWS

Questa sezione contiene note e suggerimenti specifici per IIS (Microsoft Internet Information Server). Installare il PHP su PWS/IIS 3, PWS 4 o recenti e IIS 4 o recenti.

Importante per utenti CGI: Leggere la faq su cgi.force_redirect per dettagli importanti. Questa direttiva deve essere impostata a 0.


Windows e PWS/IIS 3

Il metodo raccomandato per l'installazione con questi server è di utilizzare il file REG incluso con la distribuzione (pws-php4cgi.reg). Può essere necessario modificare questo file per adeguarlo alle estensioni usate e alle directory in cui è installato il PHP-. Oppure si può seguire i seguenti passi per farlo manualmente.

Avvertimento

Queste istruzioni richiedono di lavorare direttamente sul registry di Windows. Un errore potrebbe lasciare il sistema in uno stato instabile. Si raccomanda di fare una copia di backup del registry prima di cominciare. Il gruppo di sviluppo di PHP non è responsabile se si danneggia il registry.

  • Eseguire Regedit.

  • Posizionarsi in: HKEY_LOCAL_MACHINE /System /CurrentControlSet /Services /W3Svc /Parameters /ScriptMap.

  • Nel menu modifica selezionare: Nuovo->Stringa (New->String Value).

  • Digitare l'estensione che si desidera utilizzare per gli script PHP, Ad esempio .php.

  • Fare un doppio click su 'nuovo valore stringa' e inserire il percorso a php.exe nel campo valore. es.: c:\php\php.exe.

  • Ripetere questi passi per ciascuna estensione si desideri associare agli script PHP.

I seguenti passi non influiscono sull'installazione del server web e si applicano solo se si desidera che gli script php vengano eseguiti quando sono lanciati da linea di comando (es. run c:\myscripts\test.php) o da un doppio click sugli stessi da esplora risorse. Si può anche saltare questi passi e optare per caricare i file PHP in un editor quando si fa un doppio click su di essi.

  • Posizionarsi in: HKEY_CLASSES_ROOT

  • Nel menu modifica selezionare: nuovo->chiave (New->Key).

  • Dare come nome della chiave l'estensione che si desidera configurare es: .php.

  • Evidenziare la nuova chiave e nel pannello di destra, fare un doppio click su "default value" e inserire phpfile.

  • Ripetere il passo precedente per ogni estensione che si desidera inserire.

  • Ora crea un'altra chiave Nuovo->Chiave (New->Key) sotto HKEY_CLASSES_ROOT e chiamarla phpfile.

  • Evidenziare la nuova chiave phpfile e nel pannello di destra fare un doppio click su "default value" ed inserire PHP Script.

  • Click destro sulla chiave phpfile e selezionare Nuovo->Chiave(New->Key), chiamarla Shell.

  • Click destro sulla chiave Shell e selezionare Nuovo->Chiave(New->Key), chiamarla open.

  • Click destro sulla chiave open e selezionare Nuovo->Chiave(New->Key), chiamarla command.

  • Evidenziare la nuova chiave command e nel pannello di destra fare un doppio click su "default value" ed inserire il percorso a php.exe. es: c:\php\php.exe -q %1. (non dimenticarsi del %1).

  • Uscire da Regedit.

  • Se si usa PWS con Windows, riavviare il PC.

A questo punto gli utenti di PWS ed IIS 3 hanno il sistema operante. Gli utenti di IIS3 possono utilizzare un tool di Steven Genusa per configurare la mappatura degli script.


Windows con PWS 4 e successivi

Quando si installa il PHP su sistemi Windows con PWS 4 o versioni successive, si ha due opzioni. Una consiste nell'impostare il PHP come CGI, l'altra consiste nell'usare il modulo ISAPI.

Se si sceglie la soluzione CGI, eseguire i seguenti passi:

  • Modificare il file pws-php4cgi.reg (vedere nella directory SAPI) per inserire il percorso di php.exe. I backslash devono essere preceduti dal carattere di escape '\' ad esempio: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map] ".php"="c:\\php\\php.exe" Ora inserire questo file di registro nel sistema; dovrebbe bastare un doppio click sul file.

  • Nel PWS Manager, click destro nella direttory a cui si vuole aggiungere il supporto PHP e selezionare Proprietà (Properties). Spuntare il checkbox 'Execute' e confermare.

Se si opta per il modulo ISAPI, questi sono i passi:

  • Modificare il file pws-php4cgi.reg (vedere nella directory SAPI) per inserire il percorso di php4isapi.dll. I backslash devono essere preceduti dal carattere di escape '\' ad esempio: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map] ".php"="c:\\php\\sapi\\php4isapi.dll" Ora inserire questo file di registro nel sistema; dovrebbe bastare un doppio click sul file.

  • Nel PWS Manager, click destro nella direttory a cui si vuole aggiungere il supporto PHP e selezionare Proprietà (Properties). Spuntare il checkbox 'Execute' e confermare.


Windows NT/2000/XP con IIS 4 o successivi

Seguire queste istruzioni per installare il PHP su sistemi NT/2000/XP con IIS 4 o successivi. Si hanno a disposizione due opzioni. Una consiste nell'impostare il PHP come CGI, l'altra consiste nell'usare il modulo ISAPI.

In emtranbi i casi occorre avviare la Microsoft Management Console (può essere presente come 'Internet Services Manager', sia nel Windows NT 4.0 Option Pack o nel Pannello di controllo (Control Panel)=>Administrative Tools sotto Windows 2000/XP). Quindi click destro sul nodo Web server (questo molto probabilmente comparirà come 'Default Web Server'), e selezionare 'Proprietà' ('Properties').

Se si desidera installare il PHP come CGI seguire i seguenti passi:

  • Sotto 'Home Directory', 'Virtual Directory', o 'Directory', cliccare sul bottone 'Configuration', ed entrare in App Mappings.

  • Premere Add, e nel box Executable digitare. c:\php\php.exe (assumendo che il PHP si trovi in c:\php\).

  • Nel box Extension, digitare l'estensione dei file che si vuole associare come script PHP. Lasciare bianco 'Method exclusions' e selezionare il checkbox Script engine. Si potrebbe anche selezionare il box 'check that file exists', con una ridotta penalizzazione nella velocità, IIS (o PWS) controlleranno che lo script esista ed eseguiranno l'autentificazione prima di lanciare il PHP. Questo significa avere più errori di tipo 404 piuttosto che avere degli errori CGI dovuti al fatto che il PHP non ha dato in output alcun dato.

    Occorre eseguire il passo precedente per ogni estensione che si desideri associare al PHP. .php and .phtml sono le più comuni, anche .php3 può essere richiesta per compatibilità verso il passato.

  • Impostare le opzioni di sicurezza. (Può essere fatto dal Internet Service Manager), e se il server utilizza come file system NTFS, aggiungere i diritti di esecuzione per I_USR alla directory che contiene il php.exe.

Per impostare il modulo ISAPI occorre:

  • Se non si desidera eseguire l'autenticazione HTTP con il PHP, si può (si dovrebbe) saltare questo passo. Nei filtri ISAPI, aggiungere un nuovo filtro. Indicare PHP come nome del filtro, e indicare il percorso di php4isapi.dll.

  • Nella 'Home Directory', cliccare sul bottone 'Configuration'. Aggiungere una nuova riga nel 'Application Mappings'. Indicare il percorso di php4isapi.dll come Executable, dare .php come estensione, lasciare bianco Method exclusions, e selezionare il checkbox Script engine.

  • Fermare completamente IIS (NET STOP iisadmin)

  • Attivare IIS (NET START w3svc)


Servers-Netscape, iPlanet and SunONE

This section contains notes and hints specific to Netscape, iPlanet and SunONE webserver installs of PHP, both for Sun Solaris and Windows versions.

From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current webservers read the note about subrequests.

You can find more information about setting up PHP for the Netscape Enterprise Server (NES) here: http://benoit.noss.free.fr/php/install-php4.html


Installing PHP with NES/iPlanet/SunONE Webserver on Sun Solaris

To build PHP with NES/iPlanet/SunONE webservers, enter the proper install directory for the --with-nsapi=[DIR] option. The default directory is usually /opt/netscape/suitespot/. Please also read /php-xxx-version/sapi/nsapi/nsapi-readme.txt.

  1. Install the following packages from http://www.sunfreeware.com/ or another download site:

    autoconf-2.13
    automake-1.4
    bison-1_25-sol26-sparc-local
    flex-2_5_4a-sol26-sparc-local
    gcc-2_95_2-sol26-sparc-local
    gzip-1.2.4-sol26-sparc-local
    m4-1_4-sol26-sparc-local
    make-3_76_1-sol26-sparc-local
    mysql-3.23.24-beta (if you want mysql support)
    perl-5_005_03-sol26-sparc-local
    tar-1.13 (GNU tar)

  2. Make sure your path includes the proper directories PATH=.:/usr/local/bin:/usr/sbin:/usr/bin:/usr/ccs/bin and make it available to your system export PATH.

  3. gunzip php-x.x.x.tar.gz (if you have a .gz dist, otherwise go to 4).

  4. tar xvf php-x.x.x.tar

  5. Change to your extracted PHP directory: cd ../php-x.x.x

  6. For the following step, make sure /opt/netscape/suitespot/ is where your netscape server is installed. Otherwise, change to the correct path and run:
    ./configure --with-mysql=/usr/local/mysql \
    --with-nsapi=/opt/netscape/suitespot/ \
    --enable-libgcc

  7. Run make followed by make install.

After performing the base install and reading the appropriate readme file, you may need to perform some additional configuration steps.

Configuration Instructions for NES/iPlanet/SunONE. Firstly you may need to add some paths to the LD_LIBRARY_PATH environment for SunONE to find all the shared libs. This can best done in the start script for your SunONE webserver. Windows users can probably skip this step. The start script is often located in: /path/to/server/https-servername/start. You may also need to edit the configuration files that are located in: /path/to/server/https-servername/config/.

  1. Add the following line to mime.types (you can do that by the administration server):
    type=magnus-internal/x-httpd-php exts=php

  2. Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following, shlib will vary depending on your OS, for Unix it will be something like /opt/netscape/suitespot/bin/libphp4.so. You should place the following lines after mime types init.
    Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="/opt/netscape/suitespot/bin/libphp4.so"
    Init fn="php4_init" LateInit="yes" errorString="Failed to initialize PHP!" [php_ini="/path/to/php.ini"]
    (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your webserver config directory.

  3. Configure the default object in obj.conf (for virtual server classes [SunONE 6.0+] in their vserver.obj.conf):
    <Object name="default">
    .
    .
    .
    .#NOTE this next line should happen after all 'ObjectType' and before all 'AddLog' lines
    Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]
    .
    .
    </Object>
    (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"

  4. This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
    <Object name="x-httpd-php">
    ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
    Service fn=php4_execute [inikey=value inikey=value ...]
    </Object>
    After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.

  5. Setup of authentication: PHP authentication cannot be used with any other authentication. ALL AUTHENTICATION IS PASSED TO YOUR PHP SCRIPT. To configure PHP Authentication for the entire server, add the following line to your default object:
    <Object name="default">
    AuthTrans fn=php4_auth_trans
    .
    .
    .
    </Object>

  6. To use PHP Authentication on a single directory, add the following:
    <Object ppath="d:\path\to\authenticated\dir\*">
    AuthTrans fn=php4_auth_trans
    </Object>

Nota: The stacksize that PHP uses depends on the configuration of the webserver. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").


Installing PHP with NES/iPlanet/SunONE on Windows

To Install PHP as CGI (for Netscape Enterprise Server, iPlanet, SunONE, perhaps Fastrack), do the following:

  • Copy php4ts.dll to your systemroot (the directory where you installed Windows)

  • Make a file association from the command line. Type the following two lines:
    assoc .php=PHPScript
    ftype PHPScript=c:\php\php.exe %1 %*

  • In the Netscape Enterprise Administration Server create a dummy shellcgi directory and remove it just after (this step creates 5 important lines in obj.conf and allow the web server to handle shellcgi scripts).

  • In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/shellcgi, File Suffix:php).

  • Do it for each web server instance you want PHP to run

More details about setting up PHP as a CGI executable can be found here: http://benoit.noss.free.fr/php/install-php.html

To Install PHP as NSAPI (for Netscape Enterprise Server, iPlanet, SunONE, perhaps Fastrack), do the following:

  • Copy php4ts.dll to your systemroot (the directory where you installed Windows)

  • Make a file association from the command line. Type the following two lines:
    assoc .php=PHPScript
    ftype PHPScript=c:\php\php.exe %1 %*

  • In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/x-httpd-php, File Suffix: php).

  • Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following: You should place the lines after mime types init.
    Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="c:/php/sapi/php4nsapi.dll"
    Init fn="php4_init" LateInit="yes" errorString="Failed to initialise PHP!" [php_ini="c:/path/to/php.ini"]
    (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your webserver config directory.

  • Configure the default object in obj.conf (for virtual server classes [SunONE 6.0+] in their vserver.obj.conf): In the <Object name="default"> section, place this line necessarily after all 'ObjectType' and before all 'AddLog' lines:
    Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]
    (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On"

  • This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory):
    <Object name="x-httpd-php">
    ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
    Service fn=php4_execute [inikey=value inikey=value ...]
    </Object>
    After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html.

  • Restart your web service and apply changes

  • Do it for each web server instance you want PHP to run

Nota: More details about setting up PHP as an NSAPI filter can be found here: http://benoit.noss.free.fr/php/install-php4.html

Nota: The stacksize that PHP uses depends on the configuration of the webserver. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR").


CGI environment and recommended modifications in php.ini

Important when writing PHP scripts is the fact that iPlanet/SunONE/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the webserver itsself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP 3.x way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running webserver without any valid CGI variables!

Nota: Why are there (invalid) CGI variables in the environment?

Answer: This is because you started the webserver process from the admin server which runs the startup script of the webserver, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started webserver has some CGI environment variables in it. You can test this by starting the webserver not from the administration server. Use the Unix command line as root user and start it manually - you will see there are no CGI-like environment variables.

Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST,..., you should turn on register_globals in php.ini and change the variable order to (important: remove "E" from it, because you do not need the environment here):
variables_order = "GPCS"
register_globals = On


Special use for error pages or self-made directory listings (PHP >= 4.3.3)

You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite:
Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]
where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE'].

Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following:
Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]
For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED'].


Note about nsapi_virtual() and subrequests (PHP >= 4.3.3)

The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the webserver and insert the result in the webpage. The problem is, that this function uses some undocumented features from the NSAPI library.

Under Unix this is not a problem, because the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled.

Under Windows limitations in the DLL handling need the use of a automatic detection of the most recent ns-httpdXX.dll file. This is tested for servers till version 6.1. If a newer version of the SunONE server is used, the detection fails and nsapi_virtual() is disabled.

If this is the case, try the following: Add the following parameter to php4_init in magnus.conf/obj.conf:
Init fn=php4_init ... server_lib="ns-httpdXX.dll"
where XX is the correct DLL version number. To get it, look in the server-root for the correct DLL name. The DLL with the biggest filesize is the right one.

You can check the status by using the phpinfo() function.

Nota: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!!


Servers-OmniHTTPd Server

This section contains notes and hints specific to OmniHTTPd.


OmniHTTPd 2.0b1 and up for Windows

You need to complete the following steps to make PHP work with OmniHTTPd. This is a CGI executable setup. SAPI is supported by OmniHTTPd, but some tests have shown that it is not so stable to use PHP as an ISAPI module.

Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.

  1. Install OmniHTTPd server.

  2. Right click on the blue OmniHTTPd icon in the system tray and select Properties

  3. Click on Web Server Global Settings

  4. On the 'External' tab, enter: virtual = .php | actual = c:\path-to-php-dir\php.exe, and use the Add button.

  5. On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button.

  6. Click OK

Repeat steps 2 - 6 for each extension you want to associate with PHP.

Nota: Some OmniHTTPd packages come with built in PHP support. You can choose at setup time to do a custom setup, and uncheck the PHP component. We recommend you to use the latest PHP binaries. Some OmniHTTPd servers come with PHP 4 beta distributions, so you should choose not to set up the built in support, but install your own. If the server is already on your machine, use the Replace button in Step 4 and 5 to set the new, correct information.


Servers-Sambar

This section contains notes and hints specific to the Sambar server for Windows.


Sambar Windows

This list describes how to set up the ISAPI module to work with the Sambar server on Windows.

  • Find the file called mappings.ini (in the config directory) in the Sambar install directory.

  • Open mappings.ini and add the following line under [ISAPI]:

    Esempio 3-10. ISAPI configuration of Sambar

    *.php = c:\php\php4isapi.dll
    (This line assumes that PHP was installed in c:\php.)

  • Now restart the Sambar server for the changes to take effect.


Servers-Xitami

This section contains notes and hints specific to Xitami.


Xitami for Windows

This list describes how to set up the PHP CGI binary to work with Xitami on Windows.

Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.

  • Make sure the webserver is running, and point your browser to xitamis admin console (usually http://127.0.0.1/admin), and click on Configuration.

  • Navigate to the Filters, and put the extension which PHP should parse (i.e. .php) into the field File extensions (.xxx).

  • In Filter command or script put the path and name of your PHP executable i.e. c:\php\php.exe.

  • Press the 'Save' icon.

  • Restart the server to reflect changes.


Servers-Other web servers

PHP can be built to support a large number of web servers. Please see Server-related options for a full list of server-related configure options. The PHP CGI binaries are compatible with almost all webservers supporting the CGI standard.


Problems?

Read the FAQ

Some problems are more common than others. The most common ones are listed in the PHP FAQ, part of this manual.


Other problems

If you are still stuck, someone on the PHP installation mailing list may be able to help you. You should check out the archive first, in case someone already answered someone else who had the same problem as you. The archives are available from the support page on http://www.php.net/support.php. To subscribe to the PHP installation mailing list, send an empty mail to php-install-subscribe@lists.php.net. The mailing list address is php-install@lists.php.net.

If you want to get help on the mailing list, please try to be precise and give the necessary details about your environment (which operating system, what PHP version, what web server, if you are running PHP as CGI or a server module, safe mode, etc...), and preferably enough code to make others able to reproduce and test your problem.


Bug reports

If you think you have found a bug in PHP, please report it. The PHP developers probably don't know about it, and unless you report it, chances are it won't be fixed. You can report bugs using the bug-tracking system at http://bugs.php.net/. Please do not send bug reports in mailing list or personal letters. The bug system is also suitable to submit feature requests.

Read the How to report a bug document before submitting any bug reports!


Capitolo 4. Runtime Configuration

The configuration file

The configuration file (called php3.ini in PHP 3, and simply php.ini as of PHP 4) is read when PHP starts up. For the server module versions of PHP, this happens only once when the web server is started. For the CGI and CLI version, it happens on every invocation.

The default location of php.ini is a compile time option (see the FAQ entry), but can be changed for the CGI and CLI version with the -c command line switch, see the chapter about using PHP from the command line. You can also use the environment variable PHPRC for an additional path to search for a php.ini file.

Nota: The Apache web server changes the directory to root at startup causing PHP to attempt to read php.ini from the root filesystem if it exists.

The php.ini directives handled by extensions are documented respectively on the pages of the extensions themselfs. The list of the core directives is available in the appendix. Probably not all the PHP directives are documented in the manual though. For a completel list of directives available in your PHP version, please read your well commented php.ini file. Alternatively, you may find the the latest php.ini from CVS helpful too.

Esempio 4-1. php.ini example

; any text on a line after an unquoted semicolon (;) is ignored
[php] ; section markers (text within square brackets) are also ignored
; Boolean values can be set to either:
;    true, on, yes
; or false, off, no, none
register_globals = off
track_errors = yes

; you can enclose strings in double-quotes
include_path = ".:/usr/local/lib/php"

; backslashes are treated the same as any other character
include_path = ".;c:\php\lib"


How to change configuration settings

Running PHP as an Apache module

When using PHP as an Apache module, you can also change the configuration settings using directives in Apache configuration files (e.g. httpd.conf) and .htaccess files. You will need "AllowOverride Options" or "AllowOverride All" privileges to do so.

With PHP 4 and PHP 5, there are several Apache directives that allow you to change the PHP configuration from within the Apache configuration files. For a listing of which directives are PHP_INI_ALL, PHP_INI_PERDIR, or PHP_INI_SYSTEM, have a look at the table found within the ini_set() documentation.

Nota: With PHP 3, there are Apache directives that correspond to each configuration setting in the php3.ini name, except the name is prefixed by "php3_".

php_value name value

Sets the value of the specified directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives. To clear a previously set value use none as the value.

Nota: Don't use php_value to set boolean values. php_flag (see below) should be used instead.

php_flag name on|off

Used to set a boolean configuration directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives.

php_admin_value name value

Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or virtualhost directives. To clear a previously set value use none as the value.

php_admin_flag name on|off

Used to set a boolean configuration directive. This can not be used in .htaccess files. Any directive type set with php_admin_flag can not be overridden by .htaccess or virtualhost directives.

Esempio 4-2. Apache configuration example

<IfModule mod_php5.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag safe_mode on
</IfModule>
<IfModule mod_php4.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag safe_mode on
</IfModule>
<IfModule mod_php3.c>
  php3_include_path ".:/usr/local/lib/php"
  php3_safe_mode on
</IfModule>

Attenzione

PHP constants do not exist outside of PHP. For example, in httpd.conf you can not use PHP constants such as E_ALL or E_NOTICE to set the error_reporting directive as they will have no meaning and will evaluate to 0. Use the associated bitmask values instead. These constants can be used in php.ini


Changing PHP configuration via the Windows registry

When running PHP on Windows, the configuration values can be modified on a per-directory basis using the Windows registry. The configuration values are stored in the registry key HKLM\SOFTWARE\PHP\Per Directory Values, in the sub-keys corresponding to the path names. For example, configuration values for the directory c:\inetpub\wwwroot would be stored in the key HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot. The settings for the directory would be active for any script running from this directory or any subdirectory of it. The values under the key should have the name of the PHP configuration directive and the string value. PHP constants in the values are not parsed.


Other interfaces to PHP

Regardless of how you run PHP, you can change certain values at runtime of your scripts through ini_set(). See the documentation on the ini_set() page for more information.

If you are interested in a complete list of configuration settings on your system with their current values, you can execute the phpinfo() function, and review the resulting page. You can also access the values of individual configuration directives at runtime using ini_get() or get_cfg_var().


Capitolo 5. Sintassi Fondamentale

Modi per uscire dalla modalità HTML

Quando il PHP inizia a esaminare un file, visualizzerà il contenuto del file sino a quando non incontra uno dei tag speciali indicanti l'inizio del codice da interpretare come istruzioni PHP. A questo punto il parser eseguirà tutto il codice trovato sino a quando non incontrerà i tag di chiusura, che indicano al parser di tornare alla modalità di visualizzazione. Questo meccanismo permette di inserire codice PHP all'interno di codice HTML: tutto ciò che si trova all'esterno dei tag PHP sarà lasciato inalterato, mentre tutto ciò che si trova all'interno sarà eseguito come codice PHP.

Esistono 4 set di tag che possono essere utilizzati per delimitare blocchi di codice PHP. Soltanto due di questi (<?php. . .?> e <script language="php">. . .</script>) sono sempre disponibili; gli altri possono essere attivati o disattivati tramite il file di configurazione php.ini. Sebbene i tag brevi o quelli in stile ASP possano essere pratici, il supporto di questi non è garantito in tutte le versioni. Quindi, se si intende inserire codice PHP all'interno di testi XMl o XHTML, occorre utilizzare <?php. . .?> per essere conformi allo standard XML.  

I tag supportati dal PHP sono:     

Esempio 5-1. Metodi per uscire dalla modalità HTML

1.  <?php echo("se si vogliono produrre documenti XHTML o XML, si utilizzi questo modo\n"); ?>

2.  <? echo ("questo è il più semplice, ovvero come istruzione SGML\n"); ?>
    <?= espressione ?>  Questa è un'abbreviazione per "<? echo espressione ?>"
 
3.  <script language="php">
        echo ("alcuni editor (tipo FrontPage) non 
               amano le istruzioni di elaborazione");
    </script>

4.  <% echo ("Opzionalmente puoi utilizzare tag nello stile ASP"); %>
    <%= $variable; # Questo &egrave; una abbreviazione per "<%echo .." %>

Il primo, <?php. . .?>, è il metodo preferenziale, dato che permette l'utilizzo del PHP all'interno di codice conforme a specifiche XML come XHTML.

Il secondo metodo è disponibile solo se sono stati abilitati i tags abbreviati. Ciò può essere impostato sia utilizzando la funzione short_tags() (solo PHP 3), sia abilitando nel file di configurazione del PHP l'opzione short_open_tag, oppure compilando il PHP utilizzando l'opzione --enable-short-tags nel comando configure. Sebbene siano abilitati nel php.ini-dist riilasciato, l'uso dei tag brevi è vivamente sconsigliato.

Il quarto modo è disponibile solo se sono stati attivati nel file di configurazione i tag in stile ASP tramite l'opzione asp_tags.

Nota: Il supporto per i tag nello stile ASP è stato aggiunto nella versione 3.0.4.

Nota:      L'utilizzo dei tag brevi dovrebbe essere evitato nello sviluppo di applicazioni o librerie destinate alla distribuzione o destinati a server di produzione PHP di cui non si ha il controllo poichè questi tag potrebbero non essere attivi sul server di destinazione. Per avere maggiore portabilità, codice redistribuibile, occorre essere certi di non utilizzare i tag brevi.    

Il tag di chiusura di un blocco include il carattere di 'a capo' immediatamente seguente, se presente. Inoltre, il tag di chiusura viene considerato automaticamente come punto e virgola; pertanto non occorre inserire il punto e virgola alla fine dell'ultima riga del blocco php.      

Il PHP permette strutture tipo le seguenti:

Esempio 5-2. Modi avanzati per uscire dalla modalità HTML

<?php
if ($expression) {
    ?>
    <strong>Questa è vera.</strong>
    <?php
} else {
    ?>
    <strong>Questa è falsa.</strong>
    <?php
}
?>
Questo esempio agisce come atteso, poichè il PHP rileva il tag di chiusura ?>, e da questo punto, inizia a dare in output tutto ciò che trova fino a quando non rileva un'altro tag di apertura. Certamente l'esempio dato è macchinoso, ma per l'output di grossi blocchi di testo, l'uscire dalla modalità di parsing PHP, è generalmente più efficiente piuttosto che inviare il testo tramite ripetute funzioni echo() o print().


Separazione delle istruzioni

Le istruzioni sono separate come nel C o in Perl - ogni istruzione termina con un punto e virgola.

Il tag di chiusura (?>) implica anche la fine di un'istruzione, perciò le seguenti sono equivalenti:

<?php
    echo "Questo &grave; un test";
?>
<?php echo "Questo &grave; un test" ?>


Commenti

Il PHP supporta i commenti dei linguaggi 'C', 'C++' e della shell Unix. Per esempio:

<?php
    echo "Questo &grave; un test"; // Questo &egrave; un commento su una linea nella stile c++ 
    /* Questo &egrave; un commento su pi&ugrave; linee
       ancora un'altra linea di commento */
    echo "Questo &egrave; un altro test";
    echo "Un ultimo test"; # Questo &egrave; un commento stile shell Unix 
?>

Lo stile di commento su "una linea", attualmente commenta solo fino alla fine della linea o del blocco corrente di codice PHP.

<h1>Questo &egrave; un <?# echo "semplice";?> esempio.</h1>
<p>L'intestazione qui sopra dir&agrave; 'Questo &egrave; un esempio'.

Occorre fare attenzione nel non annidare i commenti di stile C, situazione che si presenta quando si commentano larghi blocchi di codice.

<?php
 /* 
    echo "Questo &egrave; un test"; /* Questo commento causer&agrave; dei problemi */
 */
?>

  Lo stile di commento su linea singola commenta il testo fino alla fine della riga oppure alla fine del blocco di codice PHP, dipende da cosa si incontra prima. Questo significa che il codice HTML posizionato dopo // ?> SARA' visualizzato: ?> indica di uscire dal modo PHP e di ritornare in modalità HTML, e, quindi, // non hanno più effetto.     


Capitolo 6. Types

Introduction

PHP supports eight primitive types.

Four scalar types:

Two compound types:

And finally two special types:

This manual also introduces some pseudo-types for readability reasons:

You may also find some references to the type "double". Consider double the same as float, the two names exist only for historic reasons.

The type of a variable is usually not set by the programmer; rather, it is decided at runtime by PHP depending on the context in which that variable is used.

Nota: If you want to check out the type and value of a certain expression, use var_dump().

Nota: If you simply want a human-readable representation of the type for debugging, use gettype(). To check for a certain type, do not use gettype(), but use the is_type functions. Some examples:

<?php
$bool = TRUE;   // a boolean
$str  = "foo";  // a string
$int  = 12;     // an integer

echo gettype($bool); // prints out "boolean"
echo gettype($str);  // prints out "string"

// If this is an integer, increment it by four
if (is_int($int)) {
    $int += 4;
}

// If $bool is a string, print it out
// (does not print out anything)
if (is_string($bool)) {
    echo "String: $bool";
}
?>

If you would like to force a variable to be converted to a certain type, you may either cast the variable or use the settype() function on it.

Note that a variable may be evaluated with different values in certain situations, depending on what type it is at the time. For more information, see the section on Type Juggling. Also, you may be interested in viewing the type comparison tables, as they show examples of various type related comparisons.


Booleans

This is the easiest type. A boolean expresses a truth value. It can be either TRUE or FALSE.

Nota: The boolean type was introduced in PHP 4.


Syntax

To specify a boolean literal, use either the keyword TRUE or FALSE. Both are case-insensitive.

<?php
$foo = True; // assign the value TRUE to $foo
?>

Usually you use some kind of operator which returns a boolean value, and then pass it on to a control structure.

<?php
// == is an operator which test
// equality and returns a boolean
if ($action == "show_version") {
    echo "The version is 1.23";
}

// this is not necessary...
if ($show_separators == TRUE) {
    echo "<hr>\n";
}

// ...because you can simply type
if ($show_separators) {
    echo "<hr>\n";
}
?>


Converting to boolean

To explicitly convert a value to boolean, use either the (bool) or the (boolean) cast. However, in most cases you do not need to use the cast, since a value will be automatically converted if an operator, function or control structure requires a boolean argument.

See also Type Juggling.

When converting to boolean, the following values are considered FALSE:

Every other value is considered TRUE (including any resource).

Avvertimento

-1 is considered TRUE, like any other non-zero (whether negative or positive) number!

<?php
var_dump((bool) "");        // bool(false)
var_dump((bool) 1);         // bool(true)
var_dump((bool) -2);        // bool(true)
var_dump((bool) "foo");     // bool(true)
var_dump((bool) 2.3e5);     // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array());   // bool(false)
var_dump((bool) "false");   // bool(true)
?>


Integers

An integer is a number of the set Z = {..., -2, -1, 0, 1, 2, ...}.

See also: Arbitrary length integer / GMP, Floating point numbers, and Arbitrary precision / BCMath


Syntax

Integers can be specified in decimal (10-based), hexadecimal (16-based) or octal (8-based) notation, optionally preceded by a sign (- or +).

If you use the octal notation, you must precede the number with a 0 (zero), to use hexadecimal notation precede the number with 0x.

Esempio 6-1. Integer literals

<?php
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
?>
Formally the possible structure for integer literals is:

decimal     : [1-9][0-9]*
            | 0

hexadecimal : 0[xX][0-9a-fA-F]+

octal       : 0[0-7]+

integer     : [+-]?decimal
            | [+-]?hexadecimal
            | [+-]?octal

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers.


Integer overflow

If you specify a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, if you perform an operation that results in a number beyond the bounds of the integer type, a float will be returned instead.

<?php
$large_number =  2147483647;
var_dump($large_number);
// output: int(2147483647)

$large_number =  2147483648;
var_dump($large_number);
// output: float(2147483648)

// this goes also for hexadecimal specified integers:
var_dump( 0x80000000 );
// output: float(2147483648)

$million = 1000000;
$large_number =  50000 * $million;
var_dump($large_number);
// output: float(50000000000)
?>

Avvertimento

Unfortunately, there was a bug in PHP so that this does not always work correctly when there are negative numbers involved. For example: when you do -50000 * $million, the result will be -429496728. However, when both operands are positive there is no problem.

This is solved in PHP 4.1.0.

There is no integer division operator in PHP. 1/2 yields the float 0.5. You can cast the value to an integer to always round it downwards, or you can use the round() function.

<?php
var_dump(25/7);         // float(3.5714285714286) 
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7));  // float(4) 
?>


Converting to integer

To explicitly convert a value to integer, use either the (int) or the (integer) cast. However, in most cases you do not need to use the cast, since a value will be automatically converted if an operator, function or control structure requires an integer argument. You can also convert a value to integer with the function intval().

See also type-juggling.


From booleans

FALSE will yield 0 (zero), and TRUE will yield 1 (one).


From floating point numbers

When converting from float to integer, the number will be rounded towards zero.

If the float is beyond the boundaries of integer (usually +/- 2.15e+9 = 2^31), the result is undefined, since the float hasn't got enough precision to give an exact integer result. No warning, not even a notice will be issued in this case!

Avvertimento

Never cast an unknown fraction to integer, as this can sometimes lead to unexpected results.

<?php
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
?>

See for more information the warning about float-precision.


From other types

Attenzione

Behaviour of converting to integer is undefined for other types. Currently, the behaviour is the same as if the value was first converted to boolean. However, do not rely on this behaviour, as it can change without notice.


Floating point numbers

Floating point numbers (AKA "floats", "doubles" or "real numbers") can be specified using any of the following syntaxes:

<?php
$a = 1.234; 
$b = 1.2e3; 
$c = 7E-10;
?>

Formally:

LNUM          [0-9]+
DNUM          ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM ( ({LNUM} | {DNUM}) [eE][+-]? {LNUM})

The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (that's 64 bit IEEE format).

Floating point precision

It is quite usual that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a little loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8 as the result of the internal representation really being something like 7.9999999999....

This is related to the fact that it is impossible to exactly express some fractions in decimal notation with a finite number of digits. For instance, 1/3 in decimal form becomes 0.3333333. . ..

So never trust floating number results to the last digit and never compare floating point numbers for equality. If you really need higher precision, you should use the arbitrary precision math functions or gmp functions instead.


Converting to float

For information on when and how strings are converted to floats, see the section titled String conversion to numbers. For values of other types, the conversion is the same as if the value would have been converted to integer and then to float. See the Converting to integer section for more information.


Strings

A string is series of characters. In PHP, a character is the same as a byte, that is, there are exactly 256 different characters possible. This also implies that PHP has no native support of Unicode. See utf8_encode() and utf8_decode() for some Unicode support.

Nota: It is no problem for a string to become very large. There is no practical bound to the size of strings imposed by PHP, so there is no reason at all to worry about long strings.


Syntax

A string literal can be specified in three different ways.


Single quoted

The easiest way to specify a simple string is to enclose it in single quotes (the character ').

To specify a literal single quote, you will need to escape it with a backslash (\), like in many other languages. If a backslash needs to occur before a single quote or at the end of the string, you need to double it. Note that if you try to escape any other character, the backslash will also be printed! So usually there is no need to escape the backslash itself.

Nota: In PHP 3, a warning will be issued at the E_NOTICE level when this happens.

Nota: Unlike the two other syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.

<?php
echo 'this is a simple string';

echo 'You can also have embedded newlines in 
strings this way as it is
okay to do';

// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>


Double quoted

If the string is enclosed in double-quotes ("), PHP understands more escape sequences for special characters:

Tabella 6-1. Escaped characters

sequencemeaning
\nlinefeed (LF or 0x0A (10) in ASCII)
\rcarriage return (CR or 0x0D (13) in ASCII)
\thorizontal tab (HT or 0x09 (9) in ASCII)
\\backslash
\$dollar sign
\"double-quote
\[0-7]{1,3} the sequence of characters matching the regular expression is a character in octal notation
\x[0-9A-Fa-f]{1,2} the sequence of characters matching the regular expression is a character in hexadecimal notation

Again, if you try to escape any other character, the backslash will be printed too!

But the most important feature of double-quoted strings is the fact that variable names will be expanded. See string parsing for details.


Heredoc

Another way to delimit strings is by using heredoc syntax ("<<<"). One should provide an identifier after <<<, then the string, and then the same identifier to close the quotation.

The closing identifier must begin in the first column of the line. Also, the identifier used must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore.

Avvertimento

It is very important to note that the line with the closing identifier contains no other characters, except possibly a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs after or before the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by your operating system. This is \r on Macintosh for example.

If this rule is broken and the closing identifier is not "clean" then it's not considered to be a closing identifier and PHP will continue looking for one. If in this case a proper closing identifier is not found then a parse error will result with the line number being at the end of the script.

Heredoc text behaves just like a double-quoted string, without the double-quotes. This means that you do not need to escape quotes in your here docs, but you can still use the escape codes listed above. Variables are expanded, but the same care must be taken when expressing complex variables inside a here doc as with strings.

Esempio 6-2. Heredoc string quoting example

<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* More complex example, with variables. */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

Nota: Heredoc support was added in PHP 4.


Variable parsing

When a string is specified in double quotes or with heredoc, variables are parsed within it.

There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient. It provides a way to parse a variable, an array value, or an object property.

The complex syntax was introduced in PHP 4, and can be recognised by the curly braces surrounding the expression.


Simple syntax

If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces if you want to explicitly specify the end of the name.

<?php
$beer = 'Heineken';
echo "$beer's taste is great"; // works, "'" is an invalid character for varnames
echo "He drank some $beers";   // won't work, 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works
echo "He drank some {$beer}s"; // works
?>

Similarly, you can also have an array index or an object property parsed. With array indices, the closing square bracket (]) marks the end of the index. For object properties the same rules apply as to simple variables, though with object properties there doesn't exist a trick like the one with variables.

<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys 
// and do not use {braces} when outside of strings either.

// Let's show all errors
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red', 'banana' => 'yellow');

// Works but note that this works differently outside string-quotes
echo "A banana is $fruits[banana].";

// Works
echo "A banana is {$fruits['banana']}.";

// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";

// Won't work, use braces.  This results in a parse error.
echo "A banana is $fruits['banana'].";

// Works
echo "A banana is " . $fruits['banana'] . ".";

// Works
echo "This square is $square->width meters broad.";

// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>

For anything more complex, you should use the complex syntax.


Complex (curly) syntax

This isn't called complex because the syntax is complex, but because you can include complex expressions this way.

In fact, you can include any value that is in the namespace in strings with this syntax. You simply write the expression the same way as you would outside the string, and then include it in { and }. Since you can't escape '{', this syntax will only be recognised when the $ is immediately following the {. (Use "{\$" or "\{$" to get a literal "{$"). Some examples to make it clear:

<?php
// Let's show all errors
error_reporting(E_ALL);

$great = 'fantastic';

// Won't work, outputs: This is { fantastic}
echo "This is { $great}";

// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";

// Works
echo "This square is {$square->width}00 centimeters broad."; 

// Works
echo "This works: {$arr[4][3]}";

// This is wrong for the same reason as $foo[bar] is wrong 
// outside a string.  In other words, it will still work but
// because PHP first looks for a constant named foo, it will
// throw an error of level E_NOTICE (undefined constant).
echo "This is wrong: {$arr[foo][3]}"; 

// Works.  When using multi-dimensional arrays, always use
// braces around arrays when inside of strings
echo "This works: {$arr['foo'][3]}";

// Works.
echo "This works: " . $arr['foo'][3];

echo "You can even write {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";
?>


String access and modification by character

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string in curly braces.

Nota: For backwards compatibility, you can still use array-brackets for the same purpose. However, this syntax is deprecated as of PHP 4.

Esempio 6-3. Some string examples

<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str{0};

// Get the third character of a string
$third = $str{2};

// Get the last character of a string.
$str = 'This is still a test.';
$last = $str{strlen($str)-1}; 

// Modify the last character of a string
$str = 'Look at the sea';
$str{strlen($str)-1} = 'e';
          
?>


Useful functions and operators

Strings may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will not work for this. Please see String operators for more information.

There are a lot of useful functions for string modification.

See the string functions section for general functions, the regular expression functions for advanced find&replacing (in two tastes: Perl and POSIX extended).

There are also functions for URL-strings, and functions to encrypt/decrypt strings (mcrypt and mhash).

Finally, if you still didn't find what you're looking for, see also the character type functions.


Converting to string

You can convert a value to a string using the (string) cast, or the strval() function. String conversion is automatically done in the scope of an expression for you where a string is needed. This happens when you use the echo() or print() functions, or when you compare a variable value to a string. Reading the manual sections on Types and Type Juggling will make the following clearer. See also settype().

A boolean TRUE value is converted to the string "1", the FALSE value is represented as "" (empty string). This way you can convert back and forth between boolean and string values.

An integer or a floating point number (float) is converted to a string representing the number with its digits (including the exponent part for floating point numbers).

Arrays are always converted to the string "Array", so you cannot dump out the contents of an array with echo() or print() to see what is inside them. To view one element, you'd do something like echo $arr['foo']. See below for tips on dumping/viewing the entire contents.

Objects are always converted to the string "Object". If you would like to print out the member variable values of an object for debugging reasons, read the paragraphs below. If you would like to find out the class name of which an object is an instance of, use get_class().

Resources are always converted to strings with the structure "Resource id #1" where 1 is the unique number of the resource assigned by PHP during runtime. If you would like to get the type of the resource, use get_resource_type().

NULL is always converted to an empty string.

As you can see above, printing out the arrays, objects or resources does not provide you any useful information about the values themselfs. Look at the functions print_r() and var_dump() for better ways to print out values for debugging.

You can also convert PHP values to strings to store them permanently. This method is called serialization, and can be done with the function serialize(). You can also serialize PHP values to XML structures, if you have WDDX support in your PHP setup.


String conversion to numbers

When a string is evaluated as a numeric value, the resulting value and type are determined as follows.

The string will evaluate as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise, it will evaluate as an integer.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

<?php
$foo = 1 + "10.5";                // $foo is float (11.5)
$foo = 1 + "-1.3e3";              // $foo is float (-1299)
$foo = 1 + "bob-1.3e3";           // $foo is integer (1)
$foo = 1 + "bob3";                // $foo is integer (1)
$foo = 1 + "10 Small Pigs";       // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1;          // $foo is float (11)
$foo = "10.0 pigs " + 1.0;        // $foo is float (11)     
?>

For more information on this conversion, see the Unix manual page for strtod(3).

If you would like to test any of the examples in this section, you can cut and paste the examples and insert the following line to see for yourself what's going on:

<?php
echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";
?>

Do not expect to get the code of one character by converting it to integer (as you would do in C for example). Use the functions ord() and chr() to convert between charcodes and characters.


Arrays

An array in PHP is actually an ordered map. A map is a type that maps values to keys. This type is optimized in several ways, so you can use it as a real array, or a list (vector), hashtable (which is an implementation of a map), dictionary, collection, stack, queue and probably more. Because you can have another PHP array as a value, you can also quite easily simulate trees.

Explanation of those data structures is beyond the scope of this manual, but you'll find at least one example for each of them. For more information we refer you to external literature about this broad topic.


Syntax

Specifying with array()

An array can be created by the array() language-construct. It takes a certain number of comma-separated key => value pairs.

array( [key =>] value
     , ...
     )
// key may be an integer or string
// value may be any value

<?php
$arr = array("foo" => "bar", 12 => true);

echo $arr["foo"]; // bar
echo $arr[12];    // 1
?>

A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). There are no different indexed and associative array types in PHP; there is only one array type, which can both contain integer and string indices.

A value can be of any PHP type.

<?php
$arr = array("somearray" => array(6 => 5, 13 => 9, "a" => 42));

echo $arr["somearray"][6];    // 5
echo $arr["somearray"][13];   // 9
echo $arr["somearray"]["a"];  // 42
?>

If you do not specify a key for a given value, then the maximum of the integer indices is taken, and the new key will be that maximum value + 1. If you specify a key that already has a value assigned to it, that value will be overwritten.

<?php
// This array is the same as ...
array(5 => 43, 32, 56, "b" => 12);

// ...this array
array(5 => 43, 6 => 32, 7 => 56, "b" => 12);
?>

Avvertimento

As of PHP 4.3.0, the index generation behaviour described above has changed. Now, if you append to an array in which the current maximum key is negative, then the next key created will be zero (0). Before, the new index would have been set to the largest existing key + 1, the same as positive indices are.

Using TRUE as a key will evaluate to integer 1 as key. Using FALSE as a key will evaluate to integer 0 as key. Using NULL as a key will evaluate to the empty string. Using the empty string as key will create (or overwrite) a key with the empty string and its value; it is not the same as using empty brackets.

You cannot use arrays or objects as keys. Doing so will result in a warning: Illegal offset type.


Creating/modifying with square-bracket syntax

You can also modify an existing array by explicitly setting values in it.

This is done by assigning values to the array while specifying the key in brackets. You can also omit the key, add an empty pair of brackets ("[]") to the variable name in that case.
$arr[key] = value;
$arr[] = value;
// key may be an integer or string
// value may be any value
If $arr doesn't exist yet, it will be created. So this is also an alternative way to specify an array. To change a certain value, just assign a new value to an element specified with its key. If you want to remove a key/value pair, you need to unset() it.

<?php
$arr = array(5 => 1, 12 => 2);

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42; // This adds a new element to
                // the array with key "x"
                
unset($arr[5]); // This removes the element from the array

unset($arr);    // This deletes the whole array
?>

Nota: As mentioned above, if you provide the brackets with no key specified, then the maximum of the existing integer indices is taken, and the new key will be that maximum value + 1 . If no integer indices exist yet, the key will be 0 (zero). If you specify a key that already has a value assigned to it, that value will be overwritten.

Avvertimento

As of PHP 4.3.0, the index generation behaviour described above has changed. Now, if you append to an array in which the current maximum key is negative, then the next key created will be zero (0). Before, the new index would have been set to the largest existing key + 1, the same as positive indices are.

Note that the maximum integer key used for this need not currently exist in the array. It simply must have existed in the array at some time since the last time the array was re-indexed. The following example illustrates:

<?php
// Create a simple array.
$array = array(1, 2, 3, 4, 5);
print_r($array);

// Now delete every item, but leave the array itself intact:
foreach ($array as $i => $value) {
    unset($array[$i]);
}
print_r($array);

// Append an item (note that the new key is 5, instead of 0 as you
// might expect).
$array[] = 6;
print_r($array);

// Re-index:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>

The above example would produce the following output:
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)


Useful functions

There are quite a few useful functions for working with arrays. See the array functions section.

Nota: The unset() function allows unsetting keys of an array. Be aware that the array will NOT be reindexed. If you only use "usual integer indices" (starting from zero, increasing by one), you can achieve the reindex effect by using array_values().

<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will produce an array that would have been defined as
   $a = array(1 => 'one', 3 => 'three');
   and NOT
   $a = array(1 => 'one', 2 =>'three');
*/

$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>

The foreach control structure exists specifically for arrays. It provides an easy way to traverse an array.


Array do's and don'ts

Why is $foo[bar] wrong?

You should always use quotes around a string literal array index. For example, use $foo['bar'] and not $foo[bar]. But why is $foo[bar] wrong? You might have seen the following syntax in old scripts:

<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>

This is wrong, but it works. Then, why is it wrong? The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes), and PHP may in future define constants which, unfortunately for your code, have the same name. It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that.

Nota: This does not mean to always quote the key. You do not want to quote keys which are constants or variables, as this will prevent PHP from interpreting them.

<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Simple array:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
    echo "\nChecking $i: \n";
    echo "Bad: " . $array['$i'] . "\n";
    echo "Good: " . $array[$i] . "\n";
    echo "Bad: {$array['$i']}\n";
    echo "Good: {$array[$i]}\n";
}
?>

Nota: The output from the above is:
Checking 0: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 1

Checking 1: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 2

More examples to demonstrate this fact:

<?php
// Let's show all errors
error_reporting(E_ALL);

$arr = array('fruit' => 'apple', 'veggie' => 'carrot');

// Correct
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Incorrect.  This works but also throws a PHP error of
// level E_NOTICE because of an undefined constant named fruit
// 
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// Let's define a constant to demonstrate what's going on.  We
// will assign value 'veggie' to a constant named fruit.
define('fruit', 'veggie');

// Notice the difference now
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// The following is okay as it's inside a string.  Constants are not
// looked for within strings so no E_NOTICE error here
print "Hello $arr[fruit]";      // Hello apple

// With one exception, braces surrounding arrays within strings
// allows constants to be looked for
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// This will not work, results in a parse error such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using autoglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";

// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>

When you turn error_reporting() up to show E_NOTICE level errors (such as setting it to E_ALL) then you will see these errors. By default, error_reporting is turned down to not show them.

As stated in the syntax section, there must be an expression between the square brackets ('[' and ']'). That means that you can write things like this:

<?php
echo $arr[somefunc($bar)];
?>

This is an example of using a function return value as the array index. PHP also knows about constants, as you may have seen the E_* ones before.

<?php
$error_descriptions[E_ERROR]   = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE]  = "This is just an informal notice";
?>

Note that E_ERROR is also a valid identifier, just like bar in the first example. But the last example is in fact the same as writing:

<?php
$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>

because E_ERROR equals 1, etc.

As we already explained in the above examples, $foo[bar] still works but is wrong. It works, because bar is due to its syntax expected to be a constant expression. However, in this case no constant with the name bar exists. PHP now assumes that you meant bar literally, as the string "bar", but that you forgot to write the quotes.


So why is it bad then?

At some point in the future, the PHP team might want to add another constant or keyword, or you may introduce another constant into your application, and then you get in trouble. For example, you already cannot use the words empty and default this way, since they are special reserved keywords.

Nota: To reiterate, inside a double-quoted string, it's valid to not surround array indexes with quotes so "$foo[bar]" is valid. See the above examples for details on why as well as the section on variable parsing in strings.


Converting to array

For any of the types: integer, float, string, boolean and resource, if you convert a value to an array, you get an array with one element (with index 0), which is the scalar value you started with.

If you convert an object to an array, you get the properties (member variables) of that object as the array's elements. The keys are the member variable names.

If you convert a NULL value to an array, you get an empty array.


Comparing

It is possible to compare arrays by array_diff() and by Array operators.


Examples

The array type in PHP is very versatile, so here will be some examples to show you the full power of arrays.

<?php
// this
$a = array( 'color' => 'red',
            'taste' => 'sweet',
            'shape' => 'round',
            'name'  => 'apple',
                       4        // key will be 0
          );

// is completely equivalent with
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // key will be 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// will result in the array array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// or simply array('a', 'b', 'c')
?>

Esempio 6-4. Using array()

<?php
// Array as (property-)map
$map = array( 'version'    => 4,
              'OS'         => 'Linux',
              'lang'       => 'english',
              'short_tags' => true
            );
            
// strictly numerical keys
$array = array( 7,
                8,
                0,
                156,
                -10
              );
// this is the same as array(0 => 7, 1 => 8, ...)

$switching = array(         10, // key = 0
                    5    =>  6,
                    3    =>  7, 
                    'a'  =>  4,
                            11, // key = 6 (maximum of integer-indices was 5)
                    '8'  =>  2, // key = 8 (integer!)
                    '02' => 77, // key = '02'
                    0    => 12  // the value 10 will be overwritten by 12
                  );
                  
// empty array
$empty = array();         
?>

Esempio 6-5. Collection

<?php
$colors = array('red', 'blue', 'green', 'yellow');

foreach ($colors as $color) {
    echo "Do you like $color?\n";
}

?>

This will output:

Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?

Note that it is currently not possible to change the values of the array directly in such a loop. A workaround is the following:

Esempio 6-6. Collection

<?php
foreach ($colors as $key => $color) {
    // won't work:
    //$color = strtoupper($color);
    
    // works:
    $colors[$key] = strtoupper($color);
}
print_r($colors);
?>

This will output:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

This example creates a one-based array.

Esempio 6-7. One-based index

<?php
$firstquarter  = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>

This will output:

Array 
(
    [1] => 'January'
    [2] => 'February'
    [3] => 'March'
)

Esempio 6-8. Filling an array

<?php
// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
    $files[] = $file;
}
closedir($handle); 
?>

Arrays are ordered. You can also change the order using various sorting functions. See the array functions section for more information. You can count the number of items in an array using the count() function.

Esempio 6-9. Sorting an array

<?php
sort($files);
print_r($files);
?>

Because the value of an array can be anything, it can also be another array. This way you can make recursive and multi-dimensional arrays.

Esempio 6-10. Recursive and multi-dimensional arrays

<?php
$fruits = array ( "fruits"  => array ( "a" => "orange",
                                       "b" => "banana",
                                       "c" => "apple"
                                     ),
                  "numbers" => array ( 1,
                                       2,
                                       3,
                                       4,
                                       5,
                                       6
                                     ),
                  "holes"   => array (      "first",
                                       5 => "second",
                                            "third"
                                     )
                );

// Some examples to address values in the array above 
echo $fruits["holes"][5];    // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]);  // remove "first"

// Create a new multi-dimensional array
$juices["apple"]["green"] = "good"; 
?>

You should be aware that array assignment always involves value copying. You need to use the reference operator to copy an array by reference.

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)
             
$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>


Objects

Object Initialization

To initialize an object, you use the new statement to instantiate the object to a variable.

<?php
class foo
{
    function do_foo()
    {
        echo "Doing foo."; 
    }
}

$bar = new foo;
$bar->do_foo();
?>

For a full discussion, please read the section Classes and Objects.


Converting to object

If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instance of the stdClass built in class is created. If the value was null, the new instance will be empty. For any other value, a member variable named scalar will contain the value.

<?php
$obj = (object) 'ciao';
echo $obj->scalar;  // outputs 'ciao'
?>


Resource

A resource is a special variable, holding a reference to an external resource. Resources are created and used by special functions. See the appendix for a listing of all these functions and the corresponding resource types.

Nota: The resource type was introduced in PHP 4


Converting to resource

As resource types hold special handlers to opened files, database connections, image canvas areas and the like, you cannot convert any value to a resource.


Freeing resources

Due to the reference-counting system introduced with PHP 4's Zend Engine, it is automatically detected when a resource is no longer referred to (just like Java). When this is the case, all resources that were in use for this resource are made free by the garbage collector. For this reason, it is rarely ever necessary to free the memory manually by using some free_result function.

Nota: Persistent database links are special, they are not destroyed by the garbage collector. See also the section about persistent connections.


NULL

The special NULL value represents that a variable has no value. NULL is the only possible value of type NULL.

Nota: The null type was introduced in PHP 4

A variable is considered to be NULL if

  • it has been assigned the constant NULL.

  • it has not been set to any value yet.

  • it has been unset().


Syntax

There is only one value of type NULL, and that is the case-insensitive keyword NULL.

<?php
$var = NULL;       
?>

See also is_null() and unset().


Pseudo-types used in this documentation

mixed

mixed indicates that a parameter may accept multiple (but not necessarily all) types.

gettype() for example will accept all PHP types, while str_replace() will accept strings and arrays.


number

number indicates that a parameter can be either integer or float.


callback

Some functions like call_user_func() or usort() accept user defined callback functions as a parameter. Callback functions can not only be simple functions but also object methods including static class methods.

A PHP function is simply passed by its name as a string. You can pass any builtin or user defined function with the exception of array(), echo(), empty(), eval(), exit(), isset(), list(), print() and unset().

A method of an instantiated object is passed as an array containing an object as the element with index 0 and a method name as the element with index 1.

Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object as the element with index 0.

Esempio 6-11. Callback function examples

<?php 

// simple callback example
function my_callback_function() {
    echo 'hello world!';
}
call_user_func('my_callback_function'); 

// method callback examples
class MyClass {
    function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// static class method call without instantiating an object
call_user_func(array('MyClass', 'myCallbackMethod')); 

// object method call
$obj = new MyClass();
call_user_func(array(&$obj, 'myCallbackMethod'));
?>


Type Juggling

PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which that variable is used. That is to say, if you assign a string value to variable $var, $var becomes a string. If you then assign an integer value to $var, it becomes an integer.

An example of PHP's automatic type conversion is the addition operator '+'. If any of the operands is a float, then all operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does NOT change the types of the operands themselves; the only change is in how the operands are evaluated.

<?php
$foo = "0";  // $foo is string (ASCII 48)
$foo += 2;   // $foo is now an integer (2)
$foo = $foo + 1.3;  // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs";     // $foo is integer (15)
?>

If the last two examples above seem odd, see String conversion to numbers.

If you wish to force a variable to be evaluated as a certain type, see the section on Type casting. If you wish to change the type of a variable, see settype().

If you would like to test any of the examples in this section, you can use the var_dump() function.

Nota: The behaviour of an automatic conversion to array is currently undefined.

<?php
$a = "1";     // $a is a string
$a[0] = "f";  // What about string offsets? What happens?
?>

Since PHP (for historical reasons) supports indexing into strings via offsets using the same syntax as array indexing, the example above leads to a problem: should $a become an array with its first element being "f", or should "f" become the first character of the string $a?

The current versions of PHP interpret the second assignment as a string offset identification, so $a becomes "f", the result of this automatic conversion however should be considered undefined. PHP 4 introduced the new curly bracket syntax to access characters in string, use this syntax instead of the one presented above:

<?php
$a    = "abc"; // $a is a string
$a{1} = "f";   // $a is now "afc"
?>

See the section titled String access by character for more information.


Type Casting

Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.

<?php
$foo = 10;   // $foo is an integer
$bar = (boolean) $foo;   // $bar is a boolean
?>

The casts allowed are:

  • (int), (integer) - cast to integer

  • (bool), (boolean) - cast to boolean

  • (float), (double), (real) - cast to float

  • (string) - cast to string

  • (array) - cast to array

  • (object) - cast to object

Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent:

<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>

Nota: Instead of casting a variable to string, you can also enclose the variable in double quotes.

<?php
$foo = 10;            // $foo is an integer
$str = "$foo";        // $str is a string
$fst = (string) $foo; // $fst is also a string

// This prints out that "they are the same"
if ($fst === $str) {
    echo "they are the same";
}
?>

It may not be obvious exactly what will happen when casting between certain types. For more info, see these sections:


Capitolo 7. Variables

Basics

Variables in PHP are represented by a dollar sign followed by the name of the variable. The variable name is case-sensitive.

Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'

Nota: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff).

<?php
$var = "Bob";
$Var = "Joe";
echo "$var, $Var";      // outputs "Bob, Joe"

$4site = 'not yet';     // invalid; starts with a number
$_4site = 'not yet';    // valid; starts with an underscore
$täyte = 'mansikka';    // valid; 'ä' is (Extended) ASCII 228.
?>

In PHP 3, variables are always assigned by value. That is to say, when you assign an expression to a variable, the entire value of the original expression is copied into the destination variable. This means, for instance, that after assigning one variable's value to another, changing one of those variables will have no effect on the other. For more information on this kind of assignment, see the chapter on Expressions.

PHP 4 offers another way to assign values to variables: assign by reference. This means that the new variable simply references (in other words, "becomes an alias for" or "points to") the original variable. Changes to the new variable affect the original, and vice versa. This also means that no copying is performed; thus, the assignment happens more quickly. However, any speedup will likely be noticed only in tight loops or when assigning large arrays or objects.

To assign by reference, simply prepend an ampersand (&) to the beginning of the variable which is being assigned (the source variable). For instance, the following code snippet outputs 'My name is Bob' twice:

<?php
$foo = 'Bob';              // Assign the value 'Bob' to $foo
$bar = &$foo;              // Reference $foo via $bar.
$bar = "My name is $bar";  // Alter $bar...
echo $bar;
echo $foo;                 // $foo is altered too.
?>

One important thing to note is that only named variables may be assigned by reference.

<?php
$foo = 25;
$bar = &$foo;      // This is a valid assignment.
$bar = &(24 * 7);  // Invalid; references an unnamed expression.

function test()
{
   return 25;
}

$bar = &test();    // Invalid.
?>


Predefined variables

PHP provides a large number of predefined variables to any script which it runs. Many of these variables, however, cannot be fully documented as they are dependent upon which server is running, the version and setup of the server, and other factors. Some of these variables will not be available when PHP is run on the command line. For a listing of these variables, please see the section on Reserved Predefined Variables.

Avvertimento

In PHP 4.2.0 and later, the default value for the PHP directive register_globals is off. This is a major change in PHP. Having register_globals off affects the set of predefined variables available in the global scope. For example, to get DOCUMENT_ROOT you'll use $_SERVER['DOCUMENT_ROOT'] instead of $DOCUMENT_ROOT, or $_GET['id'] from the URL http://www.example.com/test.php?id=3 instead of $id, or $_ENV['HOME'] instead of $HOME.

For related information on this change, read the configuration entry for register_globals, the security chapter on Using Register Globals , as well as the PHP 4.1.0 and 4.2.0 Release Announcements.

Using the available PHP Reserved Predefined Variables, like the superglobal arrays, is preferred.

From version 4.1.0 onward, PHP provides an additional set of predefined arrays containing variables from the web server (if applicable), the environment, and user input. These new arrays are rather special in that they are automatically global--i.e., automatically available in every scope. For this reason, they are often known as 'autoglobals' or 'superglobals'. (There is no mechanism in PHP for user-defined superglobals.) The superglobals are listed below; however, for a listing of their contents and further discussion on PHP predefined variables and their natures, please see the section Reserved Predefined Variables. Also, you'll notice how the older predefined variables ($HTTP_*_VARS) still exist. Dalla versione 5.0.0 di PHP gli array predefiniti di PHP, variabili predefinite possono essere disabilitati usando la direttiva register_long_arrays.

Variable variables: Superglobals cannot be used as variable variables inside functions or class methods.

Nota: Even though both the superglobal and HTTP_*_VARS can exist at the same time; they are not identical, so modifiying one will not change the other.

If certain variables in variables_order are not set, their appropriate PHP predefined arrays are also left empty.

PHP Superglobals

$GLOBALS

Contains a reference to every variable which is currently available within the global scope of the script. The keys of this array are the names of the global variables. $GLOBALS has existed since PHP 3.

$_SERVER

Variables set by the web server or otherwise directly related to the execution environment of the current script. Analogous to the old $HTTP_SERVER_VARS array (which is still available, but deprecated).

$_GET

Variables provided to the script via HTTP GET. Analogous to the old $HTTP_GET_VARS array (which is still available, but deprecated).

$_POST

Variables provided to the script via HTTP POST. Analogous to the old $HTTP_POST_VARS array (which is still available, but deprecated).

$_COOKIE

Variables provided to the script via HTTP cookies. Analogous to the old $HTTP_COOKIE_VARS array (which is still available, but deprecated).

$_FILES

Variables provided to the script via HTTP post file uploads. Analogous to the old $HTTP_POST_FILES array (which is still available, but deprecated). See POST method uploads for more information.

$_ENV

Variables provided to the script via the environment. Analogous to the old $HTTP_ENV_VARS array (which is still available, but deprecated).

$_REQUEST

Variables provided to the script via the GET, POST, and COOKIE input mechanisms, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the PHP variables_order configuration directive. This array has no direct analogue in versions of PHP prior to 4.1.0. See also import_request_variables().

Attenzione

Since PHP 4.3.0, FILE information from $_FILES does not exist in $_REQUEST.

Nota: When running on the command line , this will not include the argv and argc entries; these are present in the $_SERVER array.

$_SESSION

Variables which are currently registered to a script's session. Analogous to the old $HTTP_SESSION_VARS array (which is still available, but deprecated). See the Session handling functions section for more information.


Variable scope

The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well. For example:

<?php
$a = 1;
include "b.inc";
?>

Here the $a variable will be available within the included b.inc script. However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope. For example:

<?php
$a = 1; /* global scope */ 

function Test()
{ 
    echo $a; /* reference to local scope variable */ 
} 

Test();
?>

This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope. You may notice that this is a little bit different from the C language in that global variables in C are automatically available to functions unless specifically overridden by a local definition. This can cause some problems in that people may inadvertently change a global variable. In PHP global variables must be declared global inside a function if they are going to be used in that function.


The global keyword

First, an example use of global:

Esempio 7-1. Using global

<?php
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;

    $b = $a + $b;
} 

Sum();
echo $b;
?>

The above script will output "3". By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function.

A second way to access variables from the global scope is to use the special PHP-defined $GLOBALS array. The previous example can be rewritten as:

Esempio 7-2. Using $GLOBALS instead of global

<?php
$a = 1;
$b = 2;

function Sum()
{
    $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
} 

Sum();
echo $b;
?>

The $GLOBALS array is an associative array with the name of the global variable being the key and the contents of that variable being the value of the array element. Notice how $GLOBALS exists in any scope, this is because $GLOBALS is a superglobal. Here's an example demonstrating the power of superglobals:

Esempio 7-3. Example demonstrating superglobals and scope

<?php
function test_global()
{
    // Most predefined variables aren't "super" and require 
    // 'global' to be available to the functions local scope.
    global $HTTP_POST_VARS;
    
    echo $HTTP_POST_VARS['name'];
    
    // Superglobals are available in any scope and do 
    // not require 'global'. Superglobals are available 
    // as of PHP 4.1.0
    echo $_POST['name'];
}
?>


Using static variables

Another important feature of variable scoping is the static variable. A static variable exists only in a local function scope, but it does not lose its value when program execution leaves this scope. Consider the following example:

Esempio 7-4. Example demonstrating need for static variables

<?php
function Test ()
{
    $a = 0;
    echo $a;
    $a++;
}
?>

This function is quite useless since every time it is called it sets $a to 0 and prints "0". The $a++ which increments the variable serves no purpose since as soon as the function exits the $a variable disappears. To make a useful counting function which will not lose track of the current count, the $a variable is declared static:

Esempio 7-5. Example use of static variables

<?php
function Test()
{
    static $a = 0;
    echo $a;
    $a++;
}
?>

Now, every time the Test() function is called it will print the value of $a and increment it.

Static variables also provide one way to deal with recursive functions. A recursive function is one which calls itself. Care must be taken when writing a recursive function because it is possible to make it recurse indefinitely. You must make sure you have an adequate way of terminating the recursion. The following simple function recursively counts to 10, using the static variable $count to know when to stop:

Esempio 7-6. Static variables with recursive functions

<?php
function Test()
{
    static $count = 0;

    $count++;
    echo $count;
    if ($count < 10) {
        Test ();
    }
    $count--;
}
?>

Nota: Static variables maybe declared as seen in the examples above. Trying to assign values to these variables which are the result of expressions will cause a parse error.

Esempio 7-7. Declaring static variables

<?php
function foo(){
    static $int = 0;          // correct 
    static $int = 1+2;        // wrong  (as it is an expression)
    static $int = sqrt(121);  // wrong  (as it is an expression too)

    $int++;
    echo $int;
}
?>


References with global and static variables

The Zend Engine 1, driving PHP 4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example addresses:

<?php
function test_global_ref() {
    global $obj;
    $obj = &new stdclass;
}

function test_global_noref() {
    global $obj;
    $obj = new stdclass;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

Executing this example will result in the following output:

NULL
object(stdClass)(0) {
}

A similar behaviour applies to the static statement. References are not stored statically:

<?php
function &get_instance_ref() {
    static $obj;

    echo "Static object: ";
    var_dump($obj);
    if (!isset($obj)) {
        // Assign a reference to the static variable
        $obj = &new stdclass;
    }
    $obj->property++;
    return $obj;
}

function &get_instance_noref() {
    static $obj;

    echo "Static object: ";
    var_dump($obj);
    if (!isset($obj)) {
        // Assign the object to the static variable
        $obj = new stdclass;
    }
    $obj->property++;
    return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>

Executing this example will result in the following output:

Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)(1) {
  ["property"]=>
  int(1)
}

This example demonstrates that when assigning a reference to a static variable, it's not remembered when you call the &get_instance_ref() function a second time.


Variable variables

Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as:

<?php
$a = "hello";
?>

A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e.

<?php
$$a = "world";
?>

At this point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello" and $hello with contents "world". Therefore, this statement:

<?php
echo "$a ${$a}";
?>

produces the exact same output as:

<?php
echo "$a $hello";
?>

i.e. they both produce: hello world.

In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.

Avvertimento

Please note that variable variables cannot be used with PHP's Superglobal arrays. This means you cannot do things like ${$_GET}. If you are looking for a way to handle availability of superglobals and the old HTTP_*_VARS, you might want to try referencing them.


Variables from outside PHP

HTML Forms (GET and POST)

When a form is submitted to a PHP script, the information from that form is automatically made available to the script. There are many ways to access this information, for example:

Esempio 7-8. A simple HTML form

<form action="foo.php" method="post">
    Name:  <input type="text" name="username" /><br />
    Email: <input type="text" name="email" /><br />
    <input type="submit" name="submit" value="Submit me!" />
</form>

Depending on your particular setup and personal preferences, there are many ways to access data from your HTML forms. Some examples are:

Esempio 7-9. Accessing data from a simple POST HTML form

<?php 
// Available since PHP 4.1.0

   echo $_POST['username'];
   echo $_REQUEST['username'];

   import_request_variables('p', 'p_');
   echo $p_username;

// Available since PHP 3. As of PHP 5.0.0, these long predefined
// variables can be disabled with the register_long_arrays directive.

   echo $HTTP_POST_VARS['username'];

// Available if the PHP directive register_globals = on. As of 
// PHP 4.2.0 the default value of register_globals = off.
// Using/relying on this method is not preferred.

   echo $username;
?>

Using a GET form is similar except you'll use the appropriate GET predefined variable instead. GET also applies to the QUERY_STRING (the information after the '?' in a URL). So, for example, http://www.example.com/test.php?id=3 contains GET data which is accessible with $_GET['id']. See also $_REQUEST and import_request_variables().

Nota: Superglobal arrays, like $_POST and $_GET, became available in PHP 4.1.0

As shown, before PHP 4.2.0 the default value for register_globals was on. And, in PHP 3 it was always on. The PHP community is encouraging all to not rely on this directive as it's preferred to assume it's off and code accordingly.

Nota: The magic_quotes_gpc configuration directive affects Get, Post and Cookie values. If turned on, value (It's "PHP!") will automagically become (It\'s \"PHP!\"). Escaping is needed for DB insertion. See also addslashes(), stripslashes() and magic_quotes_sybase.

PHP also understands arrays in the context of form variables (see the related faq). You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input. For example, let's post a form to itself and upon submission display the data:

Esempio 7-10. More complex form variables

<?php
if (isset($_POST['action']) && $_POST['action'] == 'submitted') {
    echo '<pre>';
    print_r($_POST);
    echo '<a href="'. $_SERVER['PHP_SELF'] .'">Please try again</a>';

    echo '</pre>';
} else {
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    Name:  <input type="text" name="personal[name]" /><br />
    Email: <input type="text" name="personal[email]" /><br />
    Beer: <br />
    <select multiple name="beer[]">
        <option value="warthog">Warthog</option>
        <option value="guinness">Guinness</option>
        <option value="stuttgarter">Stuttgarter Schwabenbräu</option>
    </select><br />
    <input type="hidden" name="action" value="submitted" />
    <input type="submit" name="submit" value="submit me!" />
</form>
<?php
}
?>

In PHP 3, the array form variable usage is limited to single-dimensional arrays. In PHP 4, no such restriction applies.


IMAGE SUBMIT variable names

When submitting a form, it is possible to use an image instead of the standard submit button with a tag like:

<input type="image" src="image.gif" name="sub" />

When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables, sub_x and sub_y. These contain the coordinates of the user click within the image. The experienced may note that the actual variable names sent by the browser contains a period rather than an underscore, but PHP converts the period to an underscore automatically.


HTTP Cookies

PHP transparently supports HTTP cookies as defined by Netscape's Spec. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() function. Cookies are part of the HTTP header, so the SetCookie function must be called before any output is sent to the browser. This is the same restriction as for the header() function. Cookie data is then available in the appropriate cookie data arrays, such as $_COOKIE, $HTTP_COOKIE_VARS as well as in $_REQUEST. See the setcookie() manual page for more details and examples.

If you wish to assign multiple values to a single cookie variable, you may assign it as an array. For example:

<?php
  setcookie("MyCookie[foo]", "Testing 1", time()+3600);
  setcookie("MyCookie[bar]", "Testing 2", time()+3600);
?>

That will create two separate cookies although MyCookie will now be a single array in your script. If you want to set just one cookie with multiple values, consider using serialize() or explode() on the value first.

Note that a cookie will replace a previous cookie by the same name in your browser unless the path or domain is different. So, for a shopping cart application you may want to keep a counter and pass this along. i.e.

Esempio 7-11. A setcookie() example

<?php
if (isset($_COOKIE['count'])) {
    $count = $_COOKIE['count'] + 1;
} else {
    $count = 1;
}
setcookie("count", $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);
?>

Dots in incoming variable names

Typically, PHP does not alter the names of variables when they are passed into a script. However, it should be noted that the dot (period, full stop) is not a valid character in a PHP variable name. For the reason, look at it:
<?php
$varname.ext;  /* invalid variable name */
?>
Now, what the parser sees is a variable named $varname, followed by the string concatenation operator, followed by the barestring (i.e. unquoted string which doesn't match any known key or reserved words) 'ext'. Obviously, this doesn't have the intended result.

For this reason, it is important to note that PHP will automatically replace any dots in incoming variable names with underscores.


Determining variable types

Because PHP determines the types of variables and converts them (generally) as needed, it is not always obvious what type a given variable is at any one time. PHP includes several functions which find out what type a variable is, such as: gettype(), is_array(), is_float(), is_int(), is_object(), and is_string(). See also the chapter on Types.


Capitolo 8. Costanti

Una costante è un identificatore (nome) per un valore. Come si può intuire, tale valore non può cambiare durante l'esecuzione dello script (fanno eccezione le costanti magiche, che, in realtà, non sono costanti). Una costante è "case-sensitive" per default. È convenzione comune che i nomi di costante siano sempre maiuscoli.

In PHP il nome di una costante segue le regole di qualsiasi "etichetta". Un nome di costante valido inizia con una lettera o underscore, seguita da un numero qualsiasi di caratteri alfanumerici o underscore. L'espressione regolare che esprime questa convenzione è: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

Nota: In questo contesto una lettera è a-z, A-Z e i caratteri ASCII dal 127 al 255 (0x7f-0xff).

Come le superglobals, costante è sempre globale. Si può accedere alle costanti da qualsiasi punto dello script senza tenere conto della visibilità. Per maggiori dettagli sulla visibilità, leggere la sezione variable scope.


Sintassi

È possibile definire una variabile utilizzando la funzione define(). Una volta definita, a una costante non è possibile cambiare il valore o eliminarla.

Le costanti possono contenere solo dati di tipo scalare (boolean, integer, float e string).

Per ottenere il valore di una costante è sufficiente specificarne il nome. A differenza delle variabili, non è necessario anteporre il simbolo $ al nome di una variabile. Si può anche utilizzare la funzione constant(), per leggere il valore di una costante, nel caso in cui se ne ottenga dinamicamente il nome. Si utilizzi get_defined_constants() per ottenere una lista delle variabili definite.

Nota: Costanti e variabili (globali) si trovano in un "namespace" differente. Questo implica che generalmente TRUE e $TRUE sono differenti.

Se si utilizza il nome di una costante che non è definita, PHP assume che detto valore sia il nome della costante stessa, come se si fosse inserito il testo nel nome . Quando ciò accade PHP segnala il problema con un E_NOTICE. Vedere anche il capitolo del manuale sul perchè $foo[bar] è errata (a meno che prima non definisca bar come costante con define()). Per sapere se una costante è definita, si può utilizzare la funzione defined().

Di seguito sono riportate le principali differenze rispetto le variabili:

  • Le costanti non iniziano con il segno del dollaro ($);

  • Le costanti possono essere definite solo con la funzione define() e non tramite assegnazione;

  • Le costanti possono essere definite e utilizzate ovunque senza seguire le regole di visibilità;

  • Una volta impostate, le costanti non posso essere redefinite e ne annullate;

  • Le costanti possono essere solo valori scalari;

Esempio 8-1. Definizione di costanti

<?php
define("COSTANTE", "Ciao mondo.");
echo COSTANTE; // stampa "Ciao mondo."
echo Costante; // stampa "Costante" e genera una notice.
?>


Costanti predefinite

Il PHP mette a disposizione ad ogni script diverse costanti predefinite. Alcune di queste, tuttavia, sono create dai vari moduli, e, pertanto, saranno disponibili solo quando questi moduli sono caricati, sia dinamicamente sia staticamente.

Esistono quattro costanti magiche il cui valore cambia in base al contesto in cui sono utilizzate. Ad esempio, il valore di __LINE__ dipende da quale linea si trova nel momento in cui è richiamata. Queste costanti speciali sono 'case-insensitive' e sono:

Tabella 8-1. Le costanti "magiche" del PHP

NomeDescrizione
__LINE__ Il numero di linea corrente.
__FILE__ Il nome e percorso assoluto del file.
__FUNCTION__ Nome della funzione. (Aggiunta nel PHP 4.3.0.)
__CLASS__ Nome della classe. (Aggiunta nel PHP 4.3.0.)
__METHOD__ Nome del metodo della classe (Aggiunta nel PHP 5.0.0.)

La lista di tutte le costanti predefinite è presente nella sezione reserved predefined constants.


Capitolo 9. Expressions

Expressions are the most important building stones of PHP. In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is "anything that has a value".

The most basic forms of expressions are constants and variables. When you type "$a = 5", you're assigning '5' into $a. '5', obviously, has the value 5, or in other words '5' is an expression with the value of 5 (in this case, '5' is an integer constant).

After this assignment, you'd expect $a's value to be 5 as well, so if you wrote $b = $a, you'd expect it to behave just as if you wrote $b = 5. In other words, $a is an expression with the value of 5 as well. If everything works right, this is exactly what will happen.

Slightly more complex examples for expressions are functions. For instance, consider the following function:

<?php
function foo ()
{
    return 5;
}
?>

Assuming you're familiar with the concept of functions (if you're not, take a look at the chapter about functions), you'd assume that typing $c = foo() is essentially just like writing $c = 5, and you're right. Functions are expressions with the value of their return value. Since foo() returns 5, the value of the expression 'foo()' is 5. Usually functions don't just return a static value but compute something.

Of course, values in PHP don't have to be integers, and very often they aren't. PHP supports four scalar value types: integer values, floating point values (float), string values and boolean values (scalar values are values that you can't 'break' into smaller pieces, unlike arrays, for instance). PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned into variables or returned from functions.

PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we've already dealt with, '$a = 5'. It's easy to see that there are two values involved here, the value of the integer constant '5', and the value of $a which is being updated to 5 as well. But the truth is that there's one additional value involved here, and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that '$a = 5', regardless of what it does, is an expression with the value 5. Thus, writing something like '$b = ($a = 5)' is like writing '$a = 5; $b = 5;' (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write '$b = $a = 5'.

Another good example of expression orientation is pre- and post-increment and decrement. Users of PHP and many other languages may be familiar with the notation of variable++ and variable--. These are increment and decrement operators. In PHP, the statement '$a++' has no value (is not an expression), and thus you can't assign it or use it in any way. PHP enhances the increment/decrement capabilities by making these expressions as well, like in C. In PHP, like in C, there are two types of increment - pre-increment and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect on the variable is identical. The difference is with the value of the increment expression. Pre-increment, which is written '++$variable', evaluates to the incremented value (PHP increments the variable before reading its value, thus the name 'pre-increment'). Post-increment, which is written '$variable++' evaluates to the original value of $variable, before it was incremented (PHP increments the variable after reading its value, thus the name 'post-increment').

A very common type of expressions are comparison expressions. These expressions evaluate to either FALSE or TRUE. PHP supports > (bigger than), >= (bigger than or equal to), == (equal), != (not equal), < (smaller than) and <= (smaller than or equal to). The language also supports a set of strict equivalence operators: === (equal to and same type) and !== (not equal to or not same type). These expressions are most commonly used inside conditional execution, such as if statements.

The last example of expressions we'll deal with here is combined operator-assignment expressions. You already know that if you want to increment $a by 1, you can simply write '$a++' or '++$a'. But what if you want to add more than one to it, for instance 3? You could write '$a++' multiple times, but this is obviously not a very efficient or comfortable way. A much more common practice is to write '$a = $a + 3'. '$a + 3' evaluates to the value of $a plus 3, and is assigned back into $a, which results in incrementing $a by 3. In PHP, as in several other languages like C, you can write this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of $a can be written '$a += 3'. This means exactly "take the value of $a, add 3 to it, and assign it back into $a". In addition to being shorter and clearer, this also results in faster execution. The value of '$a += 3', like the value of a regular assignment, is the assigned value. Notice that it is NOT 3, but the combined value of $a plus 3 (this is the value that's assigned into $a). Any two-place operator can be used in this operator-assignment mode, for example '$a -= 5' (subtract 5 from the value of $a), '$b *= 7' (multiply the value of $b by 7), etc.

There is one more expression that may seem odd if you haven't seen it in other languages, the ternary conditional operator:

<?php
$first ? $second : $third
?>

If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.

The following example should help you understand pre- and post-increment and expressions in general a bit better:

<?php
function double($i)
{
    return $i*2;
}
$b = $a = 5;        /* assign the value five into the variable $a and $b */
$c = $a++;          /* post-increment, assign original value of $a 
                       (5) to $c */
$e = $d = ++$b;     /* pre-increment, assign the incremented value of 
                       $b (6) to $d and $e */

/* at this point, both $d and $e are equal to 6 */

$f = double($d++);  /* assign twice the value of $d before
                       the increment, 2*6 = 12 to $f */
$g = double(++$e);  /* assign twice the value of $e after
                       the increment, 2*7 = 14 to $g */
$h = $g += 10;      /* first, $g is incremented by 10 and ends with the 
                       value of 24. the value of the assignment (24) is 
                       then assigned into $h, and $h ends with the value 
                       of 24 as well. */
?>

Some expressions can be considered as statements. In this case, a statement has the form of 'expr' ';' that is, an expression followed by a semicolon. In '$b=$a=5;', $a=5 is a valid expression, but it's not a statement by itself. '$b=$a=5;' however is a valid statement.

One last thing worth mentioning is the truth value of expressions. In many events, mainly in conditional execution and loops, you're not interested in the specific value of the expression, but only care about whether it means TRUE or FALSE. The constants TRUE and FALSE (case-insensitive) are the two possible boolean values. When necessary, an expression is automatically converted to boolean. See the section about type-casting for details about how.

PHP provides a full and powerful implementation of expressions, and documenting it entirely goes beyond the scope of this manual. The above examples should give you a good idea about what expressions are and how you can construct useful expressions. Throughout the rest of this manual we'll write expr to indicate any valid PHP expression.


Capitolo 10. Operatori


Precedenza degli operatori

La precedenza di un operatore specifica come esso tenga legate assieme "strettamente" due espressioni. Per esempio, nell'espressione 1 + 5 * 3, la risposta è 16 e non 18 perché l'operatore di moltiplicazione ("*") ha una precedenza più alta rispetto all'operatore di addizione ("+"). Le parentesi possono essere usate per forzare la precedenza, se necessario. Per esempio: (1 + 5) * 3 viene valutata 18.

La seguente tabella fornisce una lista della precedenza degli operatori con gli operatori a più bassa precedenza listati prima.

Tabella 10-1. Precedenza degli operatori

AssociativitàOperatori
sinistra,
sinistraor
sinistraxor
sinistraand
destraprint
sinistra = += -= *= /= .= %= &= |= ^= ~= <<= >>=
sinistra? :
sinistra||
sinistra&&
sinistra|
sinistra^
sinistra&
non associativi== != === !==
non associativi< <= > >=
sinistra<< >>
sinistra+ - .
sinistra* / %
destra! ~ ++ -- (int) (float) (string) (array) (object) @
destra[
non associativinew


Operatori aritmetici

Ricordate l'aritmetica di base dalla scuola? Questi funzionano proprio come quelli.

Tabella 10-2. Operatori aritmetici

EsempioNomeRisultato
$a + $bAddizioneLa somma di $a e $b.
$a - $bSottrazioneLa differenza di $a e $b.
$a * $bMoltiplicazioneil prodotto di $a e $b.
$a / $bDivisioneQuoziente di $a e $b.
$a % $bModuloIl resto di $a diviso da $b.

L'operatore di divisione ("/") restituisce un valore float in ogni caso, anche se i due operandi sono interi (oppure stringhe che vengono convertite in interi).


Operatori di assegnazione

L'operatore di base dell'assegnazione è "=". La vostra prima inclinazione potrebbe essere di pensare che ciò sia come "uguale a". No. Esso significa realmente che l'operando a sinistra assume il valore dell'espressione a destra (ciò significa, "assegna il valore a").

Il valore di un'espressione di assegnazione è il valore assegnato. Cioè il valore di "$a = 3" è 3. Questo vi permette di fare qualche trucchetto:

$a = ($b = 4) + 5; // $a è uguale a 9 ora, e $b è stato impostato a 4.

In aggiunta all'operatore di base dell'assegnazione, ci sono gli "operatori combinati" per tutta l'aritmetica binaria e gli operatori di stringa che vi consentono di usare un valore in un'espressione e poi impostare il suo valore al risultato di quell'espressione. Per esempio:

$a = 3;
$a += 5; // imposta $a a 8, come se avessimo detto: $a = $a + 5;
$b = "Ciao ";
$b .= "Lì!"; // imposta $b a "Ciao Lì!", proprio come $b = $b . "Lì!";

Notare che l'assegnazione copia la variabile originale alla nuova (assegnazione per valore), così i cambiamenti ad una non si verificheranno nell' altra. Ciò può anche avere rilevanza se avete bisogno di copiare qualcosa come un grande array in un ciclo molto stretto. PHP 4 supporta l'assegnazione per riferimento, usando la sintassi $var = &$othervar;, ma ciò non è possibile in PHP 3. 'L'assegnazione per riferimento' vuol dire che entrambe le variabili finiscono con il puntare agli stessi dati, e nulla è copiato in nessun posto. Per ulteriori approfondimenti sui riferimenti, consultare References explained.


Operatori bitwise

Gli operatori bitwise vi permettono di alterare bit specifici in posizione on oppure off. Se entrambi i parametri di sinistra e destra sono stringhe, l'operatore bitwise opererà sui caratteri di questa stringa.

<?php
    echo 12 ^ 9; // L'output è '5'

    echo "12" ^ "9"; // L'output è il carattere Backspace (ascii 8)
                     // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8

    echo "hallo" ^ "hello"; // L'output è il valore ascii #0 #4 #0 #0 #0
                            // 'a' ^ 'e' = #4
?>

Tabella 10-3. Operatori bitwise

EsempioNomeRisultato
$a & $bAndSono impostati ad ON i bit che sono ON sia in $a che in $b.
$a | $bOrSono impostati ad ON i bit che sono ON in $a oppure in $b.
$a ^ $bXor Sono impostati ad ON i bit che sono ON in $a oppure in $b na non quelli che sono entrambi ON.
~ $aNot Sono impostati ad ON i bit che sono OFF in $a, e viceversa.
$a << $bShift left Sposta i bit di $a a sinistra di $b passi (ogni passo significa "moltiplica per due")
$a >> $bShift right Sposta i bit di $a a destra di $b passi (ogni passo significa "dividi per due")

Operatori di confronto

Gli operatori di confronto, come suggerisce il loro nome, permettono di confrontare due valori.

Tabella 10-4. Operatori di confronto

EsempioNomeRisultato
$a == $bUgualeTRUE se $a è uguale a $b.
$a === $bIdentico TRUE se $a è uguale a $b, ed essi sono dello stesso tipo. (Solo PHP 4)
$a != $bDiversiTRUE se $a è diverso da $b.
$a <> $bDiversiTRUE se $a è diverso da $b.
$a !== $bNon identici TRUE se $a è diverso da $b, o se essi non sono dello stesso tipo. (Solo PHP 4)
$a < $bMinoreTRUE se $a è strettamente minore di $b.
$a > $bMaggioreTRUE se $a è strettamente maggiore di $b.
$a <= $bMinore o ugualeTRUE se $a è minore o uguale a $b.
$a >= $bMaggiore o ugualeTRUE se $a è maggiore o uguale a $b.

Un altro operatore condizionale è l'operatore "?:" (o ternario), che opera come in C e molti altri linguaggi.

(espressione1) ? (espressione2) : (espressione3);

Questa espressione vale espressione2 se espressione1 è TRUE, e espressione3 se espressione1 è FALSE.


Operatori di controllo errori

PHP supporta un operatore di controllo dell'errore: il carattere at (@). Quando prefisso ad una espressione in PHP, qualunque messaggio di errore che potesse essere generato da quella espressione sarà ignorato.

Se la caratteristica track_errors è abilitata, qualsiasi messaggio di errore generato dall'espressione sarà salvato nella variabile globale $php_errormsg. Questa variabile sarà sovrascritta ad ogni errore, così controllatela subito se volete usarla.

<?php
/* Errore di file intenzionale */
$my_file = @file ('file_inesistente') or
    die ("Apertura del file fallita: l'errore è '$php_errormsg'");

// questo funziona per qualsiasi espressione, non solo funzioni:
$value = @$cache[$key];
// non verrà generata una notifica se l'indice $key non esiste.

?>

Nota: L'operatore @ funziona solo sulle espressioni. Una semplice regola di thumb è: se potete prendere il valore di qualcosa, potete anteporre ad esso l'operatore @. Per esempio, potete anteporre esso a variabili, funzioni e chiamate ad include(), costanti, e così via. non potete anteporre esso a definizioni di funzioni o classi, o strutture condizionali come if e foreach, e così via.

Vedere anche error_reporting().

Avvertimento

Attualmente il prefisso operatore di controllo dell'errore "@" disabiliterà la restituzione di errori per errori critici che interromperanno l'esecuzione dello script. Tra le altre cose, questo significa che se state usando "@" per sopprimere errori da una certa funzione ed essa non è disponibile oppure è stata scritta male, lo script terminerà senza dare indicazioni sul perché.


Operatori di esecuzione

PHP supporta un operatore di esecuzione: backticks (``). Notare che quelli non sono apostrofi! PHP cercherà di eseguire il contenuto dei backticks come comando di shell; sarà restituito l'output (i.e., non sarà semplicemente esportato come output; può essere assegnato ad una variabile).

$output = `ls -al`;
echo "<pre>$output</pre>";

Nota: L'operatore backtick è disabilitato quando è abilitata safe mode oppure quando è disabilitata shell_exec().

Vedere anche escapeshellcmd(), exec(), passthru(), popen(), shell_exec() e system().


Operatori di incremento/decremento

PHP supporta lo stile C degli operatori di pre- e post-incremento e decremento.

Tabella 10-5. Operatori di incremento/decremento

EsempioNomeEffetto
++$aPre-incrementoIncrementa $a di una unità, inoltre restituisce $a.
$a++Post-incrementoRestituisce $a, inoltre incrementa $a di una unità.
--$aPre-decrementoDecrementa $a di una unità, inoltre restituisce $a.
$a--Post-decrementoRestituisce $a, inoltre decrementa $a di una unità.

Qui c'è un semplice script di esempio:

<?php
echo "<h3&gt;Post-incremento</h3&gt;";
$a = 5;
echo "Dovrebbe essere 5: " . $a++ . "<br>\n";
echo "Dovrebbe essere 6: " . $a . "<br>\n";

echo "<h3>Pre-incremento</h3>";
$a = 5;
echo "Dovrebbe essere 6: " . ++$a . "<br>\n";
echo "Dovrebbe essere 6: " . $a . "<br>\n";

echo "<h3>Post-decremento</h3>";
$a = 5;
echo "Dovrebbe essere 5: " . $a-- . "<br>\n";
echo "Dovrebbe essere 4: " . $a . "<br>\n";

echo "<h3>Pre-decremento</h3>";
$a = 5;
echo "Dovrebbe essere 4: " . --$a . "<br>\n";
echo "Dovrebbe essere 4: " . $a . "<br>\n";
?>


Operatori logici

Tabella 10-6. Operatori logici

EsempioNomeRisultato
$a and $bAndTRUE se entrambi $a e $b sono TRUE.
$a or $bOrTRUE se uno tra $a o $b è TRUE.
$a xor $bXorTRUE se uno tra $a o $b è TRUE, ma non entrambi.
! $aNotTRUE se $a non è TRUE.
$a && $bAndTRUE se entrambi $a e $b sono TRUE.
$a || $bOrTRUE se uno tra $a o $b è TRUE.

La ragione per le due differenti variazioni degli operatori "and" e "or" è che essi operano con differenti precedenze. (Vedere Precedenza degli operatori.)


Operatori di stringa

Ci sono due operatori di stringa. Il primo è l'operatore di concatenazione ('.'), che restituisce la concatenazione dei suoi argomenti a destra e a sinistra. Il secondo è l'operatore di assegnazione concatenata ('.='), che aggiunge alla fine dell'argomento sul lato destro l'argomento sul lato sinistro. Per favore consultare Operatori di assegnazione per maggiori informazioni.

$a = "Ciao ";
$b = $a . "Mondo!"; // ora $b contiene "Ciao Mondo!"

$a = "Ciao ";
$a .= "Mondo!";     // ora $a contiene "Ciao Mondo!"


Capitolo 11. Strutture di controllo

Qualsiasi script PHP è costituito da una serie di istruzioni. Una istruzione può essere un'assegnazione, una chiamata di funzione, un loop, una istruzione condizionale che non fa nulla (istruzione vuota). Le istruzioni terminano con un punto e virgola. Inoltre, le istruzioni si possono raggruppare in blocchi di istruzioni racchiudendole tra parentesi graffa. Un gruppo di istruzioni è, a sua volta, un'istruzione. Il presente capitolo descrive i differenti tipi di istruzioni.


if

Il costrutto if è una delle più importanti caratteristiche di qualsiasi linguaggio, incluso PHP. Permette l'esecuzione condizionata di frammenti di codice. La struttura di controllo if di PHP è simile a quella del linguaggio C:

if (espressione)
    istruzione

Come descritto nella sezione sulle espressioni, espressione restiruirà il suo valore booleano. Se espressione vale TRUE, PHP eseguirà istruzione, e se essa vale FALSE - la ignorerà. Più informazioni riguardo i valori valutati FALSE possono essere trovati nella sezione 'Conversione in booleano' .

L'esempio che segue visualizzerà a è maggiore di b se $a sarà maggiore di $b:

if ($a > $b)
    print "a è maggiore di b";

Spesso sarà necessario eseguire più di una istruzione condizionale. Naturalmente non è necessario, utilizzare una singola clausola if per ciascuna istruzione. Si possono raggruppare diverse istruzioni in un singolo gruppo di istruzioni. Per esempio, il codice che segue visualizzerà a è maggiore di b se $a è maggiore di $b, e successivamente assegnerà il valore della variabile $a alla variabile $b:

if ($a > $b) {
    print "a è maggiore di b";
    $b = $a;
}

Si possono annidare indefinitamente istruzioni if, la qual cosa fornisce piena flessibilità per l'esecuzione di istruzioni condizionali in diversi punti del programma.


else

Spesso è necessario eseguire un'istruzione se una proposizione è vera e un'altra istruzione se la proposizione è falsa. Per questo si usa la clausola else. else estende il costrutto if aggiungendo la possibilità di eseguire un'istruzione se l'espressione nel ramo if è FALSE. L'esempio che segue visualizzerà a è maggiore di b se $a è maggiore di $b e a NON è maggiore di b altrimenti:

if ($a > $b) {
    print "a è maggiore di b";
} else {
    print "a NON è maggiore di b";
}

Il ramo else viene eseguito solo se l'espressione nel ramo if è FALSE, e, nel caso ci fossero delle clausole elseif, solamente se le espressioni in esse contenute fossero anch'esse FALSE (vedere elseif).


elseif

elseif, come è facile intuire, è una combinazione di if ed else. Analogamente ad else, estende if aggiungendo la possibilità di eseguire un'altra istruzione nel caso in cui l'espressione contenuta nel ramo if sia FALSE. Però, a differenza di else, si eseguirà l'istruzione alternativa solamente se l'espressione contenuta nel ramo elseif sarà TRUE. L'esempio che segue, visualizzerà a è maggiore di b, a è uguale a b oppure a è minore di b:

if ($a > $b) {
    print "a è maggiore di b";
} elseif ($a == $b) {
    print "a è uguale a b";
} else {
    print "a è minore di b";
}

Nel medesimo blocco if possono essere presenti più di una clausola elseif. Verrà eseguita l'istruzione del primo ramo elseif la cui espressione sia TRUE. In PHP è possibile scrivere 'else if' (due parole) e il significato sarà lo stesso di 'elseif' (una sola parola). Il significato sintattico è leggermente differente (se si ha familiarità con il linguaggio C, esso ha lo stesso comportamento) però al lato pratico l'effetto è il medesimo.

L'istruzione di un ramo elseif verrà eseguita solo se l'espressione del ramo if e le espressioni dei rami elseif precedenti sono FALSE, e se l'espressione del ramo elseif è TRUE.


Sintassi alternativa per le strutture di controllo

PHP offre una sintassi alternativa per alcune delle sue strutture di controllo; vale a dire, if, while, for, foreach e switch. Fondamentalmente la sintassi alternativa consiste nel sostituire la prima parentesi graffa con il carattere "duepunti" (:) e la seconda parentesi graffa con endif;, endwhile;, endfor;, endforeach;, oppure endswitch;, rispettivamente.

<?php if ($a == 5): ?>
a è uguale a 5
<?php endif; ?>

Nell'esempio precedente, il blocco HTML "a è uguale a 5" è incluso nel ramo if scritto utilizzando la sintassi alternativa. Il blocco HTML verrà visualizzato solamente se $a è uguale a 5.

La sintassi alternativa si applica anche ad else ed elseif. Nell'esempio che segue si mostra come utilizzare la sintassi alternativa nel caso di un if con elseif ed else:

if ($a == 5):
    print "a è uguale a 5";
    print "...";
elseif ($a == 6):
    print "a è uguale a 6";
    print "!!!";
else:
    print "a non è nè 5 nè 6";
endif;

Vedere anche while, for, e if per ulteriori esempi.


while

Il ciclo while è la forma di ciclo più semplice tra quelle possibili in PHP. Si comporta come la sua controparte nel linguaggio C. La forma di base di un ciclo while è la seguente:

while (espressione) istruzione

Il significato di un ciclo while è semplice. Istruisce l'interprete PHP perchè esegua l'istruzione (o le istruzioni) in esso racchiuse, ripetutamente, fintanto che l'espressione contenuta nella clausola while ha valore TRUE. Il valore dell'espressione viene verificato ogni volta che il ciclo si ripete (iterazione), così che anche se il valore dell'espressione cambia durante l'esecuzione dell'istruzione, il ciclo non termina fino all'iterazione successiva. Ovviamente, se l'espressione nella clausola while ha valore FALSE dall'inizio, l'istruzione racchiusa nel blocco non verrà eseguita nemmeno una volta.

Come nel caso della struttura di controllo if, si possono raggruppare più istruzioni nello medesimo ciclo while racchiudendo le istruzioni in parentesi graffa, oppure utilizzando la sintassi alternativa:

while (espressione): istruzione ... endwhile;

Gli esempi seguenti sono identici e entrambi visualizzano i numeri da 1 a 10:

/* esempio 1 */

$i = 1;
while ($i <= 10) {
    print $i++;  /* Il valore visualizzato è il valore della
                    variabile $i prima dell'incremento
                    (post-incremento) */
}

/* esempio 2 */

$i = 1;
while ($i <= 10):
    print $i;
    $i++;
endwhile;


do..while

Il ciclo do..while è simile al ciclo while, con l'unica differenza che il valore dell'espressione viene controllato alla fine di ogni iterazione anzichè all'inizio. La differenza più importante rispetto a while è che la prima iterazione di un blocco do..while verrà sempre eseguita (il valore dell'espressione viene controllato alla fine del ciclo), mentre non sarà necessariamente eseguito in un ciclo while (il valore dell'espressione viene controllato all'inizio del ciclo, e se tale valore è FALSE dall'inizio, l'esecuzione del ciclo termina immediatamente).

È ammessa una sola sintassi per il ciclo do..while:

$i = 0;
do {
   print $i;
} while ($i>0);

Il ciclo precedente verrà eseguito un'unica volta, dal momento che alla prima iterazione, quando si controlla l'espressione, il suo valore sarà FALSE ($i non è maggiore di 0) e il ciclo di esecuzioni, termina.

Chi ha utilizzato il linguaggio C conosce probabilmente un'altro modo di utilizzare il ciclo do..while, che permette di terminare l'esecuzione delle istruzioni durante l'esecuzione stessa, utilizzando do..while(0), e usando l'istruzione break. Il codice che segue esemplifica questa possibilità:

do {
    if ($i < 5) {
        print "i non è abbastanza grande";
        break;
    }
    $i *= $factor;
    if ($i < $minimum_limit) {
        break;
    }
    print "i è ok";

     ...processa i...

} while(0);

Non vi preoccupate se l'esempio non è sufficientemente chiaro. Si possono scrivere ottimi programmi PHP anche senza far ricorso a questa 'possibilità'.


for

Il ciclo for è il ciclo più complesso tra quelli disponibili in PHP. Si comporta come la sua controparte nel linguaggio C. La sintassi di un clico for è:

for (espressione1; espressione2; espressione3) istruzione

Il valore della prima espressione (espressione1) viene verificato (eseguito) una sola volta incondizionatamente all'inizio del ciclo.

Ad ogni iterazione, si controlla il valore di espressione2. Se è TRUE, il ciclo prosegue e viene eseguita l'istruzione (o le istruzioni) contenuta nel blocco; se è FALSE, l'esecuzione del ciclo termina.

Al termine di ogni iterazione, si verifica (si esegue) il valore di espressione3.

Le due espressioni possono anche non essere presenti. Se non esiste espressione2 significa che il ciclo deve essere eseguito indefinitamente (PHP considera implicitamente che il suo valore è TRUE, come in C). Questa possibilità in fondo non è utile come può sembrare perchè obbliga a terminare il ciclo utilizzando l'istruzione break invece di utilizzare le espressioni booleane del ciclo for .

Si considerino gli esempi seguenti. In ciascun caso si visualizzeranno i numeri da 1 a 10:

/* esempio 1 */

for ($i = 1; $i <= 10; $i++) {
    print $i;
}

/* esempio 2 */

for ($i = 1;;$i++) {
    if ($i > 10) {
        break;
    }
    print $i;
}

/* esempio 3 */

$i = 1;
for (;;) {
    if ($i > 10) {
        break;
    }
    print $i;
    $i++;
}

/* esempio 4 */

for ($i = 1; $i <= 10; print $i, $i++) ;

Naturalmente il primo esempio sembra il migliore (o forse il quarto), ma l'uso del ciclo for senza espressioni può essere utile in molti casi.

PHP offre una sintassi alternativa (con i "punto e virgola") per i cicli for.

for (espressione1; espressione2; espressione3): istruzione; ...; endfor;

Alcuni linguaggi permettono l'uso della struttura di controllo foreach per attraversare un array o una tabella hash. PHP 3 non premette l'uso di tale ciclo mentre PHP 4 si (vedere foreach). In PHP 3 è possibile combinare while con la funzione list() e each() per ottenere la stessa funzionalià. Si veda la documentazione di queste funzioni per ulteriori esempi.


foreach

PHP 4 (non PHP 3) permette l'uso della struttura di controllo foreach, alla stessa maniera del linguaggio Perl e altri. Ciò semplicemente fornisce una facile metodo per attraversare un array. Esistono due possibili notazioni sintattiche; la seconda è un'utile estensione della prima:

foreach(array_expression as $value) istruzione
foreach(array_expression as $key => $value) istruzione

La prima attraversa l'array dato da array_expression. Ad ogni ciclo, si assegna il valore dell'elemento corrente a $value e il puntatore interno avanza di una posizione (in modo tale che al ciclo successivo l'elemento corrente sarà il successivo elemento dell'array).

La seconda esegue lo stesso ciclo con la differenza che il valore dell'indice corrente viene assegnato ad ogni ciclo, alla variabile $key.

Nota: All'inizio dell'esecuzione di un ciclo foreach il puntatore interno viene automaticamente posizionato nella prima posizione. Questo significa che non è necessario utilizzare la funzione reset() prima di un ciclo foreach.

Nota: È importante notare che foreach opera su una copia dell'array, non sull'array stesso, pertanto il puntatore dell'array originale non viene modificato come accade utilizzando la funzione each() e le modifiche agli elementi dell'array non appaiono nell'array originale.

Nota: foreach non offre la possibilità di annullare la generazione di messaggi d'errore utilizzando il carattere '@'.

Avete probabilmente notato che i due cicli seguenti sono identici da un punto di vista funzionale:

reset ($arr);
while (list(, $value) = each ($arr)) {
    echo "Valore: $value<br>\n";
}

foreach ($arr as $value) {
    echo "Valore: $value<br>\n";
}

Allo stesso modo i due cicli seguenti sono identici:

reset ($arr);
while (list($key, $value) = each ($arr)) {
    echo "Chiave: $key; Valore: $value<br>\n";
}

foreach ($arr as $key => $value) {
    echo "Chiave: $key; Valore: $value<br>\n";
}

Di seguito, altri esempi per mostrare possibili utilizzi:

/* esempio 1 foreach: solo il valore */

$a = array (1, 2, 3, 17);

foreach ($a as $v) {
   print "Valore corrente di \$a: $v.\n";
}

/* esempio 2 foreach: valore (con la chiave stampata) */

$a = array (1, 2, 3, 17);

$i = 0; /* solo per un proposito illustrativo */

foreach($a as $v) {
    print "\$a[$i] => $v.\n";
    $i++;
}

/* esempio 3 foreach: chiave e valore */

$a = array (
    "uno" => 1,
    "due" => 2,
    "tre" => 3,
    "diciassette" => 17
);

foreach($a as $k => $v) {
    print "\$a[$k] => $v.\n";
}

/* esempio 4 foreach: array multidimensionali */

$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";

foreach($a as $v1) {
    foreach ($v1 as $v2) {
        print "$v2\n";
    }
}

/* esempio 5 foreach: array dinamici */

foreach(array(1, 2, 3, 4, 5) as $v) {
    print "$v\n";
}


break

break termina l'esecuzione di una struttura for, foreach while, do..while o switch.

break accetta un argomento opzionale che definisce, nel caso di cicli annidati, il livello del ciclo che è da interrompere.

$arr = array ('uno', 'due', 'tre', 'quattro', 'stop', 'cinque');
while (list (, $val) = each ($arr)) {
    if ($val == 'stop') {
        break;    /* Qui si può anche usare 'break 1;'. */
    }
    echo "$val<br>\n";
}

/* Uso dell'argomento opzionale. */

$i = 0;
while (++$i) {
    switch ($i) {
    case 5:
        echo "At 5<br>\n";
        break 1;  /* Interrompe solo awitch. */
    case 10:
        echo "At 10; quitting<br>\n";
        break 2;  /* Interrompe switch e while. */
    default:
        break;
    }
}


continue

continue si utilizza per interrompere l'esecuzione del ciclo corrente e continuare con l'esecuzione all'inizio del ciclo successivo.

continue accetta un argomento numerico opzionale che definisce, nel caso di cicli annidati, il numero di cicli da interrompere e da cui iniziare l'esecuzione dell'iterazione successiva.

while (list ($key, $value) = each ($arr)) {
    if (!($key % 2)) { // salta odd members
        continue;
    }
    do_something_odd ($value);
}

$i = 0;
while ($i++ < 5) {
    echo "Esterno<br>\n";
    while (1) {
        echo "&nbsp;&nbsp;Centrale<br>\n";
        while (1) {
            echo "&nbsp;&nbsp;Interno<br>\n";
            continue 3;
        }
        echo "Questo non sarà mai stampato.<br>\n";
    }
    echo "Nemmeno questo.<br>\n";
}


switch

switch è simile a una serie di if sulla stessa espressione. In molti casi può essere necessario confrontare una variabile (o espressione) con differenti valori ed eseguire un differente blocco di istruzioni a seconda del valore di detta variabile. Questo è esattamente quello che fa la struttura di controllo switch.

Gli esempi seguenti mostrano due maniere differenti di scrivere la stessa cosa, uno utilizzando una serie di if, l'altro utilizzando switch :

if ($i == 0) {
    print "i è uguale a 0";
}
if ($i == 1) {
    print "i è uguale a 1";
}
if ($i == 2) {
    print "i è uguale a 2";
}

switch ($i) {
    case 0:
        print "i è uguale a 0";
        break;
    case 1:
        print "i è uguale a 1";
        break;
    case 2:
        print "i è uguale a 2";
        break;
}

È importante comprendere esattamente come viene eseguita la clausola switch per evitare errori. Un'istruzione switch esegue linea dopo linea le istruzioni in essa contenuta. All'inizio non viene eseguito alcun codice. Solamente quando incontra una clausola case il cui valore è uguale al valore della viariabile, PHP inizia ad eseguire le istruzioni contenute nel blocco case. PHP continua l'esecuzione delle istruzioni fino alla termine del blocco switch, o quando incontra un'istruzione break. Se non esiste alcuna istruzione break al termine di un blocco case PHP continuerà l'esecuzione delle istruzioni del blocco case successivo. Per esempio:

switch ($i) {
    case 0:
        print "i è uguale a 0";
    case 1:
        print "i è uguale a 1";
    case 2:
        print "i è uguale a 2";
}

In questo caso se $i è uguale a 0, PHP eseguirà tutte le istruzioni contenute nei blocchi case. Se $i è uguale a 1, PHP eseguirà le istruzioni degli ultimi due blocchi case e solamente se $i è uguale a 2 otterremo il risultato voluto e si visualizzerà solo '$i è uguale a 2'. Pertanto è importante non dimenticare l'istruzione break (anche se in alcuni casi potrà essere necessario non utilizzarla).

In un'istruzione switch, la condizione in parentesi viene valutata una sola volta e il risultato viene confrontato con ciascun ramo case. Utilizzando elseif, la condizione viene valutata una seconda volta. Se tale condizione è più complessa di un semplice confronto e/o è in un ciclo piuttosto pesante, l'uso di switch dovrebbe garantire un minor tempo di esecuzione.

Un blocco case può anche non contenere istruzioni, nel qual caso il controllo passa semplicemente al successivo blocco case.

switch ($i) {
    case 0:
    case 1:
    case 2:
        print "i è minore di 3 ma non negativo";
        break;
    case 3:
        print "i è 3";
}

Un blocco case speciale è il il blocco case di default. Uguaglia tutte le condizioni non uguagliate nei blocchi case precedenti e dev'essere l'ultimo blocco case. Per esempio:

switch ($i) {
    case 0:
        print "i è uguale a 0";
        break;
    case 1:
        print "i è uguale a 1";
        break;
    case 2:
        print "i è uguale a 2";
        break;
    default:
        print "i è diverso da 0, 1 o 2";
}

L'espressione in un ramo case può essere qualsiasi espressione il cui valore sarà di tipo intero, decimale, numerico e stringa. Array e oggetti (objects) non sono ammessi a meno che non siano dereferenziati a un tipo di dato semplice tra quelli precedentemente elencati.

Come per altre strutture di controllo è possibile utilizzare una sintassi alternativa. Si veda Sintassi alternativa per le strutture di controllo per ulteriori esempi.

switch ($i):
    case 0:
        print "i è uguale a 0";
        break;
    case 1:
        print "i è uguale a 1";
        break;
    case 2:
        print "i è uguale a 2";
        break;
    default:
        print "i è diverso da 0, 1 o 2";
endswitch;


declare

Il costrutto declare si usa per definire direttive di esecuzione per blocchi di istruzioni. La sintassi è simile alla sintassi di altre strutture di controllo:

declare (direttiva) istruzione

La sezione direttiva permette di impostare il comportamento del blocco declare . Attualmente è riconosciuta una sola direttiva: la direttiva ticks. (Fare riferimento più in basso per ulteriori informazioni relative alla direttiva ticks)

Verrà eseguita la parte istruzione del blocco declare - come verrà eseguita e quali effetti collaterali emergeranno durante l'esecuzione potrà dipendere dalla direttiva impostata nel blocco direttiva.


Ticks

Un tick è un evento che si verifica per ogni N istruzioni di basso livello eseguite dal parser all'interno del blocco declare. Il valore per N viene specificato usando ticks=N all'interno della sezione direttiva del blocco declare.

L'evento (o gli eventi) che si verifica su ogni tick è specificato usando register_tick_function(). Vedere l'esempio più in basso per ulteriori dettagli. Notare che può verificarsi più di un evento per ogni tick.

Esempio 11-1. Segue una sezione di codice PHP

<?php
// Una funzione che registra il tempo quando viene chiamata
function profile ($dump = FALSE)
{
    static $profile;

    // Restituisce il tempo immagazinato in $profile, successivamente lo cancella
    if ($dump) {
        $temp = $profile;
        unset ($profile);
        return ($temp);
    }

    $profile[] = microtime ();
}

// Imposta un tick handler
register_tick_function("profile");

// Inizializza la funzione prima del blocco declare
profile ();

// Esegue un blocco di codice, attraverso un tick ogni seconda istruzione
declare (ticks = 2) {
    for ($x = 1; $x < 50; ++$x) {
        echo similar_text (md5($x), md5($x*$x)), "<br />";
    }
}

// Mostra i dati immagazionati nel profilo
print_r (profile (TRUE));
?>
L'esempio descrive il codice PHP all'interno del blocco 'declare', registrando il tempo in cui è stata eseguita ogni seconda istruzione di basso livello. Questa informazione può poi essere usata per trovare le aree lente all'interno di particolari segmenti di codice. Questo processo può essere ottimizzato usando altri metodi: usando i tick è più conveniente e facile da implementare.

I tick sono ben adeguati per il debugging, l'implementazione di semplici multitasking, backgrounded I/O e molti altri compiti.

Vedere anche register_tick_function() e unregister_tick_function().


return

Se viene chiamato all'interno di una funzione, l'istruzione return() termina immediatamente l'esecuzione della funzione corrente, e restituisce il suo argomento come valore della funzione chiamata. return() terminerà anche l'esecuzione di un'istruzione eval() o di un file di script.

Se viene chiamato in uno scope globale, allora verrà terrminata l'esecuzione del file di script corrente. Nel caso in cui il file di script corrente sia un file chiamato da include() o require(), il controllo viene passato al file chiamante. Ciononostante, se il file di script corrente è un file chiamato da include(), allora il valore dato da return() verrà restituito come valore della chiamata include(). Se viene chiamato return() all'interno del file di script principale, allora l'esecuzione dello script terminerà. Se il file di script corrente è stato nominato da auto_prepend_file o auto_append_file con le opzioni di configurazione nel file di configurazione, allora l'esecuzione di quello script termina.

Per maggiori informazioni, consultare Valori restituiti.

Nota: Notate che poichè return() è un costrutto di linguaggio e non una funzione, le parentesi che circondano i suoi argomenti non sono richieste --infatti, è più comune evitarle che usarle, nonostante ciò non c'è motivo di preferire un modo o l'altro.


require()

L'istruzione require() include e valuta il file specifico.

require() include e valuta uno specifico file. Informazioni dettagliate su come funziona quest'inclusione sono descritte nella documentazione di include().

require() e include() sono identiche in ogni senso eccetto per come esse trattano gli errori. include() produce un Warning mentre require() restituisce un Fatal Error. In altre parole, non esitate ad usare require() se volete che un file mancante fermi l'esecuzione della pagina. include() non si comporta in questo modo, lo script continuerà nonostante tutto. Assicuratevi di avere un appropriato include_path impostato a dovere.

Esempio 11-2. Esempio di base con require()

<?php

require 'prepend.php';

require $qualche_file;

require ('qualche_file.txt');

?>

Vedere la documentazione di include() per più esempi.

Nota: Prima di PHP 4.0.2, si applica la seguente logica: require() tenterà sempre di leggere il file chiamato, anche se la riga su cui si trova non verrà mai eseguita. L'istruzione condizionale non avrà effetto su require(). Comunque, se la riga su cui si verifica require() non viene eseguita, non sarà eseguito nemmeno il codice del file incluso. Similmente, le strutture cicliche non avranno effetto sul comportamento di require(). Sebbene il codice contenuto nel file incluso è ancora soggetto a ciclo, require() stesso si verifica solo una volta.

Vedere anche include(), require_once(), include_once(), eval(), file(), readfile(), virtual() e include_path.


include()

L'istruzione include() include e valuta il file specificato.

La documentazione seguente si applica anche a require(). I due costrutti sono identici in ogni aspetto eccetto per come essi trattano gli errori. include() produce un Warning mentre require() restituisce un Fatal Error. In altre parole, usate require() se volete che un file mancante fermi l'esecuzione della pagina. include() non si comporta in questo modo, lo script continuerà nonostante tutto. Assicuratevi di avere un appropriato include_path impostato a dovere.

Quando un file viene incluso, il codice che esso contiene eredita lo scope delle variabili della riga in cui si verifica l'inclusione. Qualsiasi variabile disponibile in quella riga nella chiamata al file sarà disponibile all'interno del file chiamato, da quel punto in avanti.

Esempio 11-3. Esempio di base con include()

vars.php
<?php

$colore = 'verde';
$frutto = 'mela';

?>

test.php
<?php

echo "Una $frutto $colore"; // Una

include 'vars.php';

echo "Una $frutto $colore"; // Una mela verde

?>

Se l'inclusione si verifica dentro una funzione all'interno del file chiamato, allora tutto il codice contenuto nel file chiamato si comporterà come se esso sia stato definito all'interno di una funzione. Così, esso seguirà lo scope delle variabili di quella funzione.

Esempio 11-4. Inclusione all'interno di funzioni

<?php

function foo()
{
global $frutto;

    include 'vars.php';

    echo "Una $frutto $colore";
}

/* vars.php è nello scope di foo() così    *
 * $colore NON è disponibile fuori di      *
 * questo scope. $frutto si perchè è stato *
 * dichiarato globale.                     */

foo();                        // Una mela verde
echo "Una $frutto $colore";   // Una mela

?>

Quando un file viene incluso, il parsing esce dalla modalità PHP e entra in modalità HTML all'inizio del file incluso, e riprende alla fine. Per questa ragione, qualunque codice all'interno del file incluso che dovrebbe essere eseguito come codice PHP deve essere incluso all'interno dei tag PHP validi di apertura e chiusura.

Se "URL fopen wrappers" nel PHP sono abilitati (come nella configurazione di default), potete specificare il file da includere usando un URL (via HTTP) invece che un percorso locale. Se il server chiamato interpreta il file incluso come codice PHP, le variabili possono essere passate al file incluso usando una stringa di richiesta URL come con l'utilizzo di HTTP GET. Non è proprio parlare della stessa cosa includere il file e averlo ereditato dallo scope di variabili del file chiamante; lo script è stato attualmente eseguito su un server remoto e il risultato è poi stato incluso nello script locale.

Esempio 11-5. include() attraverso HTTP

<?php

/* Questo esempio assume che www.example.com è configurato per eseguire file *
 * .php e non file .txt. Anche, 'Funziona' qui significa che le variabili    *
 * $foo e $bar sono disponibili all'interno del file incluso.                */

// Non funzionerà; file.txt non è stato trattato da www.example.com come PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';

// Non funzionerà; cercare un file chiamato'file.php?foo=1&bar=2' nel
// filesystem locale.
include 'file.php?foo=1&bar=2';

// Funziona.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo = 1;
$bar = 2;
include 'file.txt';  // Funziona.
include 'file.php';  // Funziona.

?>
Vedere anche Remote files, fopen() e file() per informazioni correlate.

Poichè include() e require() sono speciali costrutti di linguaggio, dovete includerli all'interno di blocchi di istruzioni se si trovano in un blocco condizionale.

Esempio 11-6. include() e i blocchi condizionali

<?php

// Questo NON VA BENE e non funzionerà come desiderato.
if ($condizione)
    include $file;
else
    include $un_altro;


// Questo è CORRETTO.
if ($condizione) {
    include $file;
} else {
    include $un_altro;
}

?>

Trattamento dei valori restituiti: È possibile eseguire un'istruzione return() in un file incluso per terminare l'esecuzione di quel file e restituirlo allo script che l'ha chiamato. È anche possibile restituire valori dai file inclusi. Potete prendere il valore di una chiamata di inclusione come fareste con una normale funzione.

Nota: In PHP 3, return potrebbe non apparire in un blocco a meno che esso sia un blocco di funzione, nel qual caso return() si applica a quella funzione e non all'intero file.

Esempio 11-7. include() and the return() statement

return.php
<?php

$var = 'PHP';

return $var;

?>

noreturn.php
<?php

$var = 'PHP';

?>

testreturns.php
<?php

$foo = include 'return.php';

echo $foo; // stampa 'PHP'

$bar = include 'noreturn.php';

echo $bar; // stampa 1

?>

$bar ha valore 1 perchè l'inclusione è stata eseguita con successo. Notare la differenza tra gli esempi sopra. Il primo usa return() all'interno di un file incluso mentre l'altro no. Pochi altri modi di "includere" file in variabili sono con fopen(), file() o usando include() insieme con Output Control Functions.

Vedere anche require(), require_once(), include_once(), readfile(), virtual(), e include_path.


require_once()

L'istruzione require_once() include e valuta il file specificato durante l'esecuzione dello script. È un comportamento simile all'istruzione require(), con la sola differenza che se il codice di un file è stato già incluso, esso non sarà incluso nuovamente. Vedere la documentazione di require() per maggiori informazioni su come funziona quest'istruzione.

require_once() dovrebbe essere usato nei casi dove lo stesso file potrebbe essere incluso e valutato più di una volta durante una particolare esecuzione di uno script, e volete essere sicuri che esso sia incluso esattamente una volta per evitare problemi con la ridefinizione di funzioni, riassegnazione di valori a variabili, etc.

Per esempi sull'utilizzo di require_once() e include_once(), consultare il codice PEAR incluso nell'ultima distribuzione del codice sorgente di PHP.

Nota: require_once() è stato aggiunto in PHP 4.0.1pl2

Vedere anche: require(), include(), include_once(), get_required_files(), get_included_files(), readfile(), e virtual().


include_once()

L'istruzione include_once() include e valuta il file specificato durante l'esecuzione dello script. È un comportamento simile all'istruzione include(), con la sola differenza che se il codice di un file è stato già incluso, esso non sarà incluso nuovamente. Come suggerisce il nome, esso sarà incluso solo una volta.

include_once() dovrebbe essere usato nei casi dove lo stesso file potrebbe essere incluso e valutato più di una volta durante una particolare esecuzione di uno script, e volete essere sicuri che esso sia incluso esattamente una volta per evitare problemi con la ridefinizione di funzioni, riassegnazione di valori a variabili, etc.

Per maggiori esempi sull'utilizzo di require_once() e include_once(), consultare il codice PEAR incluso nell'ultima distribuzione del codice sorgente di PHP.

Nota: include_once() è stato aggiunto in PHP 4.0.1pl2

Vedere anche include(), require(), require_once(), get_required_files(), get_included_files(), readfile() e virtual().


Capitolo 12. Funzioni

Funzioni definite dall'utente

Una funzione può essere definita usando la seguente sintassi:

function foo ($arg_1, $arg_2, ..., $arg_n)
{
    echo "Funzione di esempio.\n";
    return $retval;
}

All'interno di una funzione può apparire qualunque codice PHP valido, persino altre funzioni e definizioni di classe.

In PHP 3, le funzioni devono essere definite prima di essere referenziate. Non esiste nessun requisito in PHP 4.

PHP non supporta l'overloading di funzioni, non è possibile indefinire o ridefinire funzioni precedentemente dichiarate.

PHP 3 non supporta un numero variabile di argomenti per le funzioni, sebbene siano supportati gli argomenti di default (vedere Argomenti con valori di default per maggiori informazioni). PHP 4 li supporta entrambi: vedere Liste di argomenti a lunghezza variabile e i riferimenti alle funzioni func_num_args(), func_get_arg() e func_get_args() per maggiori informazioni.


Argomenti delle funzioni

L'informazione può essere passata alle funzioni tramite la lista degli argomenti, che sono liste di variabili e/o costanti delimitati dalla virgola.

PHP supporta il passaggio di argomenti per valore (comportamento di default), il passaggio per riferimento, e i valori di default degli argomenti. Le liste di argomenti di lunghezza varabile sono supportate solo in PHP 4 e successivi; vedere Liste di argomenti a lunghezza variabile e i riferimenti alle funzioni func_num_args(), func_get_arg(), e func_get_args() per maggiori informazioni. Un effetto simile può essere ottenuto in PHP 3 passando una array di argomenti alla funzione.

function prende_array($input)
{
    echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}


Costruire argomenti passati per riferimento

Di default, gli argomenti della funzione sono passati per valore (così se cambiate il valore dell'argomento all'interno della funzione , esso non cambierà fuori della funzione). Se volete permettere ad una funzione di modificare i suoi argomenti, dovete passarli per riferimento.

Se volete che una argomento sia passato sempre per riferimento ad una funzione, dovete anteporre un ampersand (&) al nome dell'argomento nella definizione della funzione:

function aggiungi_qualcosa(&$string)
{
    $string .= 'e qualche altra cosa.';
}
$str = 'Questa è una stringa, ';
aggiungi_qualcosa($str);
echo $str;    // l'output sarà 'Questa è una stringa, e qualche altra cosa.'


Valori predefiniti degli argomenti

Una funzione può definire valori predefiniti in stile C++ per argomenti scalari come segue:

function fare_il_caffe ($tipo = "cappuccino")
{
    return "Sto facendo una tazza di $tipo.\n";
}
echo fare_il_caffe ();
echo fare_il_caffe ("espresso");

L'output dal frammento di sopra è:
Sto facendo una tazza di cappuccino.
Sto facendo una tazza di espresso.

Il valore predefinito deve essere un'espressione costante, non (per esempio) una variabile o un membro di classe.

Da notare che quando vengono usati argomenti predefiniti, qualunque argomento predefinito dovrebbe essere a destra degli argomenti non-predefiniti; diversamente, le cose non funzioneranno come ci si aspetti. Si consideri il seguente frammento di codice:

function fare_lo_yogurt ($tipo = "yogurt", $gusto)
{
    return "Fare una vaschetta di $tipo a $gusto.\n";
}

echo fare_lo_yogurt ("fragola");   // non funziona come si aspetta

L'output dell'esempio di sopra è:
Warning: Missing argument 2 in call to fare_lo_yogurt() in
/usr/local/etc/httpd/htdocs/php3test/functest.html on line 41
Fare una vaschetta di fragola a.

Ora, si confronti il codice di sopra con questo:

function fare_lo_yogurt ($gusto, $tipo = "yogurt")
{
    return "Fare una vaschetta di $tipo a $gusto.\n";
}

echo fare_lo_yogurt ("fragola");   // funziona come si aspetta

L'output di questo esempio è:
Fare una vaschetta di yogurt a fragola.


Liste di argomenti a lunghezza variabile

PHP 4 ha il supporto per le liste di argomenti a lunghezza variabile nelle funzioni definite dall'utente. Ciò è realmente abbastanza semplice, usando le funzioni func_num_args(), func_get_arg(), e func_get_args().

Non è richiesta una speciale sintassi, e le liste di argomenti possono ancora essere provviste esplicitamente con le definizioni di funzioni e si comporteranno normalmente.


Valori restituiti

I valori vengono restituiti usando l'istruzione opzionale return. Può essere restituito qualsiasi tipo, incluse liste ed oggetti. Ciò provoca l'interruzione dell'esecuzione della funzione immediatamente e la restituzione del controllo alla linea da cui è stata chiamata. Vedere return() per maggiori informazioni.

function quadrato ($num)
{
    return $num * $num;
}
echo quadrato (4);   // L'output è '16'.

Non possono essere restituiti valori multipli da una funzione, ma risultati simili possono essere ottenuti restituendo una lista.

function numeri_piccoli()
{
    return array (0, 1, 2);
}
list ($zero, $uno, $due) = numeri_piccoli();

Per restituire un riferimento da una funzione, è necessario usare l'operatore di passaggio per riferimento & in entrambe le dichiarazioni di funzioni e quando viene assegnato il valore restituito ad una variabile:

function &restituisce_riferimento()
{
    return $un_riferimento;
}

$nuovo_riferimento =& restituisce_riferimento();

Per maggiori informazioni sui riferimenti, consultare References Explained.


old_function

L'istruzione old_function permette di dichiarare una funzione usando una sintassi identica a PHP/FI2 (eccetto il dover sostituire 'function' con 'old_function'.

Questa è una caratteristica deprecata, e dovrebbe essere usata solo da convertitori PHP/FI2->PHP 3.

Avvertimento

Le funzioni dichiarate come old_function non possono essere chiamate da codice interno di PHP. Tra le altre cose, questo significa che non possono essere usate in funzioni come usort(), array_walk(), e register_shutdown_function(). Si può aggirare questa limitazione scrivendo una funzione contenitore (nel normale stile di PHP 3) per chiamare la old_function.


Funzioni variabili

PHP supporta il concetto di funzioni variabili. Ciò significa che se un nome di variabile ha le parentesi accodate ad esso, PHP cercherà una funzione con lo stesso nome del valore della variabile, e cercherà di eseguirla. Tra le altre cose, ciò puo essere usato per implementare delle callbacks, tabelle di funzioni e così via.

Le funzioni variabili non funzionano con costrutti di linguaggio come echo(), unset(), isset(), empty() e include(). Ad ogni modo, il costrutto print() è un'eccezione e funzionerà. Questa è una delle maggiori differenze tra le funzioni PHP e i costrutti di linguaggio.

Esempio 12-1. Esempio di funzioni variabili

<?php
function foo()
{
    echo "In foo()<br>\n";
}

function bar($arg = '')
{
    echo "In bar(); l'argomento era '$arg'.<br>\n";
}

$func = 'foo';
$func();
$func = 'bar';
$func('test');
?>

Vedere anche variabili variabili e function_exists().


Capitolo 13. Classi e Oggetti

Classi

Una classe è una collezione di variabili e funzioni che utilizzano queste variabili. Una classe si definisce usando la seguente sintassi:

<?php
class Cart
{
    var $items;  // Articoli nel carrello
   
    // Aggiunge $num articoli di $artnr nel carrello
 
    function add_item ($artnr, $num)
    {
        $this->items[$artnr] += $num;
    }
   
    // Prende $num articoli di $artnr e li rimuove dal carrello
 
    function remove_item ($artnr, $num)
    {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } else {
            return false;
        }   
    }
}
?>

Il codice definisce una classe chiamata Cart composta da un array associativo che archivia gli articoli nel carrello e due funzioni per aggiungere e rimuovere gli articoli dal carrello stesso.

Avvertimento

NON spezzate una definizione di classe in più file o in più blocchi PHP. Il seguente codice non funziona:

<?php
class test {
?>
<?php
    function test() {
        print 'OK';
    }
}
?>

Le seguenti note cautelative sono valide per PHP 4.

Attenzione

Il nome stdClass è usato esclusivamente da Zend ed è riservato. Non è quindi possibile creare una classe chiamata stdClass in PHP.

Attenzione

I nomi di funzione __sleep e __wakeup sono riservati e magici nelle classi PHP. Non è possibile creare funzioni con questi nomi nelle classi definite dall'utente, a meno che non sia desiderata la funzionalità magica connessa a questi nomi. Si veda sotto per avere più informazioni.

Attenzione

PHP riserva tutti i nomi di funzione che iniziano con __ a funzioni magiche. Si suggerisce di non usare nomi di funzioni che utilizzano con i caratteri __ in PHP a meno che non si desideri implementare una funzionalità magica.

In PHP 4, sono permesse inizializzazioni di variabili con valori costanti solamente grazie all'uso di var. Per inizializzare variabili con valori non-costanti, bisogna creare una funzione d'inizializzazione che è chiamata automaticamente all'istanziazione di un oggetto da una classe. Questo tipo di funzione si chiama costruttore (vedi sotto).

<?php
/* questo non funziona in PHP 4. */
class Cart
{
    var $todays_date = date("Y-m-d");
    var $name = $firstname;
    var $owner = 'Fred ' . 'Jones';
    var $items = array("VCR", "TV");
}

/* Questo è corretto. */
class Cart
{
    var $todays_date;
    var $name;
    var $owner;
    var $items;

    function Cart()
    {
        $this->todays_date = date("Y-m-d");
        $this->name = $GLOBALS['firstname'];
        /* etc ... */
    }
}
?>

Le classi sono tipi del linguaggio, e sono modelli per variabili reali. Per creare una variabile oggetto si usa l'operatore new.

<?php
$cart = new Cart;
$cart->add_item("10", 1);

$another_cart = new Cart;
$another_cart->add_item("0815", 3);
?>

Il codice sopra, genera gli oggetti $cart e $another_cart, dalla classe Cart. La funzione add_item() dell'oggetto $cart è chiamata per aggiungere una ricorrenza dell'articolo numero 10 a $cart. Ad $another_cart sono aggiunte 3 ricorrenze dell'articolo numero 0815.

Sia $cart che $another_cart dispongono delle funzioni add_item(), remove_item() e della variabile $items, ma per ogni oggetto queste sono funzioni e variabili sono distinte. Potete pensare agli oggetti come a qualcosa di simile alle directories di un filesystem. In un filesystem si possono avere due diversi files README.TXT, purchè siano in directories differenti. Così come in un filesystem dovete digitare il nome (percorso) completo per raggiungere un determinato file partendo da una directory toplevel, così dovete specificare il nome completo di una funzione o variabile che desiderate richiamare da un oggetto. Per PHP, la directory toplevel è il namespace globale dell'oggetto ed il separatore del pathname (/) è ->. Così $cart->items e $another_cart->items sono due diverse variabili che differiscono per il nome. Si noti che la variabile si chiama $cart->items, e non $cart->$items, questo perchè le variabili il PHP si scrivono con un unico simbolo di dollaro.

<?php
// corretto con un singolo $
$cart->items = array("10" => 1); 

// non valido, perchè $cart->$items diventa $cart->""
$cart->$items = array("10" => 1);

// corretto, ma non sempre può funzionare:
// $cart->$myvar diventa $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);  
?>

Quando si definisce una classe, non è possibile prevedere quale nome avrà l'oggetto istanziato nel programma. Quando la classe Cart è stata scritta, non si poteva prevedere che l'oggetto istanziato da essa si sarebbe potuto chiamare $cart o $another_cart. Quindi non è possibile scrivere $cart->items all'interno della classe Cart in fase di progettazione. Per poter accedere alle funzioni e alle variabili interne di una classe perciò si usa la pseudo-variabile $this che può essere letta come 'la mia\il mio' o 'di questo oggetto'. Quindi, '$this->items[$artnr] += $num' può essere letto come 'aggiungi $num al contatore $artnr al del mio array degli articoli' o 'aggiungi $num al contatore $artnr dell'array degli articoli di questo oggetto'.

Nota: Ci sono molte utili funzioni per manipolare classi ed oggetti. Se desiderate conoscerle potete dare un'occhiata alle Class/Object Functions


extends

Spesso si ha bisogno di avere classi con variabili e funzioni simili ad altre classi. É buona norma definire una classe in modo generico, sia per poterla riutilizzare spesso, sia per poterla adattare a scopi specifici.Per facilitare questa operazione, è possibile generare classi per estensione di altre classi. Una classe estesa o derivata ha tutte le variabili e le funzioni della classe di base (questo fenomeno è chiamato 'eredità', anche se non muore nessuno) più tutto ciò che viene aggiunto dall'estensione. Non è possibile che una sottoclasse, ridefinisca variabili e funzioni di una classe madre. Una classe estesa dipende sempre da una singola classe di base: l'eredità multipla non è supportata. Le classi si estendono usando la parola chiave 'extends'.

<?php
class Named_Cart extends Cart
{
    var $owner;
  
    function set_owner ($name)
    {
        $this->owner = $name;
    }
}
?>

Qui viene definita una classe Named_Cart che ha tutte le funzioni e variabili di Cart più la variabile $owner e la funzione set_owner(). Viene creato un carrello con nome con il metodo usato in precedenza, in più la classe estesa permette di settare o leggere il nome del carrello. Si possono usare variabili e funzioni sia di Cart che della sua estensione:

<?php
$ncart = new Named_Cart;    // Crea un carrello con nome
$ncart->set_owner("kris");  // Assegna il nome al carrello
print $ncart->owner;        // stampa il nome del proprietario
$ncart->add_item("10", 1);  // (funzionalità ereditata da Cart)
?>

La relazione mostrata è chiamata relazione "genitore-figlio". Si crea una classe di base, poi utilizzando extends si crea una nuova classe basata sulla classe genitore: la classe figlia. Successivamente si può usare la classe figlia come classe base per un'altra classe.

Nota: Una classe deve essere definita prima di essere utilizzata! Se si vuole la classe Named_Cart che estende la classe Cart, bisogna definire una classe Cart prima. Se si vuole creare un'altra classe chiamata Yellow_named_cart basata sulla classe Named_Cart bisogna definire la classe Named_Cart prima. Per farla breve: l'ordine di definizione delle classi è importante.


Costruttori

Attenzione

In PHP 3 i costruttori si comportano diversamente rispetto a PHP 4. La semantica di PHP 4 è decisamente da preferire.

I costruttori sono funzioni che esistono in una classe e che sono chiamate automaticamente quando si crea una nuova istanza di una classe con new. In PHP 3, una funzione si transforma in in un costruttore quando ha lo stesso nome di una classe. In PHP 4, una funzione diventa un costruttore, quando ha lo stesso nome di una classe ed è definita all'interno della classe stessa - la differenza è sottile, ma cruciale (si veda sotto).

<?php
// Funziona in PHP 3 e PHP 4.
class Auto_Cart extends Cart
{
    function Auto_Cart()
    {
        $this->add_item ("10", 1);
    }
}
?>

Questo codice definisce una classe Auto_Cart, che non è altro che Cart più un costruttore che inizializza il carrello con una occorrenza dell'articolo numero "10" ogni volta che un nuovo Auto_Cart è creato con "new". I costruttori possono avere degli argomenti, e gli argomenti possono essere facoltativi, questo li rende molto versatili. Per poter usare una classe senza specificare parametri, tutti i parametri del costruttore devono essere resi facoltativi con valori di default.

<?php
// Funziona in PHP 3 and PHP 4.
class Constructor_Cart extends Cart
{
    function Constructor_Cart($item = "10", $num = 1)
    {
        $this->add_item ($item, $num);
    }
}
 
// Istanzia il vecchio e noioso carrello.
 
$default_cart = new Constructor_Cart;
 
// Un carrello nuovo ...
 
$different_cart = new Constructor_Cart("20", 17);
?>

E possibile utilizzare l'operatore @ per inibire gli errori provocati dal costruttore, es: @new.

Attenzione

In PHP 3, le classi e i costruttori derivati presentano un certo numero di limitazioni. I seguenti esempi dovrebbero essere letti con attenzione per capire queste limitazioni.

<?php
class A
{
    function A()
    {
      echo "Sono il costtruttore di A.<br>\n";
    }
}

class B extends A
{
    function C()
    {
        echo "Sono una normale funzione.<br>\n";
    }
}

// nessun costruttore è chiamato in PHP 3.
$b = new B;
?>

In PHP 3, nessun costruttore è stato chiamanto nel suddetto esempio. La regola in PHP 3 è: 'un costruttore è una funzione che ha lo stesso nome di una classe'. Il nome della classe è B e non c'è nessuna funzione B() nella classe B.

Questa regola è stata cambiata in PHP 4, la nuova regola dice: 'Se una classe non ha un costruttore proprio, verrà chiamato il costruttore della classe base, se esiste'. Il suddetto esempio avrebbe stampato 'Sono il costruttore di A.' in PHP 4.

<?php
class A
{
    function A()
    {
        echo "Sono il costruttore di A.<br>\n";
    }

    function B()
    {
        echo "Sono una normale funzione di nome B della classe A.<br>\n";
        echo "Non sono il costruttore di A.<br>\n";
    }
}

class B extends A
{
    function C()
    {
        echo "Sono una normale funzione.<br>\n";
    }
}

// This will call B() as a constructor.
$b = new B;
?>

In PHP 3, la funzione B() della classe A si transformerà improvvisamente in un costruttore per la classe B, anche se questo non era previsto. La regola in PHP 3 è: 'un costruttore è una funzione che ha lo stesso nome di una classe'. PHP 3 non si preoccupa se la funzione è stata definita nella classe B o se è stata ereditata.

La regola è stata corretta in PHP 4 ed è diventata: 'un costruttore è una funzione con lo stesso nome della classe in cui è definita'. Così in PHP 4, la classe B non avendo una funzione costruttore avrebbe richiamato il costruttore della sua classe base, e sarebbe stato stampato 'io sono il costruttore di A.'.

Attenzione

Nè PHP 3 nè PHP 4 chiamano costruttori di una classe base automaticamente da un costruttore di una classe derivata. È responsabilità del programmatore propagare la chiamata ai costruttori dove è necessario.

Nota: Non ci sono distruttori in PHP 3 o in PHP 4. Potete usare register_shutdown_function() per simulare la maggior parte degli effetti dei distruttori.

I distruttori sono funzioni che sono chiamate automaticamente quando una variabile è distrutta con unset() o semplicemente uscendo dal suo ambito. Non ci sono distruttori in PHP.


::

Attenzione

Ciò che segue è valido soltanto per PHP 4.

A volte è utile riferirsi alle funzioni ed alle variabili di classi base o riferirsi alle funzioni di classi senza istanziarle. L'operatore :: è usato per questi scopi.

<?php
class A
{
    function example()
    {
        echo "Sono la funzione originale A::example().<br>\n";
    }
}

class B extends A
{
    function example()
    {
        echo "Sono la funzione ridefinita B::example().<br>\n";
        A::example();
    }
}

// non viene istanziato nessun oggetto dalla classe A.
// ma il codice stampa
//   Sono la funzione originale A::example().<br>
A::example();

// crea un oggetto dalla classe B.
$b = new B;

// questo codice stampa
//   Sono la funzione ridefinita B::example().<br>
//   Sono la funzione originale A::example().<br>
$b->example();
?>

L'esempio chiama la funzione example() della classe A, ma senza creare un'istanza di A, di modo che la funzione non si possa richiamare con $a->example(). example() è chiamata come 'funzione della classe', e non come funzione di un oggetto della classe.

Si possono usare funzioni della classe, ma non le variabili della classe. Infatti, non esiste nessun oggetto nel momento della chiamata della funzione. Quindi, la funzione della classe non può usare le variabili dell'oggetto (ma può usare le variabili locali e globali) e $this non può essere usato.

Nel suddetto esempio, la classe B ridefinisce la funzione example(). La funzione originale definita nella classe A è adombrata e non più disponibile, a meno che voi non chiamiate esplicitamente con l'operatore :: scrivendo A::example() per richiamare la funzione (è possibile anche scrivere parent::example(), come mostra la sezione seguente).

In questo contesto, c'è un oggetto corrente che può avere determinate variabili. Una volta usate da parte di una funzione dell'oggetto, potete usare $this per le variabili dell'oggetto.


parent

E possibile ritrovarsi a scrivere classi con codice che si riferisce a variabili e funzioni di classi base. Ciò è particolarmente VERO se una classe derivata è un perfezionamento o una specializzazione di una classe base.

Invece di usare il nome letterale della classe, bisognerebbe usare il nome speciale parent, che si riferisce al nome della classe base definita nella dichiarazione di extends. Usando questo metodo, si evita di usare il nome della classe base nel codice scritto. Se l'albero di eredità cambiasse durante lo sviluppo della classe, il cambiamento si ridurrebbe semplicemente alla modifica della dichiarazione extends della classe.

<?php
class A
{
    function example()
    {
        echo "Sono A::example() e fornisco una funzionalità di base.<br>\n";
    }
}

class B extends A
{
    function example()
    {
        echo "Sono B::example() e fornisco una funzionalità aggiuntiva.<br>\n";
        parent::example();
    }
}

$b = new B;

// Il codice chiama B::example(), che a sua volta chiama A::example().
$b->example();
?>


Serializzare oggetti - oggetti nelle sessioni

Nota: In PHP 3, gli oggetti perdono la loro associazione di classe durante il processo di serializzazione e di deserializzazione. La variabile risultante è di tipo oggetto, ma non ha classe e metodi, e diventa inutile (come un buffo array).

Attenzione

Le seguenti informazioni sono valide soltanto per PHP 4.

serialize() restituisce una stringa che contiene una rappresentazione byte-stream di tutti i valori che possono essere memorizzati in PHP. unserialize() può usare questa stringa per ricreare i valori variabili utilizzabili. Usando serialize() per salvare un oggetto si salveranno tutte le variabili dell'oggetto. Le funzioni dell'oggetto non sono salvate, viene salvato solo il nome della classe.

Per potere usare unserialize() su un oggetto, la classe dell'oggetto deve essere definita. Cioè se avete un oggetto $a della classe A su una pagina di nome page1.php e usate serialize(), otterrete una stringa che si riferisce alla classe A e contiene tutti i valori delle variabili contenute in $a. Se desiderate potere deserializzare l'oggetto in un'altra pagina chiamata page2.php, dovete ricreare $a dalla classe A, la definizione della classe A perciò deve essere presente nella pagina page2.php. Questo può essere fatto per esempio memorizzando la definizione della classe A in un file che viene incluso sia in page1.php che in page2.php.

<?php
// classa.inc:
  
  class A 
  {
      var $one = 1;
    
      function show_one()
      {
          echo $this->one;
      }
  }
  
// page1.php:
  include("classa.inc");
  
  $a = new A;
  $s = serialize($a);
  // memorizzare $s in qualche posto della page2.
  $fp = fopen("store", "w");
  fputs($fp, $s);
  fclose($fp);

// page2.php:

  // questo è necessario perchè unserialize() funzioni correttamente.
  include("classa.inc");

  $s = implode("", @file("store"));
  $a = unserialize($s);

  // ora usiamo la function show_one() dell'oggetto $a.  
  $a->show_one();
?>

Se state usando le sessioni ed usate session_register() per registrare oggetti, questi oggetti vengono serializzati automaticamente alla fine di ogni pagina PHP e sono deserializzate automaticamente su ogni pagina della sessione. Ciò significa che gli oggetti possono mostrarsi in ogni pagina e che sono parte integrante della sessione.

Si suggerisce vivamente di includere le definizioni delle classi degli oggetti registrati su tutte le pagine, anche se le classi non sono usate su tutte le pagine. Se un oggetto viene deserializzato senza la relativa definizione della classe, perderà l'associazione ad essa e si transformerà in in un oggetto della classe stdClass senza nessuna funzione disponibile, diventando inutile.

Così se nell'esempio qui sopra $a diventasse parte di una sessione e fosse registrato con session_register("a"), dovreste includere un file classa.inc su tutte le pagine in cui è valida la sessione, non soltanto nella page1.php e nella page2.php.


Le funzioni magiche __sleep e __wakeup

serialize() controlla se la vostra classe ha una funzione dal nome magico __sleep. In caso affermativo, quella funzione viene eseguita prima di qualsiasi serializzazione. La funzione può pulire l'oggetto e restituire un array con i nomi di tutte le variabili di quell' oggetto che dovrebbero essere serializzate.

Si intende usare __sleep quando chiudendo un collegamento ad un database l'oggetto può avere dati pendenti e l'oggetto ha bisogno di essere ripulito. Inoltre, la funzione è utile se avete oggetti molto grandi che non devono essere salvati completamente.

Per contro, unserialize() controlla per vedere se c'è nella classe una funzione dal nome magico __wakeup. Se è presente questa funzione può ricostruire qualunque risorsa che l'oggetto aveva.

L'intento di __wakeup è quello di ristabilire le connessioni ai database che possono esser state persi durante la serializzazione ed effettuare altre mansioni reinizializzazione.


Riferimenti all'interno del costruttore

La creazione di riferimenti con costruttori può condurre a risultati confusi. Questa sezione in stile Tutorial vi aiuterà ad evitare problemi.

<?php
class Foo
{
    function Foo($name)
    {
        // crea un riferimento all'interno della variabile $globalref
        global $globalref;
        $globalref[] = &$this;
        // setta Name con il valore passato
        $this->setName($name);
        // e lo manda all'output
        $this->echoName();
    }

    function echoName()
    {
        echo "<br>",$this->name;
    }
	
    function setName($name)
    {
        $this->name = $name;
    }
}
?>

Verifichiamo se c'è una differenza fra $bar1 che è stato creato usando l'operatore = e $bar2 che è stato creato usando l'operatore di riferimento =& ...

<?php
$bar1 = new Foo('set in constructor');
$bar1->echoName();
$globalref[0]->echoName();

/* output:
imposta nel costruttore
imposta nel costruttore
imposta nel costruttore */

$bar2 =& new Foo('set in constructor');
$bar2->echoName();
$globalref[1]->echoName();

/* output:
imposta nel costruttore
imposta nel costruttore
imposta nel costruttore */
?>

Apparentemente non c'è differenza, ed in effetti questo è molto significativo: $bar1 e $globalref[0] _ NON _ sono riferimenti, ma sono due variabili diverse. Questo succede perché "new" non restituisce per default un riferimento, ma restituisce una copia.

Nota: Non c'è perdita di prestazioni (da php 4 in su si usa il riferimento) ad istanziare copie per riferimento. Al contrario spesso è meglio lavorare con copie istanziate per riferimento, perché creare copie reali richiede un certo tempo, mentre creare riferimenti virtuali è immediato, (a meno che non si parli di un grande array o un oggetto che viene modificato in modo successivo, allora sarebbe saggio usare i riferimenti per cambiargli tutti i valori simultaneamente).

Per dimostrare quello che è scritto sopra guardate il codice qui sotto.

<?php
// ora cambieremo il nome che cosa vi aspettate?
// potreste prevedere che $bar e $globalref[0] cambino i loro nomi ...
$bar1->setName('set from outside');

// come accennato prima ecco il risultato.
$bar1->echoName();
$globalref[0]->echoName();

/* output:
set from outside
set in constructor */

// vediamo le differenze tra $bar2 e $globalref[1] 
$bar2->setName('set from outside');

// fortunatamen sono solo uguali, ma sono la stessa variabile
// $bar2->name e $globalref[1]->name sono la stessa cosa
$bar2->echoName();
$globalref[1]->echoName();

/* output:
set from outside
set from outside */
?>

Un esempio finale, prova a farvi capire.

<?php
class A
{
    function A($i)
    {
        $this->value = $i;
        // provare a capire perchè qui non abbiamo bisogno d'un riferimento 
        $this->b = new B($this);
    }

    function createRef()
    {
        $this->c = new B($this);
    }

    function echoValue()
    {
        echo "<br>","class ",get_class($this),': ',$this->value;
    }
}


class B
{
    function B(&$a)
    {
        $this->a = &$a;
    }

    function echoValue()
    {
        echo "<br>","class ",get_class($this),': ',$this->a->value;
    }
}

// prova a capire perchè usando una semplice copia si avrebbe
// in un risultato indesiderato nella riga segnata con *
$a =& new A(10);
$a->createRef();

$a->echoValue();
$a->b->echoValue();
$a->c->echoValue();

$a->value = 11;

$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();

/*
output:
class A: 10
class B: 10
class B: 10
class A: 11
class B: 11
class B: 11
*/
?>


Confronto di oggetti in PHP 4

In PHP 4, gli oggetti sono confrontati semplicemente, cioè: due istanze di oggetto sono uguali se hanno gli stessi attributi e valori, e sono istanze della stessa classe. Questa regola regola è applicata anche nel confronto di due oggetti utilizzando l'operatore di identità (===).

Eseguendo il codice seguente:

Esempio 13-1. Esempio di confronto di oggetti in PHP 4

<?php
function bool2str($bool) {
    if ($bool === false) {
            return 'FALSE';
    } else {
            return 'TRUE';
    }
}

function compareObjects(&$o1, &$o2) {
    echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
    echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
    echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
    echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}

class Flag {
    var $flag;

    function Flag($flag=true) {
            $this->flag = $flag;
    }
}

class SwitchableFlag extends Flag {

    function turnOn() {
        $this->flag = true;
    }

    function turnOff() {
        $this->flag = false;
    }
}

$o = new Flag();
$p = new Flag(false);
$q = new Flag();

$r = new SwitchableFlag();

echo "Confronto di istanze create con gli stessi parametri\n";
compareObjects($o, $q);

echo "\nConfronto di istanze create con parametri diversi\n";
compareObjects($o, $p);

echo "\nConfronto di un'istanza della classe genitore con una sottoclasse\n";
compareObjects($o, $r);
?>
Si ha:
Confronto di istanze create con gli stessi parametri
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Confronto di istanze create con parametri diversi
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Confronto di un'istanza della classe genitore con una sottoclasse
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE
Questo è l'output che si ottiene secondo le regole di confronto descritte sopra. Solo le istanze con gli stessi valori per gli attributi e derivanti dalla stessa classe sono considerate uguali ed identiche.

Anche nei casi in cui l'oggetto è composto si applicano le stesse regole di confronto. Nell'esempio seguente creiamo una classe contenitore che archivia nell'array associativo Flag altri oggetti.

Esempio 13-2. Confronto di oggetti composti in PHP 4

<?php
class FlagSet {
    var $set;

    function FlagSet($flagArr = array()) {
        $this->set = $flagArr;
    }

    function addFlag($name, $flag) {
        $this->set[$name] = $flag;
    }

    function removeFlag($name) {
        if (array_key_exists($name, $this->set)) {
            unset($this->set[$name]);
        }
    }
}


$u = new FlagSet();
$u->addFlag('flag1', $o);
$u->addFlag('flag2', $p);
$v = new FlagSet(array('flag1'=>$q, 'flag2'=>$p));
$w = new FlagSet(array('flag1'=>$q));

echo "\nOggetti composti u(o,p) e v(q,p)\n";
compareObjects($u, $v);

echo "\nu(o,p) and w(q)\n";
compareObjects($u, $w);
?>
L'output previsto è:
Oggetti composti u(o,p) e v(q,p)
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

u(o,p) and w(q)
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE


Confronto di oggetti in PHP 5

Avvertimento

Questo modulo è SPERIMENTALE. Ovvero, il comportamento di queste funzioni, i nomi di queste funzioni, in definitiva tutto ciò che è documentato qui può cambiare nei futuri rilasci del PHP senza preavviso. Siete avvisati, l'uso di questo modulo è a vostro rischio.

In PHP 5, il confronto tra oggetti è più complicato che in PHP 4, ed è in armonia con quello che ci si può aspettare da un linguaggio orientato agli oggetti (non che PHP 5 lo sia veramente).

Quando si usa l'operatore di confronto (==), le variabili oggetto sono confrontate in modo semplice, cioè: due istanze di oggetto sono uguali se hanno gli stessi attributi e valori, e sono istanze della stessa classe, definita nello stesso spazio dei nomi.

Diversamente, quando usiamo l'operatore di identità (===), le variabili oggetto sono identiche se e solo se si riferiscono alla stessa istanza della stessa classe (in un particolare spazio dei nomi).

Un esempio chiarirà questa regola.

Esempio 13-3. Esempio di confronto di oggetti in PHP 5

<?php
function bool2str($bool) {
    if ($bool === false) {
            return 'FALSE';
    } else {
            return 'TRUE';
    }
}

function compareObjects(&$o1, &$o2) {
    echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
    echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
    echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
    echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}

class Flag {
    var $flag;

    function Flag($flag=true) {
            $this->flag = $flag;
    }
}

namespace Other {

    class Flag {
        var $flag;

        function Flag($flag=true) {
                $this->flag = $flag;
        }
    }

}

$o = new Flag();
$p = new Flag();
$q = $o;
$r = new Other::Flag();

echo "Due istanze della stessa classe\n";
compareObjects($o, $p);

echo "\nDue riferimenti alla stessa istanza\n";
compareObjects($o, $q);

echo "\nIstanze di classi di diversi spazi dei nomi e simili nomi di classe\n";
compareObjects($o, $r);
?>
L'esempio stampa:
Due istanze della stessa classe
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Due riferimenti alla stessa istanza
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Istanze di classi di diversi spazi dei nomi e simili nomi di classe
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE


Capitolo 14. Classes and Objects (PHP 5)

Introduction

Intro to oop5 for php


Constructors and Destructors

Constructor

PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

Nota: Parent constructors are not called implicitly. In order to run a parent constructor, a call to parent::__construct() is required.

Esempio 14-1. using new unified constructors

<?php
class BaseClass {
    function __construct() {
        print "In BaseClass constructor\n";
    }
}

class SubClass extends BaseClass {
    function __construct() {
        parent::__construct();
        print "In SubClass constructor\n";
    }
}

$obj = new BaseClass();
$obj = new SubClass();
?>

For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.


Destructor

PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as Java: When the last reference to an object is destroyed the object's destructor, which is a class method named __destruct() that receives no parameters, is called before the object is freed from memory.

Esempio 14-2. Destructor Example

<?php
class MyDestructableClass {
    function __construct() {
        print "In constructor\n";
        $this->name = "MyDestructableClass";
    }

    function __destruct() {
        print "Destroying " . $this->name . "\n";
    }
}

$obj = new MyDestructableClass();
?>

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.


Visibility

The visibility of a member or method can be defined by prefixing the declaration with the keywords: public, protected or private. Public declared items can be allow access to any caller. Protected limits access access to only classes inherited. Protected limits visiblity only to the class that defines the item.


Members Visibility

Class members must be defined with public, private, or private.

Esempio 14-3. Member declaration

<?php

class MyClass {
   public    $public     = "MyClass::public!\n";
   protected $protected  = "MyClass::Protected!\n";
   protected $protected2 = "MyClass::Protected2!\n";
   private   $private    = "MyClass::private!\n";

   function printHello() {
      print "MyClass::printHello() " . $this->private;
      print "MyClass::printHello() " . $this->protected;
      print "MyClass::printHello() " . $this->protected2;
   }
}

class MyClass2 extends MyClass {
   protected $protected = "MyClass2::protected!\n";

   function printHello() {

      MyClass::printHello();    

      print "MyClass2::printHello() " . $this->public; 
      print "MyClass2::printHello() " . $this->protected; 
      print "MyClass2::printHello() " . $this->protected2;

      /* Will result in a Fatal Error: */
      //print "MyClass2::printHello() " . $this->private; /* Fatal Error */

   }
}

$obj = new MyClass();

print "Main:: " . $obj->public;
//print $obj->private; /* Fatal Error */
//print $obj->protected;  /* Fatal Error */
//print $obj->protected2;  /* Fatal Error */

$obj->printHello(); /* Should print */

$obj2 = new MyClass2();
print "Main:: " . $obj2->private; /* Undefined */ 

//print $obj2->protected;   /* Fatal Error */ 
//print $obj2->protected2;  /* Fatal Error */ 

$obj2->printHello();
?>

Nota: The use PHP 4 use of declaring a variable with the keyword 'var' is no longer valid for PHP 5 objects. For compatiblity a variable declared in php will be assumed with public visiblity, and a E_STRICT warning will be issued.


::

.


Object Abstraction

PHP 5 introduces abstract classes and methods. An abstract method only declares the method's signature and does not provide an implementation. A class that contains abstract methods needs to be declared abstract.

Esempio 14-4.

<?php
abstract class AbstractClass {
   abstract public function test();
}

class ImplementedClass extends AbstractClass {
   public function test() {
       echo "ImplementedClass::test() called.\n";
   }
}

$o = new ImplementedClass;
$o->test();
?>

Abstract classes cannot be instantiated. Old code that has no user-defined classes or functions named 'abstract' should run without modifications.


Object cloning

Creating a copy of an object with fully replicated properties is not always the wanted behavior. A good example of the need for copy constructors, is if you have an object which represents a GTK window and the object holds the resource of this GTK window, when you create a duplicate you might want to create a new window with the same properties and have the new object hold the resource of the new window. Another example is if your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.

An object copy is created by using the clone keyword (which calls the object's __clone() method if possible). An object's __clone() method cannot be called directly.

$copy_of_object = clone $object;

When the developer asks to create a new copy of an object, PHP 5 will check if a __clone() method has been defined or not. If not, it will call a default __clone() which will copy all of the object's properties. If a __clone() method is defined, then it will be responsible to set the necessary properties in the created object. For convenience, the engine will supply a function that imports all of the properties from the source object, so that they can start with a by-value replica of the source object, and only override properties that need to be changed.

Esempio 14-5. Cloning an object

<?php
class MyCloneable {
   static $id = 0;

   function MyCloneable() {
       $this->id = self::$id++;
   }

   function __clone() {
       $this->address = "New York";
       $this->id = self::$id++;
   }
}

$obj = new MyCloneable();

$obj->name = "Hello";
$obj->address = "Tel-Aviv";

print $obj->id . "\n";

$obj_cloned = clone $obj;

print $obj_cloned->id . "\n";
print $obj_cloned->name . "\n";
print $obj_cloned->address . "\n";
?>

Comparing objects

In PHP 5, object comparison is a more complicated than in PHP 4 and more in accordance to what one will expect from an Object Oriented Language (not that PHP 5 is such a language).

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values, and are instances of the same class.

On the other hand, when using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.

An example will clarify these rules.

Esempio 14-6. Example of object comparison in PHP 5

<?php
function bool2str($bool) {
    if ($bool === false) {
            return 'FALSE';
    } else {
            return 'TRUE';
    }
}

function compareObjects(&$o1, &$o2) {
    echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
    echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
    echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
    echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}

class Flag {
    var $flag;

    function Flag($flag=true) {
            $this->flag = $flag;
    }
}

class OtherFlag {
    var $flag;

    function OtherFlag($flag=true) {
            $this->flag = $flag;
    }
}

$o = new Flag();
$p = new Flag();
$q = $o;
$r = new OtherFlag();

echo "Two instances of the same class\n";
compareObjects($o, $p);

echo "\nTwo references to the same instance\n";
compareObjects($o, $q);

echo "\nInstances of two different classes\n";
compareObjects($o, $r);
?>
This example will output:
Two instances of the same class
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Two references to the same instance
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Instances of two different classes
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE


Reflection

Introduction

PHP 5 comes with a complete reflection API that adds the ability to reverse-engineer classes, interfaces, functions and methods as well as extensions. Additionally, the reflection API also offers ways of retrieving doc comments for functions, classes and methods.

The reflection API is an object-oriented extension to the Zend Engine, consisting of the following classes:

<?php
  class Reflection { }
  interface Reflector { }
  class ReflectionException extends Exception { }
  class ReflectionFunction implements Reflector { }
  class ReflectionParameter implements Reflector { }
  class ReflectionMethod extends ReflectionFunction { }
  class ReflectionClass implements Reflector { }
  class ReflectionObject extends ReflectionClass { }
  class ReflectionProperty implements Reflector { }
  class ReflectionExtension implements Reflector { }
?>

Nota: For details on these classes, have a look at the next chapters.

If we were to execute the code in the example below:

Esempio 14-7. Basic usage of the reflection API

<?php
  Reflection::export(new ReflectionClass('Exception'));
?>
We will see:
Class [ <internal> class Exception ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [6] {
    Property [ <default> protected $message ]
    Property [ <default> private $string ]
    Property [ <default> protected $code ]
    Property [ <default> protected $file ]
    Property [ <default> protected $line ]
    Property [ <default> private $trace ]
  }

  - Methods [9] {
    Method [ <internal> final private method __clone ] {
    }

    Method [ <internal> <ctor> method __construct ] {
    }

    Method [ <internal> final public method getMessage ] {
    }

    Method [ <internal> final public method getCode ] {
    }

    Method [ <internal> final public method getFile ] {
    }

    Method [ <internal> final public method getLine ] {
    }

    Method [ <internal> final public method getTrace ] {
    }

    Method [ <internal> final public method getTraceAsString ] {
    }

    Method [ <internal> public method __toString ] {
    }
  }
}


ReflectionFunction

The ReflectionFunction class lets you reverse-engineer functions.

<?php
  class ReflectionFunction implements Reflector {
      public object __construct(string name)
      public string __toString()
      public static string export()
      public string getName()
      public bool isInternal()
      public bool isUserDefined()
      public string getFileName()
      public int getStartLine()
      public int getEndLine()
      public string getDocComment()
      public array getStaticVariables()
      public mixed invoke(mixed* args)
      public bool returnsReference()
      public ReflectionParameter[] getParameters()
  }
?>

To introspect a function, you will first have to create an instance of the ReflectionFunction class. You can then call any of the above methods on this instance.

Esempio 14-8. Using the ReflectionFunction class

<?php
/**
 * A simple counter
 *
 * @return    int
 */
function counter() 
{
    static $c = 0;

    return $c++;
}

// Create an instance of the Reflection_Function class
$func = new ReflectionFunction('counter');

// Print out basic information
printf(
    "===> The %s function '%s'\n".
    "     declared in %s\n".
    "     lines %d to %d\n",
    $func->isInternal() ? 'internal' : 'user-defined',
    $func->getName(),
    $func->getFileName(),
    $func->getStartLine(),
    $func->getEndline()
);

// Print documentation comment
printf("---> Documentation:\n %s\n", var_export($func->getDocComment(), 1));

// Print static variables if existant
if ($statics = $func->getStaticVariables())
{
    printf("---> Static variables: %s\n", var_export($statics, 1));
}

// Invoke the function
printf("---> Invokation results in: ");
var_dump($func->invoke());


// you may prefer to use the export() method
echo "\nReflectionFunction::export() results:\n";
echo ReflectionFunction::export('counter');
?>

Nota: The method invoke() accepts a variable number of arguments which are passed to the function just as in call_user_func().


ReflectionParameter

The ReflectionParameter class retrieves information about a function's or method's parameters.

<?php
  class ReflectionParameter implements Reflector {
      public object __construct(string name)
      public string __toString()
      public static string export()
      public string getName()
      public ReflectionClass getClass()
      public bool allowsNull()
      public bool isPassedByReference()
  }
?>

To introspect function parameters, you will first have to create an instance of the ReflectionFunction or ReflectionMethod classes and then use their getParameters() method to retrieve an array of parameters.

Esempio 14-9. Using the ReflectionParameter class

<?php
    function foo($a, $b, $c) { }
    function bar(Exception $a, &$b, $c) { }
    function baz($a = 1, $b = NULL, ReflectionFunction $c) { }
    function abc() { }

    // Create an instance of Reflection_Function with the
    // parameter given from the command line.    
    $reflect = new ReflectionFunction($argv[1]);

    echo $reflect;

    foreach ($reflect->getParameters() as $i => $param) 
    {
        printf(
            "-- Parameter #%d: %s {\n".
            "   Class: %s\n".
            "   Allows NULL: %s\n".
            "   Passed to by reference: %s\n".
            "}\n",
            $i, 
            $param->getName(),
            var_export($param->getClass(), 1),
            var_export($param->allowsNull(), 1),
            var_export($param->isPassedByReference(), 1)
        );
    }
?>

ReflectionClass

The ReflectionClass class lets you reverse-engineer classes.

<?php
  class ReflectionClass implements Reflector {
      public __construct(string name)
      public string __toString()
      public static string export()
      public string getName()
      public bool isInternal()
      public bool isUserDefined()
      public string getFileName()
      public int getStartLine()
      public int getEndLine()
      public string getDocComment()
      public ReflectionMethod getConstructor()
      public ReflectionMethod getMethod(string name)
      public ReflectionMethod[] getMethods()
      public ReflectionProperty getProperty(string name)
      public ReflectionProperty[] getProperties()
      public array getConstants()
      public mixed getConstant(string name)
      public bool isInstantiable()
      public bool isInterface()
      public bool isFinal()
      public bool isAbstract()
      public int getModifiers()
      public bool isInstance(stdclass object)
      public stdclass newInstance(mixed* args)
      public ReflectionClass[] getInterfaces()
      public ReflectionClass getParentClass()
      public bool isSubclassOf(ReflectionClass class)
  }
?>

To introspect a class, you will first have to create an instance of the ReflectionClass class. You can then call any of the above methods on this instance.

Esempio 14-10. Using the ReflectionClass class

<?php
  interface Serializable
  {
      // ...
  }

  class Object
  {
      // ...
  }

  /**
   * A counter class
   *
   */
  class Counter extends Object implements Serializable 
  {
      const START = 0;
      private static $c = Counter::START;

      /**
       * Invoke counter
       *
       * @access  public
       * @return  int
       */
      public function count()
      {
          return self::$c++;
      }
  }

  // Create an instance of the ReflectionClass class
  $class= new ReflectionClass('Counter');

  // Print out basic information
  printf(
      "===> The %s%s%s %s '%s' [extends %s]\n".
      "     declared in %s\n".
      "     lines %d to %d\n".
      "     having the modifiers %d [%s]\n",
      $class->isInternal() ? 'internal' : 'user-defined',
      $class->isAbstract() ? ' abstract' : '',
      $class->isFinal() ? ' final' : '',
      $class->isInterface() ? 'interface' : 'class',
      $class->getName(),
      var_export($class->getParentClass(), 1),
      $class->getFileName(),
      $class->getStartLine(),
      $class->getEndline(),
      $class->getModifiers(),
      implode(' ', Reflection::getModifierNames($class->getModifiers()))
  );

  // Print documentation comment
  printf("---> Documentation:\n %s\n", var_export($class->getDocComment(), 1));

  // Print which interfaces are implemented by this class
  printf("---> Implements:\n %s\n", var_export($class->getInterfaces(), 1));

  // Print class constants
  printf("---> Constants: %s\n", var_export($class->getConstants(), 1));

  // Print class properties
  printf("---> Properties: %s\n", var_export($class->getProperties(), 1));

  // Print class methods
  printf("---> Methods: %s\n", var_export($class->getMethods(), 1));

  // If this class is instantiable, create an instance
  if ($class->isInstantiable()) 
  {
      $counter= $class->newInstance();

      echo '---> $counter is instance? '; 
      echo $class->isInstance($counter) ? 'yes' : 'no';

      echo "\n---> new Object() is instance? ";
      echo $class->isInstance(new Object()) ? 'yes' : 'no';
  }
?>

Nota: The method newInstance() accepts a variable number of arguments which are passed to the function just as in call_user_func().

Nota: $class = new ReflectionClass('Foo'); $class->isInstance($arg) is equivalent to $arg instanceof Foo or is_a($arg, 'Foo').


ReflectionMethod

The ReflectionMethod class lets you reverse-engineer class methods.

<?php
  class ReflectionMethod extends ReflectionFunction {
      public __construct(mixed class, string name)
      public static string export()
      public mixed invoke(stdclass object, mixed* args)
      public bool isFinal()
      public bool isAbstract()
      public bool isPublic()
      public bool isPrivate()
      public bool isProtected()
      public bool isStatic()
      public bool isConstructor()
      public int getModifiers()
      public ReflectionClass getDeclaringClass()

      /* Inherited from ReflectionFunction */
      public string __toString()
      public string getName()
      public bool isInternal()
      public bool isUserDefined()
      public string getFileName()
      public int getStartLine()
      public int getEndLine()
      public string getDocComment()
      public array getStaticVariables()
      public bool returnsReference()
      public ReflectionParameter[] getParameters()
  }
?>

To introspect a method, you will first have to create an instance of the ReflectionMethod class. You can then call any of the above methods on this instance.

Esempio 14-11. Using the ReflectionMethod class

<?php
  class Counter {
      private static $c = 0;

      /**
       * Increment counter
       *
       * @final
       * @static
       * @access  public
       * @return  int
       */
      final public static function increment()
      {
          self::$c++;
          return self::$c;
      }
  }

  // Create an instance of the Reflection_Method class
  $method= new ReflectionMethod('Counter', 'increment');

  // Print out basic information
  printf(
    "===> The %s%s%s%s%s%s%s method '%s' (which is %s)\n".
    "     declared in %s\n".
    "     lines %d to %d\n".
    "     having the modifiers %d[%s]\n",
    $method->isInternal() ? 'internal' : 'user-defined',
    $method->isAbstract() ? ' abstract' : '',
    $method->isFinal() ? ' final' : '',
    $method->isPublic() ? ' public' : '',
    $method->isPrivate() ? ' private' : '',
    $method->isProtected() ? ' protected' : '',
    $method->isStatic() ? ' static' : '',
    $method->getName(),
    $method->isConstructor() ? 'the constructor' : 'a regular method',
    $method->getFileName(),
    $method->getStartLine(),
    $method->getEndline(),
    $method->getModifiers(),
    implode(' ', Reflection::getModifierNames($method->getModifiers()))
  );

  // Print documentation comment
  printf("---> Documentation:\n %s\n", var_export($method->getDocComment(), 1));

  // Print static variables if existant
  if ($statics= $method->getStaticVariables())
  {
      printf("---> Static variables: %s\n", var_export($statics, 1));
  }

  // Invoke the method
  printf("---> Invokation results in: ");
  var_dump($method->invoke(NULL));
?>

Nota: Trying to invoke private, protected or abstract methods will result in an exception being thrown from the invoke() method.

Nota: For static methods as seen above, you should pass NULL as the first argument to invoke(). For non-static methods, pass an instance of the class.


ReflectionProperty

The ReflectionProperty class lets you reverse-engineer class properties.

<?php
  class ReflectionProperty implements Reflector {
      public __construct(mixed class, string name)
      public string __toString()
      public static string export()
      public string getName()
      public bool isPublic()
      public bool isPrivate()
      public bool isProtected()
      public bool isStatic()
      public bool isDefault()
      public int getModifiers()
      public mixed getValue(stdclass object)
      public void setValue(stdclass object, mixed value)
      public ReflectionClass getDeclaringClass()
  }
?>

To introspect a method, you will first have to create an instance of the ReflectionProperty class. You can then call any of the above methods on this instance.

Esempio 14-12. Using the ReflectionProperty class

<?php
  class String
  {
      public $length  = 5;
  }

  // Create an instance of the ReflectionProperty class
  $prop = new ReflectionProperty('String', 'length');

  // Print out basic information
  printf(
      "===> The%s%s%s%s property '%s' (which was %s)\n".
      "     having the modifiers %s\n",
      $prop->isPublic() ? ' public' : '',
      $prop->isPrivate() ? ' private' : '',
      $prop->isProtected() ? ' protected' : '',
      $prop->isStatic() ? ' static' : '',
      $prop->getName(),
      $prop->isDefault() ? 'declared at compile-time' : 'created at run-time',
      var_export(Reflection::getModifierNames($prop->getModifiers()), 1)
  );

  // Create an instance of String
  $obj= new String();

  // Get current value
  printf("---> Value is: ");
  var_dump($prop->getValue($obj));

  // Change value
  $prop->setValue($obj, 10);
  printf("---> Setting value to 10, new value is: ");
  var_dump($prop->getValue($obj));

  // Dump object
  var_dump($obj);
?>

Nota: Trying to get or set private or protected class property's values will result in an exception being thrown.


ReflectionExtension

The ReflectionExtension class lets you reverse-engineer extensions. You can retrieve all loaded extensions at runtime using the get_loaded_extensions().

<?php
  class ReflectionExtension implements Reflector {
      public __construct(string name)
      public string __toString()
      public static string export()
      public string getName()
      public string getVersion()
      public ReflectionFunction[] getFunctions()
      public array getConstants()
      public array getINIEntries()
  }
?>

To introspect a method, you will first have to create an instance of the ReflectionProperty class. You can then call any of the above methods on this instance.

Esempio 14-13. Using the ReflectionExtension class

<?php
  // Create an instance of the ReflectionProperty class
  $ext = new ReflectionExtension('standard');

  // Print out basic information
  printf(
      "Name        : %s\n".
      "Version     : %s\n".
      "Functions   : [%d] %s\n".
      "Constants   : [%d] %s\n".
      "INI entries : [%d] %s\n",
      $ext->getName(),
      $ext->getVersion() ? $ext->getVersion() : 'NO_VERSION',
      sizeof($ext->getFunctions()),
      var_export($ext->getFunctions(), 1),
      sizeof($ext->getConstants()),
      var_export($ext->getConstants(), 1),
      sizeof($ext->getINIEntries()),
      var_export($ext->getINIEntries(), 1)
  );
?>

Extending the reflection classes

In case you want to create specialized versions of the built-in classes (say, for creating colorized HTML when being exported, having easy-access member variables instead of methods or having utility methods), you may go ahead and extend them.

Esempio 14-14. Extending the built-in classes

<?php
  /**
   * My Reflection_Method class
   *
   */
  class My_Reflection_Method extends ReflectionMethod {
    public $visibility= '';

    public function __construct($o, $m) {
      parent::__construct($o, $m);
      $this->visibility= Reflection::getModifierNames($this->getModifiers());
    }
  }

  /**
   * Demo class #1
   *
   */
  class T {
    protected function x() {}
  }

  /**
   * Demo class #2
   *
   */
  class U extends T {
    function x() {}
  }

  // Print out information
  var_dump(new My_Reflection_Method('U', 'x'));
?>

Nota: Caution: If you're overwriting the constructor, remember to call the parent's constructor _before_ any code you insert. Failing to do so will result in the following: Fatal error: Internal error: Failed to retrieve the reflection object


Capitolo 15. Spiegazioni sui riferimenti

Cosa sono i riferimenti

I riferimenti in PHP sono il mezzo per accedere ad uno stesso contenuto di variabile utilizzando diversi nomi. Non si sta parlando di puntatori come in C, ma di alias nella tabella dei simboli. Si noti che in PHP, il nome delle variabili e il loro contenuto sono cose diverse, uno stesso contenuto infatti può avere nomi diversi. L'analogia più prossima è quella con i nomi dei file e i file stessi in Unix - i nomi delle variabili sono come directory, mentre il contenuto delle variabili è il file stesso. I riferimenti possono essere pensati come hardlink del filesystem Unix.


Che cosa fanno i riferimenti

I riferimenti permettono di creare due o più variabili che si riferiscono allo stesso contenuto. Questo significa, che scrivendo:

$a =& $b

$a e $b puntano alla stessa variabile.

Nota: $a e $b sono completamente uguali, ma $a non è un puntatore a $b o vice versa, $a e $b puntano semplicemente nello stesso posto.

Questa sintassi si può usare con le funzioni, nella restituzione per riferimento, e con l'operatore new (da PHP 4.0.4 in poi):

$bar =& new fooclass();
$foo =& find_var ($bar);

Nota: Se non si usa l'operatore & l'oggeto appena creato viene copiato. Usando $this in una classe, opererà sulla sua istanza corrente. L'assegnazione senza & copia perciò l'istanza (l'oggetto) e $this opera sulla copia, che non è sempre ciò che si desidera. Normalmente si lavora su una singola istanza di oggetto, sia per motivi di prestazioni che di consumo di memoria.

Utilizzando l'operatore @ con new, si sopprimono gli errori nel costruttore in questo modo @new, il metodo però non funziona se si usa l'istruzione &new. Questa è una limitazione dello Zend Engine e provoca un parser error.

Il secondo utilizzo del riferimento è il passaggio di una variabile per riferimento. Questo si fa dichiarando una variabile locale di una funzione e una variabile nell'ambito della chiamata del riferimento con lo stesso contenuto. Esempio:

function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);

$a assume il valore 6. Questo accade perchè nella funzione foo, la variabile $var si riferisce allo stesso contenuto di $a. Si vedano le spiegazioni più dettagliate per passaggio per riferimento.

Il terzo utilizzo del riferimento è il ritorno per riferimento.


Cosa i riferimenti non sono

Come detto prima, i riferimenti non sono puntatori. Questo significa, che il seguente costrutto non fà quello che ci si aspetterebbe:

function foo (&$var)
{
    $var =& $GLOBALS["baz"];
}
foo($bar);

Nell'esempio $var in foo viene scambiato con $bar nella chiamata, e poi riscambiato con $GLOBALS["baz"]. Questo non è il modo per collegare $bar nell'ambito della chiamata con qualcos'altro usando il meccanismo di riferimento, poichè $bar non è disponibile nella funzione foo (è rappresentato da $var, ma $var possiede soltanto il contenuto della variabile e non il nome del valore collegato nella tabella dei simboli).


Passaggio per riferimento

Si può passare una variabile ad una funzione per riferimento, modificandone gli argomenti. La sintassi è la seguente:

function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
// $a adesso è 6

Nota che non si usa il segno di riferimento nella chiamata della funzione, ma solo nella definizione. La definizione della funzione basta da sola per passare correttamente un argomento per riferimento.

Le seguenti cose possono essere passate per riferimento:

  • Variabili, es. foo($a)

  • Operatore New, es. foo(new foobar())

  • Riferimento restituito da una funazione, es.

    function &bar()
    {
        $a = 5;
        return $a;
    }
    foo(bar());

    Vedi anche le spiegazioni sulla restituzione per riferimento.

Qualunque altra cosa non dovrebbe essere passata per riferimento, poichè il risultato sarebbe indefinito. Per esempio, il seguente passaggio per riferimento non è valido:

function bar() // Nota l'assenza di &
{
    $a = 5;
    return $a;
}

foo(bar());
foo($a = 5) // Expressione: non una variabile
foo(5) // Constante: non una variabile

Questi requisiti sono validi per PHP 4.0.4 e seguenti.


Restituzione per riferimento

La restituzione per riferimento è utile quando si vuole usare una funzione per trovare quale variabile un riferimento dovrebbe limitare. Per restituire per riferimento, si usa questa sintassi:

function &find_var($param)
{
    ...codice...
    return $found_var;
}

$foo =& find_var($bar);
$foo->x = 2;

In questo esempio, la proprietà dell'oggetto restituito dalla funzione find_var viene impostata, non la copia, come sarebbe stato senza l'uso della sintassi del riferimento.

Nota: Diversamente dal passaggio di un parametro, bisogna utilizzare & in entrambi i posti - nella dichiarazione per indicare che si vuole restituire per riferimento, e non per copia come di consueto, e per indicare nella chiamata, il collegamento del riferimento, piuttosto che l'usuale assegnazione che verrebbe fatta per $foo.


Cancellare riferimenti

Quando si cancella un riferimento, si rompe il collegamento tra il nome della variabile e il contenuto della variabile. Questo non significa che il contenuto della variabile venga distrutto. Per esempio:

$a = 1;
$b =& $a;
unset ($a);

non cancella $b, ma solo $a.

Di nuovo, può essere utile pensare a questo con un'analogia col comendo Unix unlink.


Spotting References

Diversi costrutti in PHP sono implementati attraverso il meccanismo dei riferimenti, dove ogni cosa detta precedentemente, si applica anche a questi costrutti. Alcuni, come il passaggio e la restituzione per riferimento, sono stati menzionati sopra, gli altri sono:


Il riferimento global

Quando si dichiara una variabile come global $var di fatto si crea un riferimento ad una variabile globale. Questo ha lo stesso significato, dell'espressione:

$var =& $GLOBALS["var"];

Questo significa, per esempio, che cancellando $var non si cancella la variabile globale.


$this

In un metodo di un oggetto, $this è sempre un riferimento all'oggetto chiamante.

III. Security

Sommario
16. Security

Capitolo 16. Security


Introduction

PHP is a powerful language and the interpreter, whether included in a web server as a module or executed as a separate CGI binary, is able to access files, execute commands and open network connections on the server. These properties make anything run on a web server insecure by default. PHP is designed specifically to be a more secure language for writing CGI programs than Perl or C, and with correct selection of compile-time and runtime configuration options, and proper coding practices, it can give you exactly the combination of freedom and security you need.

As there are many different ways of utilizing PHP, there are many configuration options controlling its behaviour. A large selection of options guarantees you can use PHP for a lot of purposes, but it also means there are combinations of these options and server configurations that result in an insecure setup.

The configuration flexibility of PHP is equally rivalled by the code flexibility. PHP can be used to build complete server applications, with all the power of a shell user, or it can be used for simple server-side includes with little risk in a tightly controlled environment. How you build that environment, and how secure it is, is largely up to the PHP developer.

This chapter starts with some general security advice, explains the different configuration option combinations and the situations they can be safely used, and describes different considerations in coding for different levels of security.


General considerations

A completely secure system is a virtual impossibility, so an approach often used in the security profession is one of balancing risk and usability. If every variable submitted by a user required two forms of biometric validation (such as a retinal scan and a fingerprint), you would have an extremely high level of accountability. It would also take half an hour to fill out a fairly complex form, which would tend to encourage users to find ways of bypassing the security.

The best security is often unobtrusive enough to suit the requirements without the user being prevented from accomplishing their work, or over-burdening the code author with excessive complexity. Indeed, some security attacks are merely exploits of this kind of overly built security, which tends to erode over time.

A phrase worth remembering: A system is only as good as the weakest link in a chain. If all transactions are heavily logged based on time, location, transaction type, etc. but the user is only verified based on a single cookie, the validity of tying the users to the transaction log is severely weakened.

When testing, keep in mind that you will not be able to test all possibilities for even the simplest of pages. The input you may expect will be completely unrelated to the input given by a disgruntled employee, a cracker with months of time on their hands, or a housecat walking across the keyboard. This is why it's best to look at the code from a logical perspective, to discern where unexpected data can be introduced, and then follow how it is modified, reduced, or amplified.

The Internet is filled with people trying to make a name for themselves by breaking your code, crashing your site, posting inappropriate content, and otherwise making your day interesting. It doesn't matter if you have a small or large site, you are a target by simply being online, by having a server that can be connected to. Many cracking programs do not discern by size, they simply trawl massive IP blocks looking for victims. Try not to become one.


Installed as CGI binary

Possible attacks

Using PHP as a CGI binary is an option for setups that for some reason do not wish to integrate PHP as a module into server software (like Apache), or will use PHP with different kinds of CGI wrappers to create safe chroot and setuid environments for scripts. This setup usually involves installing executable PHP binary to the web server cgi-bin directory. CERT advisory CA-96.11 recommends against placing any interpreters into cgi-bin. Even if the PHP binary can be used as a standalone interpreter, PHP is designed to prevent the attacks this setup makes possible:

  • Accessing system files: http://my.host/cgi-bin/php?/etc/passwd

    The query information in a URL after the question mark (?) is passed as command line arguments to the interpreter by the CGI interface. Usually interpreters open and execute the file specified as the first argument on the command line.

    When invoked as a CGI binary, PHP refuses to interpret the command line arguments.

  • Accessing any web document on server: http://my.host/cgi-bin/php/secret/doc.html

    The path information part of the URL after the PHP binary name, /secret/doc.html is conventionally used to specify the name of the file to be opened and interpreted by the CGI program. Usually some web server configuration directives (Apache: Action) are used to redirect requests to documents like http://my.host/secret/script.php to the PHP interpreter. With this setup, the web server first checks the access permissions to the directory /secret, and after that creates the redirected request http://my.host/cgi-bin/php/secret/script.php. Unfortunately, if the request is originally given in this form, no access checks are made by web server for file /secret/script.php, but only for the /cgi-bin/php file. This way any user able to access /cgi-bin/php is able to access any protected document on the web server.

    In PHP, compile-time configuration option --enable-force-cgi-redirect and runtime configuration directives doc_root and user_dir can be used to prevent this attack, if the server document tree has any directories with access restrictions. See below for full the explanation of the different combinations.


Case 1: only public files served

If your server does not have any content that is not restricted by password or ip based access control, there is no need for these configuration options. If your web server does not allow you to do redirects, or the server does not have a way to communicate to the PHP binary that the request is a safely redirected request, you can specify the option --enable-force-cgi-redirect to the configure script. You still have to make sure your PHP scripts do not rely on one or another way of calling the script, neither by directly http://my.host/cgi-bin/php/dir/script.php nor by redirection http://my.host/dir/script.php.

Redirection can be configured in Apache by using AddHandler and Action directives (see below).


Case 2: using --enable-force-cgi-redirect

This compile-time option prevents anyone from calling PHP directly with a URL like http://my.host/cgi-bin/php/secretdir/script.php. Instead, PHP will only parse in this mode if it has gone through a web server redirect rule.

Usually the redirection in the Apache configuration is done with the following directives:

Action php-script /cgi-bin/php
AddHandler php-script .php

This option has only been tested with the Apache web server, and relies on Apache to set the non-standard CGI environment variable REDIRECT_STATUS on redirected requests. If your web server does not support any way of telling if the request is direct or redirected, you cannot use this option and you must use one of the other ways of running the CGI version documented here.


Case 3: setting doc_root or user_dir

To include active content, like scripts and executables, in the web server document directories is sometimes considered an insecure practice. If, because of some configuration mistake, the scripts are not executed but displayed as regular HTML documents, this may result in leakage of intellectual property or security information like passwords. Therefore many sysadmins will prefer setting up another directory structure for scripts that are accessible only through the PHP CGI, and therefore always interpreted and not displayed as such.

Also if the method for making sure the requests are not redirected, as described in the previous section, is not available, it is necessary to set up a script doc_root that is different from web document root.

You can set the PHP script document root by the configuration directive doc_root in the configuration file, or you can set the environment variable PHP_DOCUMENT_ROOT. If it is set, the CGI version of PHP will always construct the file name to open with this doc_root and the path information in the request, so you can be sure no script is executed outside this directory (except for user_dir below).

Another option usable here is user_dir. When user_dir is unset, only thing controlling the opened file name is doc_root. Opening a URL like http://my.host/~user/doc.php does not result in opening a file under users home directory, but a file called ~user/doc.php under doc_root (yes, a directory name starting with a tilde [~]).

If user_dir is set to for example public_php, a request like http://my.host/~user/doc.php will open a file called doc.php under the directory named public_php under the home directory of the user. If the home of the user is /home/user, the file executed is /home/user/public_php/doc.php.

user_dir expansion happens regardless of the doc_root setting, so you can control the document root and user directory access separately.


Case 4: PHP parser outside of web tree

A very secure option is to put the PHP parser binary somewhere outside of the web tree of files. In /usr/local/bin, for example. The only real downside to this option is that you will now have to put a line similar to:

#!/usr/local/bin/php

as the first line of any file containing PHP tags. You will also need to make the file executable. That is, treat it exactly as you would treat any other CGI script written in Perl or sh or any other common scripting language which uses the #! shell-escape mechanism for launching itself.

To get PHP to handle PATH_INFO and PATH_TRANSLATED information correctly with this setup, the PHP parser should be compiled with the --enable-discard-path configure option.


Installed as an Apache module

When PHP is used as an Apache module it inherits Apache's user permissions (typically those of the "nobody" user). This has several impacts on security and authorization. For example, if you are using PHP to access a database, unless that database has built-in access control, you will have to make the database accessible to the "nobody" user. This means a malicious script could access and modify the database, even without a username and password. It's entirely possible that a web spider could stumble across a database administrator's web page, and drop all of your databases. You can protect against this with Apache authorization, or you can design your own access model using LDAP, .htaccess files, etc. and include that code as part of your PHP scripts.

Often, once security is established to the point where the PHP user (in this case, the apache user) has very little risk attached to it, it is discovered that PHP is now prevented from writing any files to user directories. Or perhaps it has been prevented from accessing or changing databases. It has equally been secured from writing good and bad files, or entering good and bad database transactions.

A frequent security mistake made at this point is to allow apache root permissions, or to escalate apache's abilitites in some other way.

Escalating the Apache user's permissions to root is extremely dangerous and may compromise the entire system, so sudo'ing, chroot'ing, or otherwise running as root should not be considered by those who are not security professionals.

There are some simpler solutions. By using open_basedir you can control and restrict what directories are allowed to be used for PHP. You can also set up apache-only areas, to restrict all web based activity to non-user, or non-system, files.


Filesystem Security

PHP is subject to the security built into most server systems with respect to permissions on a file and directory basis. This allows you to control which files in the filesystem may be read. Care should be taken with any files which are world readable to ensure that they are safe for reading by all users who have access to that filesystem.

Since PHP was designed to allow user level access to the filesystem, it's entirely possible to write a PHP script that will allow you to read system files such as /etc/passwd, modify your ethernet connections, send massive printer jobs out, etc. This has some obvious implications, in that you need to ensure that the files that you read from and write to are the appropriate ones.

Consider the following script, where a user indicates that they'd like to delete a file in their home directory. This assumes a situation where a PHP web interface is regularly used for file management, so the Apache user is allowed to delete files in the user home directories.

Esempio 16-1. Poor variable checking leads to....

<?php
// remove a file from the user's home directory
$username = $_POST['user_submitted_name'];
$homedir = "/home/$username";
$file_to_delete = "$userfile";
unlink ("$homedir/$userfile");
echo "$file_to_delete has been deleted!";
?>
Since the username is postable from a user form, they can submit a username and file belonging to someone else, and delete files. In this case, you'd want to use some other form of authentication. Consider what could happen if the variables submitted were "../etc/" and "passwd". The code would then effectively read:

Esempio 16-2. ... A filesystem attack

<?php
// removes a file from anywhere on the hard drive that
// the PHP user has access to. If PHP has root access:
$username = "../etc/";
$homedir = "/home/../etc/";
$file_to_delete = "passwd";
unlink ("/home/../etc/passwd");
echo "/home/../etc/passwd has been deleted!";
?>
There are two important measures you should take to prevent these issues.

  • Only allow limited permissions to the PHP web user binary.

  • Check all variables which are submitted.

Here is an improved script:

Esempio 16-3. More secure file name checking

<?php
// removes a file from the hard drive that
// the PHP user has access to.
$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim

$homedir = "/home/$username";

$file_to_delete = basename("$userfile"); // strip paths
unlink ($homedir/$file_to_delete);

$fp = fopen("/home/logging/filedelete.log","+a"); //log the deletion
$logstring = "$username $homedir $file_to_delete";
fwrite ($fp, $logstring);
fclose($fp);

echo "$file_to_delete has been deleted!";
?>
However, even this is not without it's flaws. If your authentication system allowed users to create their own user logins, and a user chose the login "../etc/", the system is once again exposed. For this reason, you may prefer to write a more customized check:

Esempio 16-4. More secure file name checking

<?php
$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim
$homedir = "/home/$username";

if (!ereg('^[^./][^/]*$', $userfile))
     die('bad filename'); //die, do not process

if (!ereg('^[^./][^/]*$', $username))
     die('bad username'); //die, do not process
//etc...
?>

Depending on your operating system, there are a wide variety of files which you should be concerned about, including device entries (/dev/ or COM1), configuration files (/etc/ files and the .ini files), well known file storage areas (/home/, My Documents), etc. For this reason, it's usually easier to create a policy where you forbid everything except for what you explicitly allow.


Database Security

Nowadays, databases are cardinal components of any web based application by enabling websites to provide varying dynamic content. Since very sensitive or secret information can be stored in a database, you should strongly consider protecting your databases.

To retrieve or to store any information you need to connect to the database, send a legitimate query, fetch the result, and close the connection. Nowadays, the commonly used query language in this interaction is the Structured Query Language (SQL). See how an attacker can tamper with an SQL query.

As you can surmise, PHP cannot protect your database by itself. The following sections aim to be an introduction into the very basics of how to access and manipulate databases within PHP scripts.

Keep in mind this simple rule: defense in depth. The more places you take action to increase the protection of your database, the less probability of an attacker succeeding in exposing or abusing any stored information. Good design of the database schema and the application deals with your greatest fears.


Designing Databases

The first step is always to create the database, unless you want to use one from a third party. When a database is created, it is assigned to an owner, who executed the creation statement. Usually, only the owner (or a superuser) can do anything with the objects in that database, and in order to allow other users to use it, privileges must be granted.

Applications should never connect to the database as its owner or a superuser, because these users can execute any query at will, for example, modifying the schema (e.g. dropping tables) or deleting its entire content.

You may create different database users for every aspect of your application with very limited rights to database objects. The most required privileges should be granted only, and avoid that the same user can interact with the database in different use cases. This means that if intruders gain access to your database using your applications credentials, they can only effect as many changes as your application can.

You are encouraged not to implement all the business logic in the web application (i.e. your script), instead do it in the database schema using views, triggers or rules. If the system evolves, new ports will be intended to open to the database, and you have to re-implement the logic in each separate database client. Over and above, triggers can be used to transparently and automatically handle fields, which often provides insight when debugging problems with your application or tracing back transactions.


Connecting to Database

You may want to estabilish the connections over SSL to encrypt client/server communications for increased security, or you can use ssh to encrypt the network connection between clients and the database server. If either of these is used, then monitoring your traffic and gaining information about your database will be difficult for a would-be attacker.


Encrypted Storage Model

SSL/SSH protects data travelling from the client to the server, SSL/SSH does not protect the persistent data stored in a database. SSL is an on-the-wire protocol.

Once an attacker gains access to your database directly (bypassing the webserver), the stored sensitive data may be exposed or misused, unless the information is protected by the database itself. Encrypting the data is a good way to mitigate this threat, but very few databases offer this type of data encryption.

The easiest way to work around this problem is to first create your own encryption package, and then use it from within your PHP scripts. PHP can assist you in this with several extensions, such as Mcrypt and Mhash, covering a wide variety of encryption algorithms. The script encrypts the data before inserting it into the database, and decrypts it when retrieving. See the references for further examples of how encryption works.

In case of truly hidden data, if its raw representation is not needed (i.e. not be displayed), hashing may also be taken into consideration. The well-known example for the hashing is storing the MD5 hash of a password in a database, instead of the password itself. See also crypt() and md5().

Esempio 16-5. Using hashed password field

<?php

// storing password hash
$query  = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
            addslashes($username), md5($password));
$result = pg_exec($connection, $query);

// querying if user submitted the right password
$query = sprintf("SELECT 1 FROM users WHERE name='%s' AND pwd='%s';",
            addslashes($username), md5($password));
$result = pg_exec($connection, $query);

if (pg_numrows($result) > 0) {
    echo "Welcome, $username!";
}
else {
    echo "Authentication failed for $username.";
}

?>

SQL Injection

Many web developers are unaware of how SQL queries can be tampered with, and assume that an SQL query is a trusted command. It means that SQL queries are able to circumvent access controls, thereby bypassing standard authentication and authorization checks, and sometimes SQL queries even may allow access to host operating system level commands.

Direct SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to expose hidden data, or to override valuable ones, or even to execute dangerous system level commands on the database host. This is accomplished by the application taking user input and combining it with static parameters to build a SQL query. The following examples are based on true stories, unfortunately.

Owing to the lack of input validation and connecting to the database on behalf of a superuser or the one who can create users, the attacker may create a superuser in your database.

Esempio 16-6. Splitting the result set into pages ... and making superusers (PostgreSQL and MySQL)

<?php

$offset = argv[0]; // beware, no input validation!
$query  = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
// with PostgreSQL 
$result = pg_exec($conn, $query);
// with MySQL
$result = mysql_query($query);

?>
Normal users click on the 'next', 'prev' links where the $offset is encoded into the URL. The script expects that the incoming $offset is a decimal number. However, what if someone tries to break in by appending a urlencode()'d form of the following to the URL

// in case of PostgreSQL
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select 'crack', usesysid, 't','t','crack'
    from pg_shadow where usename='postgres';
--

// in case of MySQL
0;
UPDATE user SET Password=PASSWORD('crack') WHERE user='root';
FLUSH PRIVILEGES;

If it happened, then the script would present a superuser access to him. Note that 0; is to supply a valid offset to the original query and to terminate it.

Nota: It is common technique to force the SQL parser to ignore the rest of the query written by the developer with -- which is the comment sign in SQL.

A feasible way to gain passwords is to circumvent your search result pages. The only thing the attacker needs to do is to see if there are any submitted variables used in SQL statements which are not handled properly. These filters can be set commonly in a preceding form to customize WHERE, ORDER BY, LIMIT and OFFSET clauses in SELECT statements. If your database supports the UNION construct, the attacker may try to append an entire query to the original one to list passwords from an arbitrary table. Using encrypted password fields is strongly encouraged.

Esempio 16-7. Listing out articles ... and some passwords (any database server)

<?php

$query  = "SELECT id, name, inserted, size FROM products
                  WHERE size = '$size'
                  ORDER BY $order LIMIT $limit, $offset;";
$result = odbc_exec($conn, $query);

?>
The static part of the query can be combined with another SELECT statement which reveals all passwords:

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--

If this query (playing with the ' and --) were assigned to one of the variables used in $query, the query beast awakened.

SQL UPDATE's are also susceptible to attack. These queries are also threatened by chopping and appending an entirely new query to it. But the attacker might fiddle with the SET clause. In this case some schema information must be possessed to manipulate the query successfully. This can be acquired by examining the form variable names, or just simply brute forcing. There are not so many naming conventions for fields storing passwords or usernames.

Esempio 16-8. From resetting a password ... to gaining more privileges (any database server)

<?php
$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>
But a malicious user sumbits the value ' or uid like'%admin%'; -- to $uid to change the admin's password, or simply sets $pwd to "hehehe', admin='yes', trusted=100 " (with a trailing space) to gain more privileges. Then, the query will be twisted:

<?php

// $uid == ' or uid like'%admin%'; --
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --";

// $pwd == "hehehe', admin='yes', trusted=100 "
$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE
...;";

?>

A frightening example how operating system level commands can be accessed on some database hosts.

Esempio 16-9. Attacking the database hosts operating system (MSSQL Server)

<?php

$query  = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);

?>
If attacker submits the value a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- to $prod, then the $query will be:

<?php

$query  = "SELECT * FROM products
                    WHERE id LIKE '%a%'
                    exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);

?>

MSSQL Server executes the SQL statements in the batch including a command to add a new user to the local accounts database. If this application were running as sa and the MSSQLSERVER service is running with sufficient privileges, the attacker would now have an account with which to access this machine.

Nota: Some of the examples above is tied to a specific database server. This does not mean that a similar attack is impossible against other products. Your database server may be similarly vulnerable in another manner.


Avoiding techniques

You may plead that the attacker must possess a piece of information about the database schema in most examples. You are right, but you never know when and how it can be taken out, and if it happens, your database may be exposed. If you are using an open source, or publicly available database handling package, which may belong to a content management system or forum, the intruders easily produce a copy of a piece of your code. It may be also a security risk if it is a poorly designed one.

These attacks are mainly based on exploiting the code not being written with security in mind. Never trust any kind of input, especially that which comes from the client side, even though it comes from a select box, a hidden input field or a cookie. The first example shows that such a blameless query can cause disasters.

  • Never connect to the database as a superuser or as the database owner. Use always customized users with very limited privileges.

  • Check if the given input has the expected data type. PHP has a wide range of input validating functions, from the simplest ones found in Variable Functions and in Character Type Functions (e.g. is_numeric(), ctype_digit() respectively) and onwards to the Perl compatible Regular Expressions support.

  • If the application waits for numerical input, consider verifying data with is_numeric(), or silently change its type using settype(), or use its numeric representation by sprintf().

    Esempio 16-10. A more secure way to compose a query for paging

    <?php
    
    settype($offset, 'integer');
    $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
    
    // please note %d in the format string, using %s would be meaningless
    $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;",
                     $offset);
    
    ?>

  • Quote each non numeric user input which is passed to the database with addslashes() or addcslashes(). See the first example. As the examples shows, quotes burnt into the static part of the query is not enough, and can be easily cracked.

  • Do not print out any database specific information, especially about the schema, by fair means or foul. See also Error Reporting and Error Handling and Logging Functions.

  • You may use stored procedures and previously defined cursors to abstract data access so that users do not directly access tables or views, but this solution has another impacts.

Besides these, you benefit from logging queries either within your script or by the database itself, if it supports logging. Obviously, the logging is unable to prevent any harmful attempt, but it can be helpful to trace back which application has been circumvented. The log is not useful by itself, but through the information it contains. More detail is generally better than less.


Error Reporting

With PHP security, there are two sides to error reporting. One is beneficial to increasing security, the other is detrimental.

A standard attack tactic involves profiling a system by feeding it improper data, and checking for the kinds, and contexts, of the errors which are returned. This allows the system cracker to probe for information about the server, to determine possible weaknesses. For example, if an attacker had gleaned information about a page based on a prior form submission, they may attempt to override variables, or modify them:

Esempio 16-11. Attacking Variables with a custom HTML page

<form method="post" action="attacktarget?username=badfoo&amp;password=badfoo">
<input type="hidden" name="username" value="badfoo" />
<input type="hidden" name="password" value="badfoo" />
</form>

The PHP errors which are normally returned can be quite helpful to a developer who is trying to debug a script, indicating such things as the function or file that failed, the PHP file it failed in, and the line number which the failure occured in. This is all information that can be exploited. It is not uncommon for a php developer to use show_source(), highlight_string(), or highlight_file() as a debugging measure, but in a live site, this can expose hidden variables, unchecked syntax, and other dangerous information. Especially dangerous is running code from known sources with built-in debugging handlers, or using common debugging techniques. If the attacker can determine what general technique you are using, they may try to brute-force a page, by sending various common debugging strings:

Esempio 16-12. Exploiting common debugging variables

<form method="post" action="attacktarget?errors=Y&amp;showerrors=1&amp;debug=1">
<input type="hidden" name="errors" value="Y" />
<input type="hidden" name="showerrors" value="1" />
<input type="hidden" name="debug" value="1" />
</form>

Regardless of the method of error handling, the ability to probe a system for errors leads to providing an attacker with more information.

For example, the very style of a generic PHP error indicates a system is running PHP. If the attacker was looking at an .html page, and wanted to probe for the back-end (to look for known weaknesses in the system), by feeding it the wrong data they may be able to determine that a system was built with PHP.

A function error can indicate whether a system may be running a specific database engine, or give clues as to how a web page or programmed or designed. This allows for deeper investigation into open database ports, or to look for specific bugs or weaknesses in a web page. By feeding different pieces of bad data, for example, an attacker can determine the order of authentication in a script, (from the line number errors) as well as probe for exploits that may be exploited in different locations in the script.

A filesystem or general PHP error can indicate what permissions the webserver has, as well as the structure and organization of files on the web server. Developer written error code can aggravate this problem, leading to easy exploitation of formerly "hidden" information.

There are three major solutions to this issue. The first is to scrutinize all functions, and attempt to compensate for the bulk of the errors. The second is to disable error reporting entirely on the running code. The third is to use PHP's custom error handling functions to create your own error handler. Depending on your security policy, you may find all three to be applicable to your situation.

One way of catching this issue ahead of time is to make use of PHP's own error_reporting(), to help you secure your code and find variable usage that may be dangerous. By testing your code, prior to deployment, with E_ALL, you can quickly find areas where your variables may be open to poisoning or modification in other ways. Once you are ready for deployment, by using E_NONE, you insulate your code from probing.

Esempio 16-13. Finding dangerous variables with E_ALL

<?php
if ($username) {  // Not initialized or checked before usage
    $good_login = 1;
}
if ($good_login == 1) { // If above test fails, not initialized or checked before usage
    readfile ("/highly/sensitive/data/index.html");
}
?>


Using Register Globals

Perhaps the most controversial change in PHP is when the default value for the PHP directive register_globals went from ON to OFF in PHP 4.2.0. Reliance on this directive was quite common and many people didn't even know it existed and assumed it's just how PHP works. This page will explain how one can write insecure code with this directive but keep in mind that the directive itself isn't insecure but rather it's the misuse of it.

When on, register_globals will inject (poison) your scripts will all sorts of variables, like request variables from HTML forms. This coupled with the fact that PHP doesn't require variable initialization means writing insecure code is that much easier. It was a difficult decision, but the PHP community decided to disable this directive by default. When on, people use variables yet really don't know for sure where they come from and can only assume. Internal variables that are defined in the script itself get mixed up with request data sent by users and disabling register_globals changes this. Let's demonstrate with an example misuse of register_globals:

Esempio 16-14. Example misuse with register_globals = on

<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
    $authorized = true;
}

// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
    include "/highly/sensitive/data.php";
}
?>

When register_globals = on, our logic above may be compromised. When off, $authorized can't be set via request so it'll be fine, although it really is generally a good programming practice to initialize variables first. For example, in our example above we might have first done $authorized = false. Doing this first means our above code would work with register_globals on or off as users by default would be unauthorized.

Another example is that of sessions. When register_globals = on, we could also use $username in our example below but again you must realize that $username could also come from other means, such as GET (through the URL).

Esempio 16-15. Example use of sessions with register_globals on or off

<?php
// We wouldn't know where $username came from but do know $_SESSION is
// for session data
if (isset($_SESSION['username'])) {

    echo "Hello <b>{$_SESSION['username']}</b>";

} else {

    echo "Hello <b>Guest</b><br />";
    echo "Would you like to login?";

}
?>

It's even possible to take preventative measures to warn when forging is being attempted. If you know ahead of time exactly where a variable should be coming from, you can check to see if the submitted data is coming from an inappropriate kind of submission. While it doesn't guarantee that data has not been forged, it does require an attacker to guess the right kind of forging. If you don't care where the request data comes from, you can use $_REQUEST as it contains a mix of GET, POST and COOKIE data. See also the manual section on using variables from outside of PHP.

Esempio 16-16. Detecting simple variable poisoning

<?php
if (isset($_COOKIE['MAGIC_COOKIE'])) {

    // MAGIC_COOKIE comes from a cookie.
    // Be sure to validate the cookie data!

} elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) {

   mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']);
   echo "Security violation, admin has been alerted.";
   exit;

} else {

   // MAGIC_COOKIE isn't set through this REQUEST

}
?>

Of course, simply turning off register_globals does not mean your code is secure. For every piece of data that is submitted, it should also be checked in other ways. Always validate your user data and initialize your variables! To check for unitialized variables you may turn up error_reporting() to show E_NOTICE level errors.

Matrici superglobali: note di disponibilità: A partire da PHP 4.1.0, sono disponibili le matrici superglobali quali $_GET , $_POST, e $_SERVER, ecc. Per maggiori dettagli, si rimanda al capitolo superglobals del manuale


User Submitted Data

The greatest weakness in many PHP programs is not inherent in the language itself, but merely an issue of code not being written with security in mind. For this reason, you should always take the time to consider the implications of a given piece of code, to ascertain the possible damage if an unexpected variable is submitted to it.

Esempio 16-17. Dangerous Variable Usage

<?php
// remove a file from the user's home directory... or maybe
// somebody else's?
unlink ($evil_var);

// Write logging of their access... or maybe an /etc/passwd entry?
fwrite ($fp, $evil_var);

// Execute something trivial.. or rm -rf *?
system ($evil_var);
exec ($evil_var);

?>
You should always carefully examine your code to make sure that any variables being submitted from a web browser are being properly checked, and ask yourself the following questions:

  • Will this script only affect the intended files?

  • Can unusual or undesirable data be acted upon?

  • Can this script be used in unintended ways?

  • Can this be used in conjunction with other scripts in a negative manner?

  • Will any transactions be adequately logged?

By adequately asking these questions while writing the script, rather than later, you prevent an unfortunate re-write when you need to increase your security. By starting out with this mindset, you won't guarantee the security of your system, but you can help improve it.

You may also want to consider turning off register_globals, magic_quotes, or other convenience settings which may confuse you as to the validity, source, or value of a given variable. Working with PHP in error_reporting(E_ALL) mode can also help warn you about variables being used before they are checked or initialized (so you can prevent unusual data from being operated upon).


Hiding PHP

In general, security by obscurity is one of the weakest forms of security. But in some cases, every little bit of extra security is desirable.

A few simple techniques can help to hide PHP, possibly slowing down an attacker who is attempting to discover weaknesses in your system. By setting expose_php = off in your php.ini file, you reduce the amount of information available to them.

Another tactic is to configure web servers such as apache to parse different filetypes through PHP, either with an .htaccess directive, or in the apache configuration file itself. You can then use misleading file extensions:

Esempio 16-18. Hiding PHP as another language

# Make PHP code look like other code types
AddType application/x-httpd-php .asp .py .pl
Or obscure it completely:

Esempio 16-19. Using unknown types for PHP extensions

# Make PHP code look like unknown types
AddType application/x-httpd-php .bop .foo .133t
Or hide it as HTML code, which has a slight performance hit because all HTML will be parsed through the PHP engine:

Esempio 16-20. Using HTML types for PHP extensions

# Make all PHP code look like HTML
AddType application/x-httpd-php .htm .html
For this to work effectively, you must rename your PHP files with the above extensions. While it is a form of security through obscurity, it's a minor preventative measure with few drawbacks.


Keeping Current

PHP, like any other large system, is under constant scrutiny and improvement. Each new version will often include both major and minor changes to enhance and repair security flaws, configuration mishaps, and other issues that will affect the overall security and stability of your system.

Like other system-level scripting languages and programs, the best approach is to update often, and maintain awareness of the latest versions and their changes.


Capitolo 17. Autenticazione HTTP usando PHP

I meccanismi di Autenticazione HTTP sono disponibili in PHP solo quando questo viene usato come un modulo di Apache ed esso non è quindi disponibile nella versione CGI. In uno script PHP modulo di Apache, è possibile usare la funzione header() per inviare un messaggio di "Authentication Required" al browser dell'utente, provocando quindi l'apertura di una finestra contenente una richiesta di Nome utente/Password. Una volta che l'utente ha compilato i campi nome utente e password, l'URL contenente lo script PHP verrà richiamato nuovamente usando le variabili predefinite, PHP_AUTH_USER, PHP_AUTH_PW e PHP_AUTH_TYPE impostate con, rispettivamente: nome, password e tipo di autenticazione. Queste variabili predefinite possono essere trovate negli array $_SERVER e $HTTP_SERVER_VARS. Solamente il tipo di autenticazione "Basic" è al momento supportato. Fare riferimento alla funzione header() per ulteriori informazioni.

Nota sulla versione di PHP: Le variabili autoglobali, come $_SERVER, esistono in PHP dalla versione 4.1.0. $HTTP_SERVER_VARS è disponibile a partire da PHP 3.

Un frammento di script di esempio che richiede l'autenticazione da parte del browser su una pagina, potrebbe essere il seguente:

Esempio 17-1. Esempio di Autenticazione HTTP

<?php
  if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="Il mio realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Messaggio da inviare se si preme il tasto Cancel';
    exit;
  } else {
    echo "<p>Ciao {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo "<p>Hai inserito {$_SERVER['PHP_AUTH_PW']} come tua password.</p>";
  }
?>

Note sulla compatibilità: Fare molta attenzione quando si scrive codice per le intestazioni HTTP. Per ottenere la massima compatibilità con tutti i client, la paorla-chiave "Basic" deve essere scritta con una "B" maiuscola, la stringa realm deve essere racchiusa in virgolette doppie (non singole), ed esattamente uno spazio deve precedere il codice 401 nella linea di intestazione HTTP/1.0 401.

Invece di stampare semplicemente PHP_AUTH_USER e PHP_AUTH_PW, probabilmente si vorrà controllare la validità dello username e della password. Probabilmente inviando una chiamata al database, o cercando un utente in un file dbm.

Si faccia attenzione ad alcune versioni di Internet Explorer. Sembra che siano molto schizzinosi riguardo all'ordine delle intestazioni. Inviare l'intestazione WWW-Authenticate prima dell'intestazione HTTP/1.0 401 sembra sistemare le cose per il momento.

Al fine di prevenire che qualcuno scriva uno script che rivela la password di una pagina che era stata autenticata tramite un tradizionale meccanismo esterno, le variabili PHP_AUTH non verranno impostate se è abilitata l'autenticazione esterna per quella determinata pagina. In questo caso, la variabile REMOTE_USER può essere usata per identificare un utente autenticato esternamente. Così, $_SERVER['REMOTE_USER'].

Nota sulla Configurazione: PHP usa la presenza di una direttiva AuthType per determinare se viene utilizzata l'autenticazione esterna. Evitare questa direttiva nel contesto dove si intende usare l'autenticazione con PHP (altrimenti ogni tentativo di autenticazione fallirà).

Si fa notare, però, che quanto scritto sopra non impedisce a qualcuno che controlla un URL non autenticato di sottrarre password da URL autenticati presenti sullo stesso server.

Sia Netscape Navigator che Internet Explorer cancellano la cache locale della finestra del browser, per quanto riguarda il realm, al ricevimento di una risposta 401 da parte del server. Questo è effettivamente un meccanismo di "log out" per l'utente, che lo forza a reinserire lo username e la password. Alcune persone usano questo per fare il "time out" dei login, o per rendere disponibili bottoni di "log-out".

Esempio 17-2. Esempio di Autenticazione HTTP che impone l'inserimento di nuovo username/password

<?php
  function authenticate() {
    header('WWW-Authenticate: Basic realm="Prova del Sistema di Autenticazione"');
    header('HTTP/1.0 401 Unauthorized');
    echo "Per poter accedere a questa risorsa occorre inserire una coppia login e password valide\n";
    exit;
  }
 
  if (!isset($_SERVER['PHP_AUTH_USER']) || ($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
   authenticate();
  } 
  else {
   echo "<p>Benvenuto: {$_SERVER['PHP_AUTH_USER']}<br>";
   echo "Vecchio: {$_REQUEST['OldAuth']}";
   echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='POST'>\n";
   echo "<input type='hidden' name='SeenBefore' value='1'>\n";
   echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}'>\n";
   echo "<input type='submit' value='Ri autentifica'>\n";
   echo "</form></p>\n";
  }
?>

Questo comportamento non è richiesto dallo standard di autenticazione HTTP Basic, quindi non si dovrebbe mai fare affidamento su di esso. Test effettuati con Lynx mostrano che Lynx non cancella le credenziali di autenticazione al ricevimento del codice di risposta 401 da parte del server, quindi, premendo indietro e avanti nuovamente, darà nuovamente accesso alla risorsa, ammesso che le rispettive richieste di credenziali non siano cambiate. L'utente può però premere il tasto '_' al fine di cancellare le sue informazioni di autenticazione.

Si noti anche che questo non funziona con il server IIS di Microsoft e con la versione CGI di PHP a causa di una limitazione di IIS.

Nota: Se è abilitato safe mode viene aggiunto lo uid dello script al realm dell'header WWW-Authenticate.


Capitolo 18. Cookies

PHP supporta in modo trasparente i cookies HTTP. I cookies sono un meccanismo per memorizzare dati nel browser remoto e tenere traccia degli utenti o identificarli al loro ritorno. I cookies possono essere impostati tramite la funzione setcookie(). I cookies sono parte dell'intestazione HTTP, quindi setcookie() deve essere chiamata prima che qualsiasi output sia inviato al browser. Si tratta della stessa limitazione della funzione header(). Si può utilizzare la funzione di buffer dell'output per posticipare l'output dello script finchè non avete stabilito se impostare o meno qualsiasi cookies o l''invio di header.

Ogni cookie inviato dal client sarà automaticamente trasformato in una variabile PHP, come avviene nel caso di dati GET o POST, in base alle variabili di configurazione register_globals e variables_order. Se si vogliono assegnare più valori ad un singolo cookie, basta aggiungere [] al nome del cookie.

Nel PHP 4.1.0 e successivi, il vettore auto-globale $_COOKIE sarà sempre impostato con qualsiasi cookies inviati dal client. $HTTP_COOKIE_VARS è anch'essa impostata nelle versioni precedenti del PHP se è impostata la variabile di configurazione track_vars. (Questo parametro è sempre a on a partire da PHP 4.0.3.)

Per maggiori dettagli si veda la funzione setcookie().


Capitolo 19. Dealing with XForms

XForms defines a variation on traditional webforms which allows them to be used on a wider variety of platforms and browsers or even non-traditional media such as PDF documents.

The first key difference in XForms is how the form is sent to the client. XForms for HTML Authors contains a detailed description of how to create XForms, for the purpose of this tutorial we'll only be looking at a simple example.

Esempio 19-1. A simple XForms search form

<h:html xmlns:h="http://www.w3.org/1999/xhtml"
        xmlns="http://www.w3.org/2002/xforms">
<h:head>
 <h:title>Search</h:title>
 <model>
  <submission action="http://example.com/search"
              method="post" id="s"/>
 </model>
</h:head>
<h:body>
 <h:p>
  <input ref="q"><label>Find</label></input>
  <submit submission="s"><label>Go</label></submit>
 </h:p>
</h:body>
</h:html>

The above form displays a text input box (named q), and a submit button. When the submit button is clicked, the form will be sent to the page referred to by action.

Here's where it starts to look different from your web application's point of view. In a normal HTML form, the data would be sent as application/x-www-form-urlencoded, in the XForms world however, this information is sent as XML formatted data.

If you're choosing to work with XForms then you probably want that data as XML, in that case, look in $HTTP_RAW_POST_DATA where you'll find the XML document generated by the browser which you can pass into your favorite XSLT engine or document parser.

If you're not interrested in formatting and just want your data to be loaded into the traditional $_POST variable, you can instruct the client browser to send it as application/x-www-form-urlencoded by changing the method attribute to urlencoded-post.

Esempio 19-2. Using an XForm to populate $_POST

<h:html xmlns:h="http://www.w3.org/1999/xhtml"
        xmlns="http://www.w3.org/2002/xforms">
<h:head>
 <h:title>Search</h:title>
 <model>
  <submission action="http://example.com/search"
              method="urlencoded-post" id="s"/>
 </model>
</h:head>
<h:body>
 <h:p>
  <input ref="q"><label>Find</label></input>
  <submit submission="s"><label>Go</label></submit>
 </h:p>
</h:body>
</h:html>

Nota: As of this writing, many browsers do not support XForms. Check your browser version if the above examples fails.


Capitolo 20. Caricare file

Metodo POST per caricamento di file

PHP è in grado di ricevere file caricati da qualsiasi browser compatibile con le specifiche RFC-1867 (che comprende Netscape Navigator 3 o successivo, Microsoft Internet Explorer 3 con una modifica di Microsoft, o versioni successive senza modifica). Questa caratteristica permette di caricare sia file di testo che binari. Utilizzando le funzioni di PHP per l'autenticazione e manipolazione dei file, è possibile avere pieno controllo su chi ha i permessi per caricare un file e su ciò che deve essere fatto una volta che il file è stato caricato.

Note relative alla configurazione: Si vedano i parametri file_uploads, upload_max_filesize, upload_tmp_dir, e post_max_size nel php.ini

Si noti che PHP permette l'upload di file con metodo PUT come utilizzato dai programmi Netscape Composer e W3C Amaya. Si veda Supporto per metodo PUT per maggiori dettagli.

La schermata di caricamento di un file può essere costruita con una form particolare, di questo tipo:

Esempio 20-1. Form di caricamento file

<form enctype="multipart/form-data" action="_URL_" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
Invia questo file: <input name="userfile" type="file">
<input type="submit" value="Invia File">
</form>
Il valore della action _URL_ dovrebbe puntare a un file PHP. Il campo nascosto MAX_FILE_SIZE deve precedere il campo di immissione del file e il suo valore è la dimensione massima accettata del file. Il valore è in byte.

Avvertimento

Il valore MAX_FILE_SIZE è consigliato al browser. E' facile aggirare questo valore, quindi non fate affidamento sul fatto che il navigatore si comporti come desiderato! L'impostazione PHP lato server per la dimensione massima non può comunque essere aggirata. Tuttavia si può comunque inserire MAX_FILE_SIZE per evitare all'utente di attendere il trasferimento di un file prima di scoprire che è di dimensioni eccessive.

Le variabili definite per i file inviati differiscono in base alla versione di PHP ed alla configurazione. La variabile globale $_FILES esiste a partire dalla versione 4.1.0 di PHP. La matrice $HTTP_POST_FILES esiste dalla versione 4.0.0. Tutte queste matrici conterranno tutte le informazioni dei file inviati. Si consiglia di preferire l'uso di $_FILES. Se il parametro register_globals è impostato a on, esisteranno anche le relative variabili. Attenzione che per default il parametro register_globals viene impostato a off dalla versione 4.2.0 di PHP.

Di seguito verrà illustrato il contenuto di $_FILES nel caso dell'esempio precedente. Si noti che si assume come nome del file inviato userfile, come nell'esempio precedente.

$_FILES['userfile']['name']

Il nome originale del file sulla macchina dell'utente.

$_FILES['userfile']['type']

Il mime-type del file, se il browser fornisce questa informazione. Un esempio potrebbe essere "image/gif".

$_FILES['userfile']['size']

La dimensione, in bytes, del file caricato.

$_FILES['userfile']['tmp_name']

Il nome del file temporaneo in cui il file caricato è salvato sul server.

$_FILES['userfile']['error']

Il codice di errore associato all'upload di questo file. Il campo ['error'] è stato aggiunto nella versione 4.2.0 di PHP.

Nota: Nelle versioni di PHP precedenti alla 4.1.0 questa variabile era chiamata $HTTP_POST_FILES e non era una variabile autoglobal come è $_FILES. La versione 3 di PHP non supporta $HTTP_POST_FILES.

Quando register_globals è impostato a on nel php.ini, sono disponibili variabili addizionali. Da esempio, $userfile_name sarà uguale a $_FILES['userfile']['name'], $userfile_type sarà uguale a $_FILES['userfile']['type'], eccetera. Si ricordi che a partire dalla versione 4.2.0 di PHP il parametro register_globals viene impostato a off per default. E' preferibile non fare affidamento su questo parametro.

I file sono, di default, salvati in una directory temporanea sul server, a meno che un diverso percorso sia specificato nella direttiva upload_tmp_dir nel file php.ini. La directory del server predefinita può essere cambiata impostando la variabile di ambiente TMPDIR in cui è in esecuzione PHP. Non è possibile impostare questa variabile utilizzando la funzione putenv() da uno script PHP. Questa variabile di ambiente può anche essere usata per assicurarsi che anche altre operazioni stiano lavorando sui file caricati.

Esempio 20-2. Verifica dell'upload di file

Si vedano le definizioni delle funzioni is_uploaded_file() e move_uploaded_file() per maggiori dettagli. L'esempio seguente illustra il processamento di un file inviato tramite un form.

<?php
// Nelle versioni di PHP precedenti alla 4.1.0 si deve utilizzare  $HTTP_POST_FILES anzichè $_FILES.
// Nelle versioni di PHP precedenti alla 4.0.3, si utilizzi copy() e is_uploaded_file() anzichè move_uploaded_file

$uploaddir = '/var/www/uploads/';
print "<pre>";
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) { 
    print "Il file è valido, e inviato con successo.  Ecco alcune informazioni:\n"; 
    print_r($_FILES);
} else {
    print "Possibile attacco tramite file upload! Alcune informazioni:\n"; 
    print_r($_FILES);
}
 
?>

Lo script PHP che riceve il file caricato dovrebbe implementare la logica necessaria per determinare cosa deve essere fatto con il file caricato. E' possibile, per esempio, utilizzare la variabile $_FILES['userfile']['size'] per eliminare file che siano troppo grandi o troppo piccoli. E' possibile utillizzare la variabile $_FILES['userfile']['type'] per eliminare tutti i file che non soddisfano certi criteri. A partire da PHP 4.2.0, si può utilizzare $_FILES['userfile']['error'] ed organizzare la logica in base ai codici di errore. Quale che sia la logica, bisognerebbe comunque sempre cancellare il file dalla directory temporanea e spostarlo da qualche altra parte.

Il file sarà eliminato dalla directory temporanea al termine della richiesta se non è stato mosso e rinominato.


Spiegazione dei messaggi di errore

Dalla versione 4.2.0, il PHP restituisce un codice di errore nella matrice del file. Il codice di errore si trova nell'indice ['error'] e viene valorizzato durante l'upload del file da parte del PHP. In altre parole l'errore può essere trovato in $_FILES['userfile']['error'].

UPLOAD_ERR_OK

Valore: 0; Non vi sono errori, l'upload è stato eseguito con successo.

UPLOAD_ERR_INI_SIZE

Valore: 1; Il file inviato eccede le dimensioni specificate nel parametro upload_max_filesize di php.ini.

UPLOAD_ERR_FORM_SIZE

Valore: 2; Il file inviato eccede le dimensioni specificate nel parametro MAX_FILE_SIZE del form.

UPLOAD_ERR_PARTIAL

Valore: 3; Upload eseguito parzialmente.

UPLOAD_ERR_NO_FILE

Valore: 4; Nessun file è stato inviato.

Nota: Questi valori sono diventate costanti PHP a partire dal PHP 4.3.0.


Common Pitfalls

La voce MAX_FILE_SIZE non può specificare una dimensione del file maggiore di quella impostata dal parametro upload_max_filesize del file php.ini. L'impostazione di default è 2 Megabytes.

Se si è impostato un limite di memoria memory_limit può essere necessario ampliarlo. Occorre essere certi di impostare memory_limit alle dimensioni appropriate.

Se max_execution_time è impostato ad un valore basso, l'esecuzione dello script può eccedere tale valore. Ampliare max_execution_time ad un tempo sufficiente per l'upload.

Nota: max_execution_time influisce solo sul tempo di esecuzione dello script. Il tempo utilizzato per attività esterno allo script, tipo le chiamate di sistema system(), o la funzione sleep(), le query nei database, il tempo inpiegato nell'upload del file non è considerato nel computo del tempo di esecuzione dello script.

Se post_max_size è impostato ad un valore troppo piccolo, non si può inviare file di grosse dimensioni. Impostare post_max_size alle dimensioni appropriate.

Non controllare il file su cui si sta operando potrebbe dare agli utenti accesso a informazioni sensibili contenute in altre directory.

Si noti che che il server http CERN sembra eliminare qualsiasi cosa a partire dal primo spazio nell'header mime content-type che riceve dal client. Fino a che questo si verificherà, il server http CERN non supporterà la possibilità di caricare file.

A causa della varietà di formati di directory, non si è in grado di garantire che nomi di file strani (ad esempio contenenti spazi) siano gestiti correttamente.


Caricamento di più file

E' possibile inviare più file contemporanemante utilizzando in input nomi differenti.

E' possibile caricare più file contemporaneamente e avere le informazioni organizzate automaticamente in array. Per questo è necessario utilizzare la medesima sintassi di invio di array da form HTML che è utilizzata con select e checkbox multipli:

Nota: Il supporto per il caricamento di file multipli è presente dalla versione 3.0.10.

Esempio 20-3. Caricamento di più file

<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Send these files:<br>
  <input name="userfile[]" type="file"><br>
  <input name="userfile[]" type="file"><br>
  <input type="submit" value="Send files">
</form>

Quando la form è inviata, gli array $_FILES['userfile'], $_FILES['userfile']['name'], e $_FILES['userfile']['size'] saranno inizializzati (come sarà valorizzato $HTTP_POST_FILES per le versioni di PHP precedenti la 4.1.0). Quando il parametro register_globals è impostato a on saranno presenti anche le variabili globali. Ognuno di questi è un array indicizzato numericamente con i valori relativi ai diversi file caricati.

Per esempio, si supponga che i nomi di file /home/test/review.html e /home/test/xwp.out siano inviati. In questo caso, $_FILES['userfile']['name'][0] conterrebbe il valore review.html, e $_FILES['userfile']['name'][1] conterrebbe il valore xwp.out. Analogamente, $_FILES['userfile']['size'][0] conterrebbe la dimensione di review.html, e così via.

Anche $_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0], e $_FILES['userfile']['type'][0] sono impostati.


Supporto per metodo PUT

Il supporto al metodo PUT è cambiato tra PHP 3 e PHP 4. In PHP 4 occorre utilizzare il flusso standard di input per leggere il contenuto di un PUT HTTP.

Esempio 20-4. Salvataggio di un file HTTP PUT con PHP 4

<?php
/* I dati PUT arrivano in stdin */
$putdata = fopen("php://stdin","r");
 
/* Apertura del file in scrittura */
$fp = fopen("myputfile.ext","w");
/* Lettura dei dati d 1kb alla volta e scrittura nel file */
while ($data = fread($putdata,1024))
  fwrite($fp,$data);
 
/* Chiusura */
fclose($fp);
fclose($putdata);
?>

Nota: Tutta la documentazione che segue si applica solo a PHP 3.

PHP fornisce supporto per il metodo HTTP PUT utilizzato da programmi come Netscape Composer e W3C Amaya. Le richieste PUT sono molto più semplici rispetto al caricamento di un file, e assomigliano a

PUT /percorso/nomefile.html HTTP/1.1

Questo significa che normalmente il programma remoto intende salvare il contenuto della richesta come : /percorso/nomefile.html nel filesystem sul server web. Non è ovviamente una buona idea per Apache o PHP lasciare a un qualsiasi utente la possibilità di sovrascrivere file sul server web. Quindi, per gestire questa richiesta si deve chiedere al server web che si vuole che sia un certo script PHP a gestire la richiesta stessa. In Apache si ottiene questo con la direttiva Script. Può essere posta quasi ovunque nel file di configurazione di Apache. Un posto frequente è all'interno di un blocco <Directory> oppurte all'interno del blocco <Virtualhost>. Un linea come la seguente è sufficiente:

Script PUT /put.php

Questo chiede ad Apache di inviare tutte le richieste PUT che soddisfano il contesto in cui si è inserito questo comando allo script put.php. Questo richiede, naturalmente, che sia abilitato PHP per l'estensione .php e che PHP sia attivo.

All'interno del file put.php si può inserire qualcosa del tipo:

<?php copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI); ?>

Questo copia il file nella posizione chiesta dal programma remoto. E' probabile che si vogliano effettuare dei controlli o autenticazioni dell'utente prima di effettuare questa copia. L'unica magia qui presente è che quando PHP vede una richiesta con metodo PUT memorizza il file caricato in un file temporaneo così come per i file caricati con il metodo POST. Quando la richiesta termina, questo file temporaneo è eliminato. Quindi il gestore della richiesta PUT deve copiare il file da qualche parte. Il nome del file temporaneo è memorizzato nella variabile $PHP_PUT_FILENAME, ed è possibile vedere il nome del file di destinazione nella variabile $REQUEST_URI (potrebbe variare su web server diversi da Apache). Qusto nome di file di destinazione è quello specificato dal client remoto. Non è necessario seguire le indicazioni del client. E' possibile, per esempio, copiare tutti i file caricati in una apposita directory.


Capitolo 21. Utilizzo di file remoti

Se allow_url_fopen è abilitato in php.ini, si possono usare URL FTP e HTTP con la maggior parte delle funzioni che richiedono nomi di file come parametri, incluse le funzioni require(), require_once(), include() e include_once(). Vedere Appendice L per maggiori dettagli sui protocolli supportati dal PHP.

Nota: In PHP 4.0.3 e precedenti, al fine di poter utilizzare gli URL wrapper, occorreva specificare l'opzione di configurazione --enable-url-fopen-wrapper.

Nota: Al momento, le versioni Windows di PHP precedenti la 4.3, non supportano l'accesso remoto ai file con le seguenti funzioni: include(), include_once(), require() e require_once() e le funzioni imagecreatefromXXX del modulo Riferimento XLII, Funzioni per le immagini.

Per esempio, si può usare per aprire un file da un web server remoto, elaborare i dati presi da remoto, e usarli per effetuare delle query, o semplicemente visualizzarli con lo stile del proprio sito web.

Esempio 21-1. Leggere il titolo di una pagina web remota

<?php
$file = fopen ("http://www.example.com/", "r");
if (!$file) {
    echo "<p>Impossibile aprire il file remoto.\n";
    exit;
}
while (!feof ($file)) {
    $linea = fgets ($file, 1024);
    /* Funziona solo se title e i relativi tag sono sulla medesima riga */
    if (eregi ("<title>(.*)</title>", $linea, $out)) {
        $title = $out[1];
        break;
    }
}
fclose($file);
?>

Si può anche scrivere in un file remoto via FTP (se l'utente con cui ci si connette ha le autorizzazioni necessarie). Si possono solamente creare nuovi file usando questo metodo, se si prova a sovrascrivere un file che già esiste, fopen() non avrà successo.

Per connettersi con un utenti diversi da 'anonymous' si ha bisogno di specificare lo username (e la relativa password) assieme all'URL, in questo modo: 'ftp://user:password@ftp.example.com/directory/del/file'. (Si può usare lo stesso tipo di sintassi per accedere a file via HTTP quando richiedono autenticazione Basic).

Esempio 21-2. Salvataggio di dati su server remoto

<?php
$file = fopen ("ftp://ftp.example.com/incoming/outputfile", "w");
if (!$file) {
    echo "<p>Impossibile aprire il file remoto in scrittura.\n";
    exit;
}
/* Scrive i dati qui. */
fputs ($file, $_SERVER['HTTP_USER_AGENT'] . "\n");
fclose ($file);
?>

Nota: Dall'esempio precedente ci si può fare un'idea di come usare questa tecnica per effettuare dei log in remoto, ma come già accennato, con questo sitema non è possibile scrivere con fopen() su file già esistenti. Per fare una procedura di log distribuito è più indicata la funzione syslog().


Capitolo 22. Gestione della connessione

Nota: Le seguenti note si applicano a partire dalla versione 3.0.7.

Internamente il PHP mantiene lo stato della connessione. Si hanno 3 possibili stati:

  • 0 - NORMAL

  • 1 - ABORTED

  • 2 - TIMEOUT

Quendo uno script PHP viene eseguito normalmente si trova nello stato NORMAL. Se il client remoto si disconnette viene attivato il flag ABORTED. La disconnessione di un client remoro è generalmente causata dalla pressione del tasto STOP da parte dell'utente. Se invece si raggiunge il limite di tempo imposto dal PHP (vedere set_time_limit()) si attiva lo stato TIMEOUT.

Si può decidere se la disconnessione del client debba fare abortire lo script o meno. In certi casi è più pratico lasciare finire lo script anche se non c'è più il browser remoto a ricevere i dati. Tuttavia il comportamento di default è di fare abortire lo script quando il client remoto si disconnette. Questo comportamento può essere impostato tramite la direttiva di php.ini ignore_user_abort oppure tramite la corrispondente direttiva "php_value ignore_user_abort" del file .conf di Apache oppure con la funzione ignore_user_abort(). Se non si segnala al PHP di ignorare la disconssessione dell'utente lo script sarà interrotto. Unica eccezione si ha con la registrazione di una funzione di chiusura utilizzando register_shutdown_function(). Con una funzione di shutdown, quando l'utente remoto preme il bottone di STOP, alla prima occasione in cui lo script tenterà di produrre un output, il PHP intercetterà che la connessione è interrotta e richiamerà la funzione di shutdown. Questa funzione sarà richiamata anche al normale termine dello script, pertanto per eseguire passi differenti in caso di disconnessione del client occorre utilizzare la funzione connection_aborted(). Questa funzione restituisce TRUE se la connessione è stata interrotta.

Uno script può essere fermato dal timer incorporato nel PHP. Per default il timeout è impostato a 30 secondi. Tale limite può essere variato agendo sulla direttiva max_execution_time nel php.ini o nel corrispondente parametro "php_value max_execution_time" nella configurazione di Apache, oppure con la funzione set_time_limit(). Quando termina il tempo impostato lo script viene interrotto, se è stata prevista una funzione di shutdown, questa verrà eseguita. All'interno di questa funzione si può discriminare se è stata attivata per lo scadere del timeout utilizzando la funzione connection_timeout(). Questa restituisce TRUE se la funzione di shutdown è stata chiamata per lo scadere del tempo a disposizione.

Un aspetto che occorre notare sui stati ABORTED e TIMEOUT è che possono essere attivi contemporaneamente. Questo può accadere se si è impostato il PHP affinchè ignori le interruzioni da parte dell'utente. Infatti il PHP continua a tenere traccia della disconnessione dell'utente, ma, semplicemente, non viene interrotto lo script. Quindi, quando termina il tempo, lo script sarà interrotto e verrà richiamata la funzione di shutdown, se presente. In questa situazione sia connection_timeout() sia connection_aborted() restituiranno TRUE. Si può anche verificare entrambi gli stati tramite una chiamata singola utilizzando la funzione connection_status(). Questa restituisce un campo di bit con l'indicazione degli stati attivi. Quindi, ad esempio, se entrambi gli stati sono attivi, la funzione restituirà 3.


Capitolo 23. Connessioni Persistenti ai Database

Connessioni persistenti sono collegamenti SQL che non vengono chiusi quando l'esecusione di uno script viene terminata. Quando è richiesta una connessione persistente, PHP controlla se esiste già una identica connessione persistente (che è rimasta aperta da prima) - e se esiste, la usa. Se non esiste, crea il collegamento. Una connessione 'identica' è una connessione aperta verso lo stesso host, con lo stesso username e la stessa password (dove applicabile).

Nota: Ci sono altre estensioni che permettono di usare connessioni persistenti, ad esempio l'estensione IMAP.

Chi non ha molta familiarità con il modo in cui lavorano i server web e di come essi distribuiscano il carico potrebbero confondere le connessioni permanenti per ciò che esse non sono. In particolare, non danno la possibilità di aprire 'sessioni utente' sullo stesso collegamento SQL, non danno la possibilità di gestire una transazione in maniera efficiente e sopratutto non fanno molte altre cose. Infatti, per essere molto chiari su questo punto, le connessioni persistenti non hanno nessuna funzionalià che non era disponibile con le loro omonime non-persistenti.

Perché?

Questo ha a che fare con il modo in cui i server web operano. Ci sono tre modi in cui un server web può utilizzare PHP per generare le pagine web.

Il primo metodo ` quello di usare il PHP come un "wrapper" (involucro) CGI. Quando viene eseguito in questa modalità, per ogni pagina che viene richiesta al server web che contenga del codice PHP, viene creata e, alla fine dell'esecuzione, distrutta, una istanza dell'interprete PHP. Poiché viene distrutta alla fine di ogni richiesta, qualunque risorsa abbia acquisito (come ad esempio un collegamento ad un server di database SQL) verrà anch'essa distrutta. In questo caso, non vi è nessun guadagno nell'usare le connessioni persistenti -- semplicemente esse non persistono.

Il secondo, e più popolare, metodo è quello di eseguire il programma PHP come modulo in un server web multiprocesso, cosa che attualmente include solo Apache. Un server multiprocesso ha tipicamente un processo (il padre) che coordina un insieme di processi (i suoi figli) che sono quelli che generano le pagine web. Quando arriva una richiesta da parte di un client, questa è passata ad uno dei figli che in quel momento non è già occupato a servire un altro client. Questo significa che quando lo stesso client effettua una seconda richiesta al server, esso potrà essere servito da un diverso processo figlio rispetto a quello della prima volta. In questa situazione, usare una connessione persistente, permette di stabilire una e una sola connessione al database SQL per ogni processo figlio, poiché ciascun processo figlio necessita di collegarsi al database SQL solo la prima volta che richiama una pagina che ne fa uso. Quando viene richamata un'altra pagina che necessita di una connessione al server SQL, essa può riutilizzare la connessione che lo stesso processo figlio aveva stabilito in precedenza.

L'ultimo metodo è quello di usare il PHP come una plug-in per un server web multithread. Attualmente PHP 4 supporta ISAPI, WSAPI e NSAPI (su piattaforma Windows), i quali permettono di usare PHP come una plug-in sui server web multithread come FastTrack (iPlanet) di Netscape, Internet Information Server (IIS) di Microsoft e WebSite Pro di O'Reilly. Il comportamento è essenzialmente lo stesso che si ha nel modello multiprocesso descritto prima. Si noti che il supporto SAPI non è disponibile in PHP 3.

Se le connessioni persistenti non hanno nessuna funzionalità aggiuntiva, perch´ usarle?

La risposta, in questo caso è estremamente semplice: efficienza. Le connessioni persistenti sono utili se il carico di lavoro necessario per aprire una connessione al server SQL è alto. Che il carico sia molto alto o meno dipende da molti fattori. Quali, il tipo di database che si utilizza, il fatto che esso si trovi sulla stessa macchina sulla quale si trova il server web, quanto carico di lavoro ha la macchina sulla quale si trova il server SQL, e molte altre ragioni. Il fatto importante è che se il carico di lavoro necessario per aprire le connessioni è alto, le connessioni persistenti possono aiutare in maniera considerevole. Fanno in modo che il processo figlio si colleghi semplicemente una volta durante la sua intera vita, invece di collegarsi ogni volta che processa una pagina che richiede una connessione al server SQL. Questo significa che per ogni figlio che ha aperto una connessione persistente, si avrà una nuova connessione persistente aperta verso il server. Per esempio, se si hanno 20 diversi processi figlio che eseguono uno script che crea una connessione persistente al server SQL server, si avranno 20 diverse connessioni al server SQL, una per ogni figlio.

Si fa notare, tuttavia, che questo può avere degli svantaggi se si fa uso di un database che ha un limite al numero di connessioni, minore rispetto al numero delle connessioni persistenti dei procesi figlio. Se per esempio di usa un database con 16 connessioni simultanee, e durante un periodo di intensa attività del web server, 17 processi figlio cercano di collegarsi, uno non sarà in grado di farlo. Se nei vostri script ci sono bug che non permettono alle connessioni di chiudersi in maniera regolare (come ad esempio un loop infinito), un database con sole 16 connessioni diventerà rapidamente saturo. Fare riferimento alla documentazione del database per informazioni su come gestire connessioni abbandonate o inattive.

Avvertimento

Ci sono un paio di altri caveat da tenere in considerazione quando si usano le connessioni persistenti. Uno è che quando si usa il table locking su una connessione persistente, se lo script, per una qualunque ragione non è in grado di rimuovere il blocco, allora i successivi script che useranno la stessa connessione rimarranno bloccati in maniera indefinita e potrebbe essre necessario riavviare il server httpd o il server database. Un altro è che quando si usano le transazioni, un transaction block verrà trasferito anche allo script successivo che usa la medesima connessione, se lo script in esecuzione termina prima che sia terminato il transaction block. In entrambi i casi, si può usare register_shutdown_function() per registrare una semplice funzione di pulizia per sbloccare le tabelle o effettuare il roll back delle transaczioni. Sarebbe meglio non dover affrontare il problema, semplicemente non usando le connessioni persistenti negli script che usano i lock delle tabelle o le transaczioni (si possono comunque usare in altre situazioni).

Sommario importante. Le connessioni persistenti sono state pensate per avere una mappatura uno-a-uno con le connessioni di tipo normale. Ciò significa che si dovrebbe sempre essere in grado di cambiare una connessione persistente con una connessione non-persistente, e che questo non dovrebbe cambiare il modo in cui lo script si comporta. Può (e probabilmente succederà) cambiare l'efficienza dello script, ma non il suo comportamento!

Vedere anche fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), imap_popen(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), ocipLogon(), odbc_pconnect(), ora_pLogon(), pfsockopen(), pg_pconnect() e sybase_pconnect().


Capitolo 24. Modalità sicura (Safe mode)

La modalità Safe Mode è un tentativo di risolvere il problema di sicurezza derivante dalla condivisione del server. Dal punto di vista architetturale non è corretto cercare di risolvere questo problema al livello del PHP, ma poiché le alternative al livello del web server e del SO (Sistema Operativo) non sono realistiche, in molti, specialmente ISP (Internet Service Provider), utilizzano la modalità sicura.

Le direttive di configurazione che controllano la modalità sicura sono:
safe_mode = Off 
open_basedir = 
safe_mode_exec_dir = 
safe_mode_allowed_env_vars = PHP_ 
safe_mode_protected_env_vars = LD_LIBRARY_PATH 
disable_functions =

Quando safe_mode è attiva (on), il PHP verifica se il proprietario dello script in esecuzione e il proprietario del file su cui si sta operando con una funzione sui file, coincidono. Per esempio:
-rw-rw-r--    1 rasmus   rasmus       33 Jul  1 19:20 script.php 
-rw-r--r--    1 root     root       1116 May 26 18:01 /etc/passwd
Eseguendo questo script.php
<?php
 readfile('/etc/passwd'); 
?>
results in this error when Safe Mode is enabled:
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not 
allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2

Se, invece di safe_mode, viene definita una directory open_basedir allora tutte le operazioni sui file saranno limitate ai file sottostanti la directory specificata. Per esempio (nel file httpd.conf di Apache):
<Directory /docroot>
  php_admin_value open_basedir /docroot 
</Directory>
If you run the same script.php with this open_basedir setting then this is the result:
Warning: open_basedir restriction in effect. File is in wrong directory in 
/docroot/script.php on line 2

È possibile inoltre disabilitare le singole funzioni. Se si aggiunge la seguente riga al file php.ini:
disable_functions readfile,system
Then we get this output:
Warning: readfile() has been disabled for security reasons in 
/docroot/script.php on line 2


Funzioni limitate/disabilitate dalla modalità sicura (safe-mode)

Questo è un elenco probabilmente ancora incompleto e forse non esatto delle funzioni limitate da Safe Mode.

Tabella 24-1. Funzioni limitate dalla modalità sicura

FunzioniLimitazioni
dbmopen()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
dbase_open()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro_rowcount()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro_retrieve()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
ifx_*()sql_safe_mode restrictions, (!= Safe Mode)
ingres_*()sql_safe_mode restrictions, (!= Safe Mode)
mysql_*()sql_safe_mode restrictions, (!= Safe Mode)
pg_loimport()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
posix_mkfifo()Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
putenv()Obbedisce le direttive del file ini safe_mode_protected_env_vars e safe_mode_allowed_env_vars. Vedere la documentazione relativa on putenv()
move_uploaded_file()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chdir()Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
dl()Questa funzione è disabilitata nella modalitàsafe-mode
backtick operatorQuesta funzione è disabilitata nella modalitàsafe-mode
shell_exec() (functional equivalent of backticks)Questa funzione è disabilitata nella modalitàsafe-mode
exec()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
system()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
passthru()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
popen()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
mkdir()Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
rmdir()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
rename()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
unlink()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
copy()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione. (on source and target)
chgrp()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chown()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chmod()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. In addition, you cannot set the SUID, SGID and sticky bits
touch()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione.
symlink()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione. (note: only the target is checked)
link()Controlla che i file o le directory su cui si sta lavorando, abbiano lo stesso UID dello script che è in esecuzione. Controlla che la directory su cui si sta lavorando, abbia lo stesso UID dello script che è in esecuzione. (note: only the target is checked)
getallheaders()In Safe Mode, headers beginning with 'authorization' (case-insensitive) will not be returned. Warning: this is broken with the aol-server implementation of getallheaders()!
Qualsiasi funzione che utilizza php4/main/fopen_wrappers.c ??


Capitolo 25. Utilizzo di PHP da linea di comando

A partire dalla versione 4.3.0, il PHP supporta un nuovo tipo di SAPI (Server Application Programming Interface) chiamata CLI che significa Interfaccia per la Linea di Comando (Command Line Interface). Come il nome stesso suggerisce, questo tipo di SAPI è mirato allo sviluppo di applicazioni shell (o desktop) con PHP. Esistono alcune differenze tra la CLI SAPI e le altre SAPI; queste saranno illustrate nel corrente capitolo. Val la pena ricordare che CLI e CGI sono differenti SAPI sebbene condividano il medesimo comportamento in diverse situazioni.

La CLI SAPI è stata rilasciata per la prima volta con PHP 4.2.0, ma era ancora sperimentale e quindi doveva essere esplicitamente abilitata con --enable-cli nell'esecuzione di ./configure. A partire dal PHP 4.3.0 la CLI SAPI non viene più considerata sperimentale e quindi l'opzione --enable-cli è attivata per default. Vedere --disable-cli per disabilitare l'opzione.

Dal PHP 4.3.0, il nome, la posizione, e l'esistenza di eseguibili CLI/CGI differirà in base a come il PHP sarà installato sul sistema. Per default quando si esegue il make, si compila sia la versione CLI sia la versione CGI e saranno poste rispettivamente in sapi/cgi/php e sapi/cli/php a partire dalla directory dei sorgenti. Occorre notare che entrambi gli eseguibili sono chiamati php. Ciò che accade durante l'esecuzione di make install dipende dalla linea di configurazione. Se durante la configurazione si è scelto un modulo SAPI, tipo apxs, o si è attivato --disable-cgi, l'eseguibile CLI viene copiato in {PREFIX}/bin/php durante make install, altrimenti in questa cartella sarà posto l'eseguibile CGI. Così, per esempio, se si ha come parametro di configurazione --with--apxs allora l'eseguibile CLI sarà copiato in {PREFIX}/bin/php durante make install. Se si vuole evitare l'installazione dell'eseguibile CGI, utilizzare make install-cli dopo make install. In alternativa si può specificare --disable-cgi nella linea di configurazione.

Nota: Poichè sia --enable-cli sia --enable-cgi sono abilitati per default, avere semplicemente --enable-cli nella linea di configurazione non significa necessariamente che l'eseguibile CLI sia copiato come {PREFIX}/bin/php con l'esecuzione di make install.

Nel pacchetto per Windows, nelle versioni tra PHP 4.2.0 e PHP 4.2.3, l'eseguibile CLI era presente come php-cli.exe, nella medesima cartella della versione CGI php.exe. A partire dal PHP 4.3.0 nel pacchetto per Windows la versione CLI viene distribuita come php.exe in una cartella a parte chiamata cli, avendo perciò cli/php.exe.

Quale SAPI ho?: Da shell, digitando php -v si avrà l'informazione di quale php si tratta, CGI o CLI. Vedere anche la funzione php_sapi_name()e la costante PHP_SAPI per dettagli.

Nota: Una pagina stile man di Unix è stata aggiunta in PHP 4.3.2. La si può visualizzare digitando man php da linea di comando.

Le principali differenze tra la CLI SAPI e le altre SAPI sono:

  • A differenza di CGI SAPI, non sono inviate in output delle intestazioni.

    Mentre nella CGI SAPI esiste un modo per sopprimere le intestazioni, nella CLI SAPI non si ha una opzione per abilitare le intestazioni.

    Per default CLI parte in modalità silenziosa, si è mantenuto, comunque, l'opzione -q per motivi di compatibilità; in questo modo si possono utlizzare i vecchi script CGI.

    Non cambia la directory di lavoro in quella dello script. (E' rimasta l'opzione -C per compatibilità)

    Messaggi di errore in formato testo (non formattati in HTML).

  • Esistono, inoltre, alcune direttive del php.ini che sono forzate nell'impostazione dalla CLI SAPI poichè non hanno senso nell'ambiente di shell:

    Tabella 25-1. Direttive del php.ini forzate

    DirettivaCLI SAPI valore di defaultCommento
    html_errorsFALSE E' difficile leggere i messaggi di errore nella shell quando sono affogati in tag HTML prive di significato; pertanto il default della direttiva è impostato a FALSE.
    implicit_flushTRUE E' desiderabile che ogni tipo di output proveniente da print(), echo() e simili sia scritto immediatamente e non venga bufferizzato. Tuttavia è ancora possibile utilizzare le funzioni di controllo dell'output se si desidera ritardare o manipolare lo standard output.
    max_execution_time0 (unlimited) Considerate le svariate possibilità offerte da PHP nell'ambiente di shell, il tempo massimo di esecuzione è stato impostato a infinito. Mentre nelle applicazione scritte per il web i tempi di esecuzione sono rapidi, le applicazioni di shell tendono ad avere tempi di esecuzione molto più lunghi.
    register_argc_argvTRUE

    Poichè è impostato a TRUE nella CLI SAPI si ha sempre la possibilità di accedere alla variabili argc (numero di argomenti passati all'applicazione) e argv (matrice degli argumenti).

    A partire da PHP 4.3.0, quando si utilizza la CLI SAPI le variabili PHP $argc e $argv sono sempre registrate e valorizzate in modo appropriato. Prima di questa versione la creazione di queste variabili era coerente con il comportamento delle versioni CGI e MODULO le quali richiedevano che la direttiva PHP register_globals fosse impostata a on. A prescindere dalla versione o dall'impostazione di register_globals si può sempre accedere alle variabili $_SERVER o $HTTP_SERVER_VARS. Esempio: $_SERVER['argv']

    Nota: Queste direttive non possono essere inizializate con altri valori dal file di configurazione php.ini o da uno personalizzato (se specifictao). Questa è una limitazione perchè questi valori di default sono applicati dopo avere esaminato tutti i file di configurazione. Tuttavia i loro valori possono essere cambiati durante l'esecuzione (operazione che non ha senso per queste direttive, ad esempio register_argc_argv).

  • Per potere lavorare meglio con le shell, sono state definite le seguenti costanti:

    Tabella 25-2. Costanti specifiche per CLI

    CostanteDescrizione
    STDIN Un flusso già aperto allo stdin. Questo evita di aprirlo con
    $stdin = fopen('php://stdin', 'r');
    STDOUT Un flusso già aperto allo stdout. Questo evita di aprirlo con
    $stdout = fopen('php://stdout', 'w');
    STDERR Un flusso già aperto allo stderr. Questo evita di aprirlo con
    $stderr = fopen('php://stderr', 'w');

    Stante a quanto descritto non occorre più aprire in autonomia flussi per, ad esempio, lo stderr, ma semplicemente si può usare le costanti anzichè una nuova risorsa di flusso:
    php -r 'fwrite(STDERR, "stderr\n");'
    Non occorre chiudere esplicitamente questi flussi, saranno chiusi automaticamente dal PHP alla fine dello script.

  • La CLI SAPI non cambia la directory corrente in quella dello script eseguito!

    Il seguente esempio illustra la diferenza rispetto alla CGI SAPI:
    <?php
        /* Semplice esempio di test chiamato test.php*/
        echo getcwd(), "\n";
    ?>

    Quando si usa la versione CGI, si avrà il seguente output:
    $ pwd
    /tmp
    
    $ php -q another_directory/test.php
    /tmp/another_directory
    Questo evidenzia chiaramente come il PHP cambi la directory corrente con quella in cui si trova lo script.

    Utilizzando la versione CLI SAPI abbiamo:
    $ pwd
    /tmp
    
    $ php -f another_directory/test.php
    /tmp
    Questo permette una grande flessibilità nello scrivere tools in PHP.

    Nota: La CGI SAPI supporta il comportamento della CLI SAPI attivando l'opzione -C quando viene eseguito da linea di comando.

L'elenco completo delle opzioni del PHP disponibili da linea di comando può essere visualizzato in qualsiasi momento eseguendo il PHP con l'opzione -h:
Usage: php [options] [-f] <file> [args...]
       php [options] -r <code> [args...]
       php [options] [-- args...]
  -s               Display colour syntax highlighted source.
  -w               Display source with stripped comments and whitespace.
  -f <file>        Parse <file>.
  -v               Version number
  -c <path>|<file> Look for php.ini file in this directory
  -a               Run interactively
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -z <file>        Load Zend extension <file>.
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -i               PHP information
  -r <code>        Run PHP <code> without using script tags <?..?>
  -h               This help

  args...          Arguments passed to script. Use -- args when first argument 
                   starts with - or script is read from stdin

La vesione CLI SAPI ha tre differenti modi per eseguire il codice PHP:

  1. Dire al PHP di eseguire certi file.

    php my_script.php
    
    php -f my_script.php
    Entrambi i metodi (con o senza l'opzione -f) eseguono il file my_script.php. Si può scegliere qualsiasi nome per lo script da eseguire - non è obbligatorio che gli script PHP finiscano con l'estensione .php, ma possono avere qualsiasi nome o estensione che si desideri.

  2. Passare il codice PHP da eseguire direttamente da linea di comando.

    php -r 'print_r(get_defined_constants());'
    Occorre prestare molta attenzione alla sostituzione delle variabili di shell e all'uso degli apici.

    Nota: Osservando con attenzione l'esempio si nota l'assenza dei tag di inizio e fine! L'opzione -r non li richiede. L'uso dei tag genera un errore di parsing.

  3. Si può passare il codice PHP da eseguire via standard input (stdin).

    Questo da la possibilità di generare dinamicamente del codice PHP e passarlo all'eseguibile, come illustrato nel seguente esempio (fittizio):
    $ some_application | some_filter | php | sort -u >final_output.txt

Non si possono combinare tra loro questi tre metodi di esecuzione del codice.

Come qualsiasi applicazione di shell, anche l'eseguibile PHP accetta diversi argomenti, ma anche lo script PHP può ricevere argomenti. Il numero degli argomenti passabili allo script non è limitato dal PHP (si rammenta che la shell ha un limite nel numero di caratteri che possono essere passati; solitamente non si raggiunte questo limite). Gli argomenti passati allo script sono disponibili nell'array $argv. L'indice zero contiene sempre il nome dello script (che è - nel caso in cui il codice PHP provenda o dallo standard input o dalla linea di comando con l'opzione -r). La seconda variabile globale registrata è $argc la quale contiene il numero degli elementi nella matrice $argv (non è il numero degli argomenti passati allo script).

Fino a quando gli argomenti passati allo script non iniziano con il carattere - non si deve prestare alcuna cautela. Tuttavia se si passa allo script argomenti che iniziano con - si hanno dei problemi perchè lo stesso PHP ritiene di doverli gestire. Per evitare ciò occorre utilizzare il separatore di argomenti --. Dopo che il PHP ha incontrato questo separatore, ogni argomento verrà passato direttamente allo script.

# Questo non visualizzerà il codice passato, ma l'elenco delle opzioni
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# Questo passerà il '-h'allo script ed eviterà al PHP di visualizzare le opzioni
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

Tuttvia esiste un'altro modo per eseguire gli script PHP. Si può scrivere uno script la cui prima riga inizi con #!/usr/bin/php. Seguendo questa regola si può posizionare il normale codice PHP tra i tag di apertura e chiusura del PHP. Una volta impostati correttamente gli attributi del file (ad esempio chmod +x test) lo script può essere eseguito come una normale shell o script perl:
#!/usr/bin/php
<?php
    var_dump($argv);
?>
Assumento che questo file sia chiamato test nella directory corrente, si può eseguire:
$ chmod 755 test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}
Come si può notare in questo caso non vi è necessità di prestare attenzione nel passare i parametri che iniziano con -.

Tabella 25-3. Opzioni della linea di comando,

OptionDescription
-s

Visualizza il sorgente con sintassi colorata.

Questa opzione utilizza il meccanismo interno di parsing dei file e produce una versione HTML del sorgente e la dirige verso lo standard output. Occore notare che questa funzione genera dei blocchi di tag HTML <code> [...] </code> e non le intestazione HTML.

Nota: Questa opzione non funziona abbinata all'opzione -r.

-w

Visualizza il sorgente senza gli spazi e i commenti.

Nota: Questa opzione non funziona abbinata all'opzione -r.

-f

Analizza ed esegue il file passato con l'opzione -f. Questo parametro è opzionale e può essere omesso. Basta fornire il nome del file da eseguire.

-v

Visualizza le versioni di PHP, PHP SAPI, e Zend nello standard output, ad esempio:
$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies

-c

Con questa opzione si può sia specificare la directory in cui cercare il php.ini o si può specificare un file INI personalizzato (che non deve necessariamente chiamarsi php.ini), ad esempio:
$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

-a

Esegue il PHP in modo interattivo.

-d

Questa opzione permette di impostare valori personalizzati per qualsiasi delle direttive di configurazione previste in php.ini. La sintassi è:
-d configuration_directive[=value]

Esempi:
# Omettendo il valore si imposta la direttiva data a "1"
$ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Passando un valore vuoto si imposta la direttiva a ""
php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# La direttiva di configurazione viene impostata a qualsiasi valore passato dopo il carattere '='
$  php -d max_execution_time=20 -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php -d max_execution_time=doesntmakesense -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"

-e

Genera informazioni estese per il debugger/profiler.

-z

Carica l'estensione Zend. Soltano se si fornisce un nome di file, il PHP tenta di caricare l'estensione dal corrente percorso di default delle librerie (solitamente, sui sistemi Linux, /etc/ld.so.conf). Se si fornisce un nome di file con percorso assoluto, ls libreria non sarà cercata nella directory di default. Un nome di file con percorso relativo indica al PHP di tentare di caricare l'estensione con percorso relativo alla directory corrente.

-l

Questa opzione fornisce un metodo pratico per eseguire un controllo sintattico di un dato codice PHP. Se il controllo ha successo, verrà visualizzato il testo No syntax errors detected in <filename> e alla shell sarà restituito il codice 0. Se si rilevano errori si avrà il testo Errors parsing <filename>, inoltre si avranno anche i messaggi di errore del parser ed alla shell sarà restituito il codice 255.

Questa opzione non rileva errori fatali (tipo funzioni non definite). Occorre utilizzare l'opzione -f se si desidera rilevare gli errori fatali.

Nota: Questa opzione non è abbinabile all'opzione -r.

-m

Utilizzare questa opzione per visualizzare i moduli PHP e di Zend integrati (e quindi caricati):
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

-i Questa opzione della linea di comando richiama la funzione phpinfo(), e ne visualizza il risultato. Se il PHP non funziona correttamente, è opportuno utilizzare php -i per verificare se sono visualizzati messaggi di errore prima o al posto della tabella con le informazioni. Fare attenzione che l'output è in formato HTML e quindi abbastanza lungo.
-r

Questa opzione permette l'esecuzione di codice PHP direttamente da linea di comando. I tag PHP di apertura e di chiusura (<?php e ?>) non sono necessari anzi, se presenti, causano un errore del parser.

Nota: Quando si utilizza questo metodo occorre prestare attenzione ad evitare collisioni con la sostituzione delle varibili eseguita dalla shell sulla linea di comando.

Ecco un esempio che visualizza un errore di parsing
$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '='
In questo caso il problema è dovuto alla sostituzione della variabile eseguita da sh/bash anche quando si usano i doppi apici ". Poichè la viriabile $foo non è definita, essa verrà espansa con 'niente' generando il seguente codice PHP:
$ php -r " = get_defined_constants();"
Il metodo corretto richiede l'uso dell'apice singolo '. Le variabili racchiuse in stringhe delimite dall'apice singolo non vengono espanse da sh/bash.
$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]
Se si utilizzano shell differenti rispetto a sh/bash, si potrebbe incorrere in altri problemi. In tal caso aprite una segnalazione di errore o inviate una mail a phpdoc@lists.php.net. Tuttavia si può facilmente incorrere in problemi nell'avere variabili di shell nel codice o nell'utilizzare le barre rovesciate (backslash) per l'escape. Siete avvertiti.

Nota: L'opzione -r è disponibile solo nella CLI SAPI e non nella CGI SAPI.

-h Con questa opzione si ha l'elenco dei comandi di linea ed una breve descrizione di questi.

L'eseguibile PHP può essere utilizzato per eseguire script PHP in modo indipendente dal server web. Se ci si trova su sistemi Unix, si può aggiungere una prima linea speciale allo script PHP e renderlo eseguibile, in questo modo il sistema sa quale programma deve interpretare lo script. Sui sistemi Windows si può associare php.exe all'estensione .php, o si può scrivere un batch per eseguire gli script tramite PHP. La prima riga inserita per i sistemi Unix non crea problemi in Windows, in questo modo si possono scrivere batch multi-piattaforma. Seguirà un semplice esempio di programma PHP da linea di comando.

Esempio 25-1. Script sviluppato per essere esguito da linea di comando (script.php)

#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

Questo è uno script PHP da linea di comando con una opzione.

  Utilizzo:
  <?php echo $argv[0]; ?> <opzione>

  <opzione> può essere qualsiasi parola che si desidera
  stampata. Con --help, -help, -h,
  o -? si ottiene questo aiuto.
<?php
} else {
    echo $argv[1];
}
?>

Nello script precedente, abbiamo utilizzato la prima riga per indicare che questo file deve essere interpretato dal PHP. Poichè qui lavoriamo con la versione CLI non vengono prodotte intestazioni HTTP. Esistono due variabili che si possono utilizzare nelle applicazioni PHP da linea di comando: $argc e $argv. La prima è il numero di argomenti più uno (il nome dello script). La seconda è una matrice contenente gli argomenti, iniziando dal nome dello script all'indice zero ($argv[0]).

Nel programma precedente abbiamo verificato se i parametri passati erano di più o di meno di uno. Inoltre se l'argomento è --help, -help, -h oppure -?, si visualizza un messaggio di aiuto, visualizzando in modo dinamico il nome dello script. Se si riceve un argomento differente questo sarà visualizzato.

Se si desidera eseguire lo script precedente su Unix, occorre, per prima cosa, renderlo eseguibile, e quindi richiamarlo con script.php echothis oppure script.php -h. Su Windows occorre scrivere un batch per ottenere questo risultato:

Esempio 25-2. File batch per eseguire uno script PHP da linea di comando (script.bat)

@c:\php\cli\php.exe script.php %1 %2 %3 %4

Assumendo che programma precedente sia chiamato script.php, che la versione CLI di php.exe sia in c:\php\cli\php.exe questo batch eseguirà lo script con le opzioni passate: script.bat echothis oppure script.bat -h.

Vedere anche la documentazione del modulo Readline per informazioni su funzioni che possono essere utilizzate per migliorare le applicazioni da linea di comando.

V. Guida Funzioni

Sommario
I. Funzioni Apache
II. Funzioni di Array
III. Funzioni Aspell [deprecated]
IV. Funzioni Matematiche BCMath a precisione arbitraria
V. Funzioni di compressione Bzip2
VI. Funzioni Calendar
VII. Funzioni API CCVS [deprecate]
VIII. Funzioni di supporto COM per Windows
IX. Funzioni per Classi/Oggetti
X. Funzioni ClibPDF
XI. Funzioni di Crack
XII. Funzioni CURL, Client URL Library
XIII. Funzioni di pagamento Cybercash
XIV. Funzioni di amministrazione Cyrus IMAP
XV. Funzioni di tipo dei caratteri
XVI. Database (dbm-style) Abstraction Layer Functions
XVII. Funzioni di Data e Ora
XVIII. Funzioni dBase
XIX. Funzioni DBM
XX. dbx Functions
XXI. DB++ Functions
XXII. Funzioni per l'IO diretto
XXIII. Funzioni per le directory
XXIV. DOM Functions
XXV. Funzioni DOM XML
XXVI. Funzioni .NET
XXVII. Funzioni di gestione degli errori e di logging
XXVIII. File Alteration Monitor Functions
XXIX. FrontBase Functions
XXX. Funzioni filePro
XXXI. Filesystem functions
XXXII. Funzioni Forms Data Format
XXXIII. Funzioni FriBiDi
XXXIV. Funzioni FTP
XXXV. Function Handling Functions
XXXVI. Gettext
XXXVII. Funzioni GMP
XXXVIII. Funzioni HTTP
XXXIX. Hyperwave Functions
XL. Hyperwave API Functions
XLI. funzioni iconv
XLII. Funzioni per le immagini
XLIII. IMAP, POP3 and NNTP Functions
XLIV. Informix Functions
XLV. Funzioni InterBase
XLVI. ID3 Functions
XLVII. Ingres II Functions
XLVIII. IRC Gateway Functions
XLIX. PHP / Java Integration
L. LDAP Functions
LI. LZF Functions
LII. Funzioni di Mail
LIII. mailparse Functions
LIV. Funzioni Matematiche
LV. Multibyte String Functions
LVI. MCAL Functions
LVII. Mcrypt Encryption Functions
LVIII. MCVE Payment Functions
LIX. Memcache Functions
LX. Mhash Functions
LXI. Mimetype Functions
LXII. Funzioni per Microsoft SQL Server
LXIII. Ming functions for Flash
LXIV. Miscellaneous Functions
LXV. mnoGoSearch Functions
LXVI. mSQL Functions
LXVII. MySQL Functions
LXVIII. Improved MySQL Extension
LXIX. Mohawk Software Session Handler Functions
LXX. muscat Functions
LXXI. Funzioni di rete
LXXII. Ncurses Terminal Screen Control Functions
LXXIII. Lotus Notes Functions
LXXIV. NSAPI-specific Functions
LXXV. Funzioni ODBC Unificate
LXXVI. Object Aggregation/Composition Functions
LXXVII. Funzioni Oracle 8
LXXVIII. OpenSSL Functions
LXXIX. Funzioni Oracle
LXXX. Ovrimos SQL Functions
LXXXI. Output Control Functions
LXXXII. Proprietà object e method call overloading
LXXXIII. PDF functions
LXXXIV. Verisign Payflow Pro Functions
LXXXV. PHP Opzioni&Informazioni
LXXXVI. Funzioni POSIX
LXXXVII. Funzioni PostgreSQL
LXXXVIII. Process Control Functions
LXXXIX. Funzioni per l'esecuzione di programmi
XC. Funzioni per le Stampanti
XCI. Pspell Functions
XCII. GNU Readline
XCIII. GNU Recode Functions
XCIV. Funzioni per le espressioni regolari (Perl compatibili)
XCV. Funzioni qtdom
XCVI. Funzioni per le espressioni regolari (POSIX estesa)
XCVII. Funzioni per i semafori, la memoria condivisa ed IPC
XCVIII. SESAM Database Functions
XCIX. Funzioni di gestione della sessione
C. Funzioni relative alla memoria condivisa
CI. SimpleXML functions
CII. SOAP Functions
CIII. SQLite
CIV. Shockwave Flash Functions
CV. Funzioni per SNMP
CVI. Funzioni relative ai Socket
CVII. Standard PHP Library (SPL) Functions
CVIII. Stream Functions
CIX. Stringhe
CX. Sybase Functions
CXI. TCP Wrappers Functions
CXII. Tidy Functions
CXIII. Tokenizer Functions
CXIV. URL Functions
CXV. Funzioni di Variabili
CXVI. Funzioni vpopmail
CXVII. Funzioni W32api
CXVIII. WDDX Functions
CXIX. Funzioni relative al parser XML
CXX. Funzioni XMLRPC
CXXI. xdiff Functions
CXXII. XSL functions
CXXIII. Funzioni XSLT
CXXIV. YAZ Functions
CXXV. YP/NIS Functions
CXXVI. Funzioni per File Zip (Accesso di Sola Lettura)
CXXVII. Funzioni di compressione Zlib

I. Funzioni Apache

Introduzione

Queste funzioni sono disponibili unicamente quando PHP è eseguito come modulo Apache.

Nota: La variabile del server PATH_TRANSLATED non viene più impostata implicitamente sotto Apache 2 SAPI, diversamente da quanto accadeva in Apache 1, dove questa veniva impostata allo stesso valore della variabile SCRIPT_FILENAME qualora non fosse già riempita. Questa modifica è stata fatta per adeguarsi alle specifiche CGI. Consultare il bug #23610 per ulteriori informazioni.


Installazione

Per l'installazione di PHP su Apache vedere la sezione Apache nel capitolo che tratta l'installazione.


Configurazione di Runtime

Il comportamento del modulo Apache per PHP è influenzato dalle impostazioni in php.ini. Le impostazioni di configurazione del php.ini possono essere scavalcate attraverso le impostazioni php_flag nel file di configurazione del server o nei file .htaccess locali.

Esempio 1. disabilitazione dell'interprete PHP in una directory mediante .htaccess

php_flag engine off

Tabella 1. Opzioni di configurazione di Apache

NomeDefaultModificabileFunzione
engineOnPHP_INI_ALLaccende o spegne l'interprete PHP
child_terminateOffPHP_INI_ALL decide se gli script PHP possono richiedere la terminazione dei processi figli alla fine della richiesta HTTP, vedere anche apache_child_terminate()
last_modifiedOffPHP_INI_ALLmanda la data di modifica degli script nell'header Last-Modified:
xbithackOffPHP_INI_ALLinterpreta i file con il bit di esecuzione impostato, a prescindere dalla loro estensione

Breve descrizione dei parametri di configurazione.

engine boolean

Questa direttiva è utile solo nella versione di PHP compilata come modulo di Apache. Viene usata dai siti che vogliono spegnere e accendere il parsing PHP in base alla directory o al virtual server corrente. Inserendo engine off nel posto appropriato nel file httpd.conf, il PHP può essere abilitato o disabilitato.


Tipi di risorse

Questa estensione non definisce alcun tipo di risorsa.


Costanti predefinite

Questa estensione non definisce alcuna costante.

Sommario
apache_child_terminate -- Interrompe il processo apache dopo la presente richiesta
apache_get_modules --  Get a list of loaded Apache modules
apache_get_version --  Fetch Apache version
apache_getenv --  Get an Apache subprocess_env variable
apache_lookup_uri --  Esegue una richiesta parziale della URI specificata e restituisce tutte le informazioni
apache_note -- Ricava o imposta una variabile nella tabella notes di Apache
apache_request_headers -- Estrae tutti gli header della richiesta HTTP
apache_response_headers --  Estrae tutti gli header della risposta HTTP
apache_setenv -- Imposta una variabile Apache subprocess_env
ascii2ebcdic -- Traduce una stringa da ASCII a EBCDIC
ebcdic2ascii -- Traduce una stringa da string EBCDIC ad ASCII
getallheaders -- Estrae tutti gli header della richiesta HTTP
virtual -- Esegue una sotto-richiesta Apache

apache_child_terminate

(PHP 4 >= 4.0.5, PHP 5)

apache_child_terminate -- Interrompe il processo apache dopo la presente richiesta

Descrizione

bool apache_child_terminate ( void )

apache_child_terminate() informa il processo Apache che sta eseguendo la richiesta PHP corrente di terminare quando l'esecuzione del codice PHP è stata completata. Può essere usata per interrompere un processo dopo che sia stato eseguito uno script con alta occupazione di memoria dal momento che la memoria viene normalmente liberata internamente ma non restituita al sistema operativo.

Nota: La disponibilità di questa caratteristica è controllata dalal direttiva del php.ini child_terminate, che è impostata a off di default.

Questa caratteristica non è inoltre disponibile sulle versioni multithread di apache come, ad esempio, la versione win32.

Vedere anche exit().

apache_get_modules

(PHP 4 >= 4.3.2, PHP 5)

apache_get_modules --  Get a list of loaded Apache modules

Description

array apache_get_modules ( void )

This function returns an array with the loaded Apache modules.

Esempio 1. apache_get_modules() example

<?php
print_r(apache_get_modules());
?>

The above example will output something similar to:

Array
(
    [0] => core
    [1] => http_core
    [2] => mod_so
    [3] => sapi_apache2
    [4] => mod_mime
    [5] => mod_rewrite
)

apache_get_version

(PHP 4 >= 4.3.2, PHP 5)

apache_get_version --  Fetch Apache version

Description

string apache_get_version ( void )

apache_get_version() returns the version of Apache as string, or FALSE on failure.

Esempio 1. apache_get_version() example

<?php
$version = apache_get_version();
echo "$version\n";
?>

The printout of the above program will look similar to:

Apache/1.3.29 (Unix) PHP/4.3.4

See also phpinfo().

apache_getenv

(PHP 4 >= 4.3.0, PHP 5)

apache_getenv --  Get an Apache subprocess_env variable

Description

string apache_getenv ( string variable [, bool walk_to_top])

Avvertimento

Questa funzione, al momento non è documentata; è disponibile soltanto la lista degli argomenti.

apache_lookup_uri

(PHP 3>= 3.0.4, PHP 4 , PHP 5)

apache_lookup_uri --  Esegue una richiesta parziale della URI specificata e restituisce tutte le informazioni

Descrizione

object apache_lookup_uri ( string nomefile)

Questa funzione esegue una richiesta parziale per una URI. Esegue l'operazione finché ottiene tutte le informazioni importanti sulla risorsa e restituisce queste informazioni in una classe. Le proprietà della classe restituita sono:

status
the_request
status_line
method
content_type
handler
uri
filename
path_info
args
boundary
no_cache
no_local_copy
allowed
send_bodyct
bytes_sent
byterange
clength
unparsed_uri
mtime
request_time

Esempio 1. esempio di apache_lookup_uri()

<?php
$info = apache_lookup_uri('index.php?var=value');
print_r($info);

if (file_exists($info->filename)) {
    echo 'file exists!';
}
?>

Questo esempio produrrà un risultato simile al seguente:

stdClass Object
(
    [status] => 200
    [the_request] => GET /dir/file.php HTTP/1.1
    [method] => GET
    [mtime] => 0
    [clength] => 0
    [chunked] => 0
    [content_type] => application/x-httpd-php
    [no_cache] => 0
    [no_local_copy] => 1
    [unparsed_uri] => /dir/index.php?var=value
    [uri] => /dir/index.php
    [filename] => /home/htdocs/dir/index.php
    [args] => var=value
    [allowed] => 0
    [sent_bodyct] => 0
    [bytes_sent] => 0
    [request_time] => 1074282764
)
file exists!

Nota: apache_lookup_uri() funziona solo quando PHP è installato come modulo Apache.

apache_note

(PHP 3>= 3.0.2, PHP 4 , PHP 5)

apache_note -- Ricava o imposta una variabile nella tabella notes di Apache

Descrizione

string apache_note ( string nome_nota [, string valore])

apache_note() è una funzione specifica di Apache che ricava o imposta un valore nella tabella notes di una richiesta HTTP. Se viene invocata con un solo argomento restituisce il valore della nota nome_nota. Se viene chiamata con due argomenti, imposta il valore della nota nome_nota a valore e restituisce il valore precedente della nota nome_nota.

apache_request_headers

(PHP 4 >= 4.3.0, PHP 5)

apache_request_headers -- Estrae tutti gli header della richiesta HTTP

Descrizione

array apache_request_headers ( void )

apache_request_headers() restituisce un array associativo contenente tutti gli header HTTP nella richiesta corrente. Questa funzionalità è supportata solo quando PHP è un modulo di Apache.

Esempio 1. esempio di apache_request_headers()

<?php
$headers = apache_request_headers();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}
?>

Nota: Prima del PHP 4.3.0, apache_request_headers() si chiamava getallheaders(). Dopo il PHP 4.3.0, getallheaders() è un alias di apache_request_headers().

Nota: È possibile ottenere il valore delle variabili comuni CGI anche leggendole dalle variabili di ambiente; questo funziona indipendentemente dal fatto che si stia usando PHP come modulo Apache. Utilizzare phpinfo() per ottenere una lista di tutte le variabili d'ambiente disponibili.

Nota: Dal PHP 4.3.3 è possibile utilizzare questa funzione anche con il modulo server NSAPI dei server web Netscape/iPlanet/SunONE

Vedere anche apache_response_headers().

apache_response_headers

(PHP 4 >= 4.3.0, PHP 5)

apache_response_headers --  Estrae tutti gli header della risposta HTTP

Descrizione

array apache_response_headers ( void )

Restituisce un array contenente tutti gli header della risposta HTTP di Apache. Questa funzione è disponibile solo nel PHP 4.3.0 o successivi.

Nota: Dal PHP 4.3.3 è possibile utilizzare questa funzione anche con il modulo server NSAPI dei server web Netscape/iPlanet/SunONE

Vedere anche getallheaders() e headers_sent().

apache_setenv

(PHP 4 >= 4.2.0, PHP 5)

apache_setenv -- Imposta una variabile Apache subprocess_env

Descrizione

int apache_setenv ( string varibile, string valore [, bool vai_in_cima])

Avvertimento

Questa funzione, al momento non è documentata; è disponibile soltanto la lista degli argomenti.

ascii2ebcdic

(PHP 3>= 3.0.17)

ascii2ebcdic -- Traduce una stringa da ASCII a EBCDIC

Descrizione

int ascii2ebcdic ( string ascii_str)

ascii2ebcdic() è una funzione Apache che è disponibile solo su sistemi operativi basati sull'EBCDIC (OS/390, BS2000). Traduce la stringa codificata in ASCII ascii_str nella sua rappresentazione equivalente EBCDIC (proteggendo i dati binari), e restituisce il risultato.

Vedere anche la funzione duale ebcdic2ascii()

ebcdic2ascii

(PHP 3>= 3.0.17)

ebcdic2ascii -- Traduce una stringa da string EBCDIC ad ASCII

Descrizione

int ebcdic2ascii ( string ebcdic_str)

ebcdic2ascii() è una funzione Apache che è disponibile solo su sistemi operativi basati su EBCDIC (OS/390, BS2000). Traduce la stringa codificata in EBCDIC ebcdic_str nella sua rappresentazione equivalente ASCII (proteggendo i dati binari), e restituisce il risultato.

Vedere anche la funzione duale ascii2ebcdic()

getallheaders

(PHP 3, PHP 4 , PHP 5)

getallheaders -- Estrae tutti gli header della richiesta HTTP

Descrizione

array getallheaders ( void )

getallheaders() è un alias di apache_request_headers(). Restituisce un array associativo contenente tutti gli header HTTP nella richiesta corrente. Leggere la documentazione di apache_request_headers() per ulteriori informazioni sul funzionamento.

Nota: Nel PHP 4.3.0 getallheaders() è diventata un alias di apache_request_headers(). In breve, è stata rinominata. Ciò dipende dal fatto che questa funzione è disponibile soltanto quando PHP è compilato come modulo di Apache.

Nota: Dal PHP 4.3.3 è possibile utilizzare questa funzione anche con il modulo server NSAPI dei server web Netscape/iPlanet/SunONE

Vedere anche apache_request_headers().

virtual

(PHP 3, PHP 4 , PHP 5)

virtual -- Esegue una sotto-richiesta Apache

Descrizione

int virtual ( string nomefile)

virtual() è una funzione specifica Apache che è equivalente a <!--#include virtual...--> in mod_include. Esegue una sotto-richiesta Apache. È utile ad includere script CGI o file .shtml, o qualsiasi altra cosa si voglia fa analizzarea ad Apache. Si noti che per uno script CGI, questo deve generare degli header CGI validi. Quindi, Come minimo deve generare un header Content-type.

Al fine di eseguire la sotto-richiesta, tutti i buffer vengono chiusi e svuotati verso il browser, e anche gli header in attesa vengono inviati.

Dal PHP 4.0.6, è possibile utilizzare virtual() sui file PHP. Comunque è preferibile usare include() o require() se è necessarei includere un altro file PHP.

Nota: Dal PHP 4.3.3 è possibile utilizzare questa funzione anche con il modulo server NSAPI dei server web Netscape/iPlanet/SunONE

II. Funzioni di Array

Introduzione

Queste funzioni permettono di manipolare e interagire con gli array in vari modi. Gli array sono indispensabili per immagazzinare, mantenere e operare su gruppi di variabili.

Sono supportati sia array semplici che multi-dimensionali, che possono essere sia creati dall'utente che da funzioni. Ci sono specifiche funzioni di database per riempire gli array a partire da interrogazioni sui dati, e parecchie funzioni restituiscono array.

Vedere la sezione Array del manuale per una spiegazione dettagliata di come gli array siano implementati ed usati in PHP. Vedere anche per altri modi di manipolazione degli array.


Requisiti

Non sono necessarie librerie esterne per utilizzare questo modulo.


Installazione

Non è necessaria nessuna installazione per usare queste funzioni, esse fanno parte del core di PHP.


Configurazione di Runtime

Questa estensione non definisce alcuna direttiva di configurazione in php.ini


Tipi di risorse

Questa estensione non definisce alcun tipo di risorsa.


Costanti predefinite

Le costanti qui elencate sono sempre disponibili in quanto parte del core di PHP.

CASE_LOWER (integer)

CASE_LOWER è usata con array_change_key_case() per convertire le chiavi degli array in minuscolo. Questo è il valore di default per array_change_key_case().

CASE_UPPER (integer)

CASE_UPPER è usata con array_change_key_case() per convertire le chiavi degli array in maiuscolo.

flag per l'ordinamento:

SORT_ASC (integer)

SORT_ASC è usata con array_multisort() per ordinare in senso crescente.

SORT_DESC (integer)

SORT_DESC è usata con array_multisort() per ordinare in senso decrescente.

flag per il tipo di ordinamento: usati da varie funzioni di ordinamento

SORT_REGULAR (integer)

SORT_REGULAR è usata per comparare gli oggetti in modo normale.

SORT_NUMERIC (integer)

SORT_NUMERIC è usata per comparare gli oggetti in modo numerico.

SORT_STRING (integer)

SORT_STRING è usata per comparare gli oggetti come se fossero stringhe.

COUNT_NORMAL (integer)

COUNT_RECURSIVE (integer)

EXTR_OVERWRITE (integer)

EXTR_SKIP (integer)

EXTR_PREFIX_SAME (integer)

EXTR_PREFIX_ALL (integer)

EXTR_PREFIX_INVALID (integer)

EXTR_PREFIX_IF_EXISTS (integer)

EXTR_IF_EXISTS (integer)

EXTR_REFS (integer)

Sommario
array_change_key_case -- Restituisce un array con tutte le chiavi cambiate in maiuscolo o in minuscolo
array_chunk -- Spezza un array in tronconi
array_combine --  Crea un'array utilizzando un'array per le chiavi e un'altro per i suoi valori
array_count_values -- Conta tutti i valori di un array
array_diff_assoc -- Calcola la differenza tra due o più array con un ulteriore controllo sull'indice
array_diff_uassoc --  Computes the difference of arrays with additional index check which is performed by a user supplied callback function
array_diff -- Calcola la differenza di due o più array
array_fill -- Riempie un array con i valori specificati
array_filter --  Filtra gli elementi di un array usando una funzione callback
array_flip -- Scambia tutte le chiavi di un array con i loro valori associati
array_intersect_assoc -- Calcola l'intersezione degli array con un ulteriore controllo sugli indici
array_intersect -- Calcola l'intersezione degli arrays
array_key_exists -- Controlla se l'indice (o chiave) specificato esiste nell'array
array_keys -- Restituisce tutte le chiavi di un array
array_map --  Applica la funzione callback a tutti gli elementi dell'array dato
array_merge_recursive -- Fonde due o più array in modo ricorsivo
array_merge -- Fonde due o più array
array_multisort -- Ordina array multipli o multidimensionali
array_pad --  Riempie con un valore un array fino alla lunghezza specificata
array_pop -- Estrae l'elemento alla fine dell'array
array_push --  Accoda uno o più elementi ad un array
array_rand --  Estrae a caso uno o più elementi da un array
array_reduce --  Riduce iterativamente l'array a un singolo valore utilizzando una funzione callback
array_reverse --  Restituisce un array con gli elementi in ordine invertito
array_search --  Ricerca un dato valore in un array e ne restituisce la chiave corrispondente, se la ricerca ha successo.
array_shift --  Estrae l'elemento alla testa dell'array
array_slice -- Estrae un sottoinsieme da un array
array_splice --  Rimuove una porzione dell'array e la sostituisce con altro
array_sum --  Calcola la somma dei valori di un array.
array_udiff_assoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function.
array_udiff_uassoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function. The index check is done by a callback function also
array_udiff -- Computes the difference of arrays by using a callback function for data comparison.
array_unique -- Rimuove i valori duplicati di un array
array_unshift --  Inserisce uno o più elementi all'inizio dell'array
array_values -- Restituisce tutti i valori di un array
array_walk_recursive --  Apply a user function recursively to every member of an array
array_walk --  Esegue una funzione su ogni elemento dell'array
array --  Crea un array
arsort --  Ordina un array in ordine decrescente e mantiene le associazioni degli indici
asort -- Ordina un array e mantiene le associazioni degli indici
compact --  Crea un array contenente variabili e il loro valore
count -- Conta gli elementi in una variabile
current -- Restituisce l'elemento corrente di un array
each --  Restituisce la corrente coppia chiave/valore di un array e incrementa il puntatore dell'array
end --  Sposta il puntatore interno dell'array all'ultimo elemento
extract --  Importa le variabili nella tabella dei simboli
in_array -- Controlla se un valore è presente in un array
key -- Estrae la chiave corrente da un array associativo
krsort -- Ordina rispetto alle chiavi di un array in ordine inverso
ksort -- Ordina rispetto alle chiavi di un array
list --  Assegna valori a delle variabili come se fossero un array
natcasesort --  Ordina un array usando un algoritmo di "ordine naturale" non sensibile alle maiuscole/minuscole
natsort --  Ordina un array usando un algoritmo di "ordine naturale"
next --  Incrementa il puntatore interno dell'array
pos -- Restituisce l'elemento corrente di un array
prev -- Decrementa il puntatore interno dell'array
range --  Crea un array contenente una serie di elementi
reset --  Reimposta il puntatore interno di un array sulla posizione iniziale
rsort -- Ordina un array in ordine decrescente
shuffle -- Mescola un array
sizeof -- Alias di count()
sort -- Ordina un array
uasort --  Ordina un array mediante una funzione definita dall'utente e mantiene le associazioni
uksort --  Ordina rispetto alle chiavi di un array mediante una funzione definita dall'utente
usort --  Ordina un array mediante una funzione definita dall'utente

array_change_key_case

(PHP 4 >= 4.2.0, PHP 5)

array_change_key_case -- Restituisce un array con tutte le chiavi cambiate in maiuscolo o in minuscolo

Descrizione

array array_change_key_case ( array input [, int case])

array_change_key_case() cambia le chiavi nell'array input in modo che siano tutte minuscole o maiuscole. Il tipo di cambiamento dipende dal parametro opzionale case. Si possono usare due costanti, CASE_UPPER per le maiuscole e CASE_LOWER per le minuscole. Il default è CASE_LOWER. La funzione non modifica le chiavi numeriche.

Esempio 1. esempio di array_change_key_case()

<?php
$input_array = array("PriMo" => 1, "SecOndO" => 4);
print_r(array_change_key_case($input_array, CASE_UPPER));
?>

Il risultato di questo programma sarà:

Array
(
    [PRIMO] => 1
    [SECONDO] => 2
)

Se un array ha degli indici che risulteranno identici dopo l'esecuzione di questa funzione (es. "keY" e "kEY") il valore dell'ultimo indice sovrascrivera' gli altri.

array_chunk

(PHP 4 >= 4.2.0, PHP 5)

array_chunk -- Spezza un array in tronconi

Descrizione

array array_chunk ( array input, int dimensione [, bool mantieni_chiavi])

array_chunk() spezza l'array in più array di dimensione dimensione. L'ultimo array potrebbe ovviamente avere una dimensione inferiore. Gli array sono restituiti in un array multidimensionale indicizzato con chiavi che partono da zero.

Impostando il parametro opzionale preserve_keys a TRUE, si forza PHP a mantenere le chiavi originarie dell'array di input. Se si imposta a FALSE come chiavi verranno usati in ogni array dei numeri crescenti a partire da zero. Il default è FALSE.

Esempio 1. esempio di array_chunk()

<?php
$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));
?>

Il risultato di questo programma sarà:

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [0] => c
            [1] => d
        )

    [2] => Array
        (
            [0] => e
        )

)
Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [2] => c
            [3] => d
        )

    [2] => Array
        (
            [4] => e
        )

)

array_combine

(PHP 5)

array_combine --  Crea un'array utilizzando un'array per le chiavi e un'altro per i suoi valori

Descrizione

array array_combine ( array keys, array values)

Restituisce un'array utilizzando i valori dell'array keys come chiavi e i valori dall' array values come valori corrispondenti.

Restituisce FALSE se il numero degli elementi in ogni array non è uguale o se gli array sono vuoti.

Esempio 1. Esempio di array_combine()

<?php
$a = array('verde', 'rosso', 'giallo');
$b = array('avocado', 'mela', 'banana');
$c = array_combine($a, $b);

print_r($c);
?>

Il risultato è:

Array
(
    [verde]  => avocado
    [rosso]  => mela
    [giallo] => banana
)

Vedere anche array_merge(), array_walk() e array_values().

array_count_values

(PHP 4 , PHP 5)

array_count_values -- Conta tutti i valori di un array

Descrizione

array array_count_values ( array input)

array_count_values() restituisce un array che ha i valori dell'array input per chiavi e la loro frequenza in input come valori.

Esempio 1. Esempio di array_count_values()

<?php
$array = array(1, "ciao", 1, "mondo", "ciao");
print_r(array_count_values($array));
?>

Il risultato di questo programma sarà:

Array
(
    [1] => 2
    [ciao] => 2
    [mondo[ => 1
)

Vedere anche count(), array_unique(), array_values() e count_chars().

array_diff_assoc

(PHP 4 >= 4.3.0, PHP 5)

array_diff_assoc -- Calcola la differenza tra due o più array con un ulteriore controllo sull'indice

Descrizione

array array_diff_assoc ( array array1, array array2 [, array ...])

array_diff_assoc() restituisce un array contenente tutti i valori di array1 che non sono presenti in alcuno degli altri array. Si noti che le chiavi sono utilizzate nel confronto, diversamente da array_diff().

Esempio 1. esempio di array_diff_assoc()

<?php
$array1 = array("a" => "verde", "b" => "marrone", "c" => "blu", "rosso");
$array2 = array("a" => "verde", "giallo", "rosso");
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>

Il risultato è:

Array
(
    [b] => marrone
    [c] => blu
    [0] => rosso
)

Nell'esempio si vede che la coppia "a" => "verde" è presente in entrambi gli array e quindi non è nel risultato della funzione. Invece, la coppia 0 => "rosso" è nel risultato perché nel secondo argomento "red" cha come chiave 1.

Due valori delle coppie chiave => valore sono considerati uguali solo se (string) $elem1 === (string) $elem2 . In altre parole c'è un controllo stringente che si accerta che le rappresentazioni sotto forma di stringa siano uguali.

Nota: Si noti che questa funzione controlla solo una dimensione di un array n-dimensionale. Ovviamente è possibile controllare le altre dimensioni usando array_diff_assoc($array1[0], $array2[0]);.

Vedere anche array_diff(), array_intersect(), and array_intersect_assoc().

array_diff_uassoc

(PHP 5)

array_diff_uassoc --  Computes the difference of arrays with additional index check which is performed by a user supplied callback function

Description

array array_diff_uassoc ( array array1, array array2 [, array ..., callback key_compare_func])

array_diff_uassoc() returns an array containing all the values from array1 that are not present in any of the other arguments. Note that the keys are used in the comparison unlike array_diff(). This comparison is done by a user supplied callback function. It must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. This is unlike array_diff_assoc() where an internal function for comparing the indices is used.

Esempio 1. array_diff_uassoc() example

<?php
function key_compare_func($a, $b) 
{
    if ($a === $b) {
        return 0;
    }
    return ($a > $b)? 1:-1;
}

$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result = array_diff_uassoc($array1, $array2, "key_compare_func");
?>

The result is:

Array
(
    [b] => brown
    [c] => blue
    [0] => red
)

In our example above you see the "a" => "green" pair is present in both arrays and thus it is not in the ouput from the function. Unlike this, the pair 0 => "red" is in the ouput because in the second argument "red" has key which is 1.

The equality of 2 indices is checked by the user supplied callback function.

Nota: Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using, for example, array_diff_uassoc($array1[0], $array2[0], "key_compare_func");.

See also array_diff(), array_diff_assoc(), array_udiff(), array_udiff_assoc(), array_udiff_uassoc(), array_intersect(), array_intersect_assoc(), array_uintersect(), array_uintersect_assoc() and array_uintersect_uassoc().

array_diff

(PHP 4 >= 4.0.1, PHP 5)

array_diff -- Calcola la differenza di due o più array

Descrizione

array array_diff ( array array1, array array2 [, array ...])

array_diff() restituisce un array contenente tutti i valori di array1 che non sono presenti in alcuno degli altri array. Si noti che le associazioni con le chiavi vengono mantenute.

Esempio 1. Esempio di array_diff()

<?php
$array1 = array("a" => "verde", "rosso", "blu", "rosso");
$array2 = array("b" => "verde", "giallo", "rosso");
$risultato = array_diff($array1, $array2);

print_r($result);
?>

Occorrenze multiple in $array1 sono tutte trattate nello stesso modo. Questo codice mostrerà:

Array
(
    [1] => blu
)

Nota: Due elementi sono considerati uguali se e solo se (string) $elem1 === (string) $elem2. Ovvero: quando la rappresentazione sotto forma di stringa è la stessa.

Nota: Si noti che questa funzione controlla solo una dimensione di un array n-dimensionale. Ovviamente è possibile controllare le altre dimensioni usando array_diff($array1[0], $array2[0]);.

Avvertimento

Questa funzione era errata nel PHP 4.0.4!

Vedere anche array_diff_assoc(), array_intersect() e array_intersect_assoc().

array_fill

(PHP 4 >= 4.2.0, PHP 5)

array_fill -- Riempie un array con i valori specificati

Descrizione

array array_fill ( int inizio, int num, mixed valore)

array_fill() riempie un array con num elementi inizializzati con il valore del parametro valore, e con le chiavi che partono dal valore del parametro start_index. Si noti che num deve essere un valore maggiore di zero, altrimenti PHP mostrerà un avvertimento.

Esempio 1. esempio di array_fill()

<?php
$a = array_fill(5, 6, 'banana');
print_r($a);
?>

$a ora è:

Array
(
    [5]  => banana
    [6]  => banana
    [7]  => banana
    [8]  => banana
    [9]  => banana
    [10] => banana
)

Vedere anche str_repeat() e range().

array_filter

(PHP 4 >= 4.0.6, PHP 5)

array_filter --  Filtra gli elementi di un array usando una funzione callback

Descrizione

array array_filter ( array input [, callback callback])

array_filter() esegue un'iterazione su ogni valore nell' array input passandolo alla funzione. Se funzione restituisce TRUE, il valore corrente di input viene restituito nell'array risultato. Le chiavi sono mantenute.

Esempio 1. Esempio di array_filter()

<?php
function dispari($var) 
{
    return($var % 2 == 1);
}

function pari($var) 
{
    return($var % 2 == 0);
}

$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);

echo "Dispari :\n";
print_r(array_filter($array1, "dispari");
echo "Pari :\n";
print_r(array_filter($array2, "pari");
?>

Il risultato di questo sarà:

Dispari :
Array
(
    [a] => 1
    [c] => 3
    [e] => 5
)
Pari:
Array
(
    [0] => 6
    [2] => 8
    [4] => 10
    [6] => 12
)

Gli utenti non possono modificare l'array attraverso la funzione di callback, ad esempio aggiungere/togliere un elemento, o cancellare l'array su cui array_filter() è applicata. Se l'array viene cambiato, il comportamento di questa funzione non è definito.

Se la funzione callback non viene indicata, array_filter() rimuoverà tutti gli elementi di input che siano uguali a FALSE. Vedere conversione a boolean per ulteriori informazioni.

Esempio 2. array_filter() senza callback

<?php

$entry = array(
             0 => 'pippo',
             1 => false,
             2 => -1,
             3 => null,
             4 => ''
          );

print_r(array_filter($entry));
?>

Questo mostrerà:

Array
(
    [0] => pippo
    [2] => -1
)

Vedere anche array_map() e array_reduce().

array_flip

(PHP 4 , PHP 5)

array_flip -- Scambia tutte le chiavi di un array con i loro valori associati

Descrizione

array array_flip ( array trans)

array_flip() restituisce un array scambiato, ovvero le chiavi di trans diventano valori e i valori di trans diventano chiavi.

Si noti che i valori di trans devono poter diventare chiavi valide, ovvero devo essere di tipo integer o string. Un errore verrà segnalato se un valore ha il tipo errato, e la coppia chiave/valore in questione non verrà scambiata.

Se un valore ha più di una occorrenza, L'ultima chiave verrà usata come valore, e tutte le altre verranno perse.

array_flip() restituisce FALSE se fallisce.

Esempio 1. Esempio di array_flip()

<?php
$trans = array_flip($trans);
$original = strtr($str, $trans);
?>

Esempio 2. Esempio di array_flip(): collisione

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

ora $trans è:

Array
(
    [1] => b
    [2] => c
)

Vedere anche array_values(), array_keys() e array_reverse().

array_intersect_assoc

(PHP 4 >= 4.3.0, PHP 5)

array_intersect_assoc -- Calcola l'intersezione degli array con un ulteriore controllo sugli indici

Descrizione

array array_intersect_assoc ( array array1, array array2 [, array ...])

array_intersect_assoc() restituisce un array contenente tutti i valori di array1 che siano presenti in tutti gli array passati come argomento. Si noti che le chiavi sono utilizzate nel confronto, diversamente da array_intersect().

Esempio 1. esempio di array_intersect_assoc()

<?php
$array1 = array("a" => "verde", "b" => "marrone", "c" => "blu", "rosso");
$array2 = array("a" => "verde", "giallo", "rosso");
$result_array = array_intersect_assoc($array1, $array2);
?>

$result_array sarà:

Array
(
    [a] => verde
)

Nell'esempio si vede che solo la coppia "a" => "verde" è presente in entrambi gli array e quindi viene restituita. Il valore "rosso" non viene restituito perché in $array1 la sua chiave è 0 mentre la chiave di "rosso" in $array2 è 1.

I due valori delle coppie chiave => valore sono considerati uguali solo se (string) $elem1 === (string) $elem2 . In altre parole viene eseguito un controllo stringente che si accerta che le rappresentazioni sotto forma di stringa siano uguali.

Vedere anche array_intersect() array_diff() e array_diff_assoc().

array_intersect

(PHP 4 >= 4.0.1, PHP 5)

array_intersect -- Calcola l'intersezione degli arrays

Descrizione

array array_intersect ( array array1, array array2 [, array ...])

array_intersect() restituisce un array contenente tutti i valori di array1 che siano presenti in tutti gli array passati come argomento. Si noti che le associazioni con le chiavi sono mantenute.

Esempio 1. Esempio di array_intersect()

<?php
$array1 = array("a" => "verde", "rosso", "blu");
$array2 = array("b" => "verde", "giallo", "rosso");
$risultato = array_intersect($array1, $array2);
?>

In questo modo $result sarà:

Array
(
    [a] => verde
    [0] => rosso
)

Nota: Due elementi sono considerati uguali solo e solo se (string) $elem1 === (string) $elem2. Ovvero: quando la rappresentazione sotto forma di stringa è la stessa.

Vedere anche array_intersect_assoc(), array_diff() e array_diff_assoc().

array_key_exists

(PHP 4 >= 4.1.0, PHP 5)

array_key_exists -- Controlla se l'indice (o chiave) specificato esiste nell'array

Descrizione

bool array_key_exists ( mixed chiave, array cerca)

array_key_exists() restituisce TRUE se il parametro chiave esiste nell'array. chiave può essere qualsiasi valore accettabile per un indice di array.

Esempio 1. esempio di array_key_exists()

<?php
$un_array = array("primo" => 1, "secondo" => 4);
if (array_key_exists("primo", $un_array)) {
    echo "L'elemento 'primo' è nell'array";
    }
    ?>

Nota: Il nome di questa funzione è key_exists() nel PHP 4.0.6.

Vedere anche isset(), array_keys() e in_array().

array_keys

(PHP 4 , PHP 5)

array_keys -- Restituisce tutte le chiavi di un array

Descrizione

array array_keys ( array input [, mixed valore_ricerca])

array_keys() rstituisce le chiavi, numeriche e stringa, dell'array input.

Se il parametro opzionale valore_ricerca è specificato, solo le chiavi che corrispondono a quel valore vengono restituite. Altrimenti, vengono restituite tutte le chiavi dell'array input.

Esempio 1. Esempio di array_keys()

?php
$array = array(0 => 100, "colore" => "rosso");
print_r(array_keys($array))

$array = array("blu", "rosso", "verde", "blu", "blu");
print_r(array_keys($array, "blu"));

$array = array("colore" => array("blu", "rosso", "verde"),
               "misura" =&gt; array("piccola", "media", "grande"));
print_r(array_keys($array));
?>

Il risultato di questo programma sarà:

Array
(
    [0] => 0
    [1] => colore
)
Array
(
    [0] => 0
    [1] => 3
    [2] => 4
)
Array
(
    [0] => colore
    [1] => misura
)

Vedere anche array_values() e array_key_exists().

array_map

(PHP 4 >= 4.0.6, PHP 5)

array_map --  Applica la funzione callback a tutti gli elementi dell'array dato

Descrizione

array array_map ( mixed funzione, array arr1 [, array ...])

array_map() restituisce un array contenente tutti gli elementi di arr1 dopo che è stata loro applicata la funzione callback. Il numero di parametri che la funzione callback accetta deve corrispondere al numero di array passati alla funzione array_map()

Esempio 1. Esempio di array_map()

<?php
function cubo($n) 
{
    return($n * $n * $n);
}

$a = array(1, 2, 3, 4, 5);
$b = array_map("cubo", $a);
print_r($b);
?>

In questo modo $b sarà:

Array
(
    [0] => 1
    [1] => 8
    [2] => 27
    [3] => 64
    [4] => 125
)

Esempio 2. array_map() - usare più array

<?php
function mostra_Spagnolo($n, $m) 
{
    return("Il numero $n si dice $m in Spagnolo");
}

function mappa_Spagnolo($n, $m) 
{
    return(array($n => $m));
}

$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");

$c = array_map("mostra_Spagnolo", $a, $b);
print_r($c);

$d = array_map("mappa_Spagnolo", $a, $b);
print_r($d);
?>

Questo restituisce:

//stampa di $c
Array
(
    [0] => Il numero 1 si dice uno in Spagnolo
    [1] => Il numero 2 si dice dos in Spagnolo
    [2] => Il numero 3 si dice tres in Spagnolo
    [3] => Il numero 4 si dice cuatro in Spagnolo
    [4] => Il numero 5 si dice cinco in Spagnolo
)

// stampa di $d
Array
(
    [0] => Array
        (
            [1] => uno
        )

    [1] => Array
        (
            [2] => dos
        )

    [2] => Array
        (
            [3] => tres
        )

    [3] => Array
        (
            [4] => cuatro
        )

    [4] => Array
        (
            [5] => cinco
        )

)

Generalmente, quando si usano due o più array, questi devono avere eguale lunghezza in quanto la funzione callback viene applicata in parallelo agli elementi corrispondenti. Se gli array sono di lunghezza diversa, il più corto verrà esteso con elementi vuoti.

Un uso interessante di questa funzione è quello di costruire un array di array, cosa che può essere facilmente ottenuta usando NULL come nome della funzione callback

Esempio 3. Creare un array di array

<?php
$a = array(1, 2, 3, 4, 5);
$b = array("uno", "due", "tre", "quattro", "cinque");
$c = array("uno", "dos", "tres", "cuatro", "cinco");

$d = array_map(null, $a, $b, $c);
print_r($d);
?>

Il risultato di questo programma sarà;

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => uno
            [2] => uno
        )

    [1] => Array
        (
            [0] => 2
            [1] => due
            [2] => dos
        )

    [2] => Array
        (
            [0] => 3
            [1] => tre
            [2] => tres
        )

    [3] => Array
        (
            [0] => 4
            [1] => quattro
            [2] => cuatro
        )

    [4] => Array
        (
            [0] => 5
            [1] => cinque
            [2] => cinco
        )

)

Vedere anche array_filter(), array_reduce() e array_walk().

array_merge_recursive

(PHP 4 >= 4.0.1, PHP 5)

array_merge_recursive -- Fonde due o più array in modo ricorsivo

Descrizione

array array_merge_recursive ( array array1, array array2 [, array ...])

Array_merge_recursive() fonde gli elementi di due o più array in modo tale che i valori di un array siano accodati all'array precedente. Restituisce l'array risultante.

Se gli array in input hanno le stesse chiavi stringa, i valori di queste chiavi vengono fusi in un array, e questo è fatto in modo ricorsivo, cio` se uno dei valori è un array, la funzione lo fonder%agrave; con una voce corrispondente in un altro array Comunque, se gli array hanno la stessa chiave numerica, l'ultimo valore non sovrascriver` il valore originale, bensì verrà accodato.

Esempio 1. Esempio di array_merge_recursive()

<?php
$ar1 = array("colore" => array ("preferito" => "rosso"), 5);
$ar2 = array(10, "colore" => array ("preferito" => "verde", "blu"));
$risultato = array_merge_recursive($ar1, $ar2);
?>

La variabile $risultato sarà:

Array
(
    [colore] => Array
        (
             [preferito] => Array
                (
                    [0] => rosso
                    [1] => verde
                )

            [0] => blu
        )

    [0] => 5
    [1] => 10
)

Vedere anche array_merge().

array_merge

(PHP 4 , PHP 5)

array_merge -- Fonde due o più array

Descrizione

array array_merge ( array array1, array array2 [, array ...])

array_merge() fonde gli elementi di due o più array in modo che i valori di un array siano accodati a quelli dell'array precedente. Restituisce l'array risultante.

Se gli array in input hanno le stesse chiavi stringa, l'ultimo valore di quella chiave sovrascriverà i precedenti. Comunque, se gli array hanno le stesse chiavi numeriche, l'ultimo valore non sovrascriverà quello originale, bensì sarà accodato.

Esempio 1. Esempio di array_merge()

<?php
$array1 = array("colore" => "rosso", 2, 4);
$array2 = array("a", "b", "colore" => "verde", "forma" => "trapezio", 4);
$risultato = array_merge($array1, $array2);
print_r($risultato);
?>

La variabile $risultato sarà:

Array
(
    [colore] => verde
    [0] => 2
    [1] => 4
    [2] => a
    [3] => b
    [forma] => trapezio
    [4] => 4
)

Esempio 2. Esempio di array_merge()

<?php
$array1 = array();
$array2 = array(1 => "dati");
$result = array_merge($array1, $array2);
?>

Non dimenticarsi che le chiavi numeriche saranno rinumerate!

Array
(
    [0] => data
)

Se si vogliono preservare gli array e li si vuole solo concatenare, usare l'operatore +:

<?php
$array1 = array();
$array2 = array(1 => "dati");
$result = $array1 + $array2;
?>

La chiave numerica sarà preservata e così pure l'associazione.

Array
(
    [1] => data
)

Nota: Le chiavi condivise verranno sovrascritte dalla prima chiave processata.

Vedere anche array_merge_recursive() e array_combine() e operatori sugli array.

array_multisort

(PHP 4 , PHP 5)

array_multisort -- Ordina array multipli o multidimensionali

Descrizione

bool array_multisort ( array ar1 [, mixed arg [, mixed ... [, array ...]]])

Array_multisort() Può essere usata per ordinare parecchi array allo stesso tempo, oppure un array multidimensionale, rispetto a una o più dimensioni. Mantiene le associazioni delle chiavi durante l'ordinamento, mentre le chiavi numeriche vengono reindicizzate.

Gli array in input sono trattati come campi di una tabella che vengano ordinati per righe - questo assomiglia alla funzionalità della clausola SQL ORDER BY Il primo array è quello primario, rispetto a cui ordinare. Le righe (valori) in questo array that siano uguali vengono ordinate secondo l'array successivo, e così via.

La struttura degli argomenti di questa funzione è un po' inusuale, ma flessibile. Il primo argomento deve essere un array. In seguito, ogni argomento può essere sia un array che un flag di ordinamento, selezionabile dalla seguente lista.

Flag di ordinamento:

  • SORT_ASC - ordinamento crescente

  • SORT_DESC - ordinamento decrescente

Sorting type flags:

  • SORT_REGULAR - confronta gli elementi in modo normale

  • SORT_NUMERIC - confronta gli elementi numericamente

  • SORT_STRING - confronta gli elementi come stringhe

Dopo ogni array, non si possono specificare due flag dello stesso tipo. I flag specificati dopo un array si applicano solo a quell'array - sono reimpostati ai default SORT_ASC e SORT_REGULAR prima di ogni nuovo array passato come argomento.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. Ordinamre più array

<?php
$ar1 = array("10", 100, 100, "a");
$ar2 = array(1, 3, "2", 1);
array_multisort($ar1, $ar2);
?>

In questo esempio, dopo l'ordinamento, il primo array conterrà "10", "a", 100, 100. Il secondo array conterrà 1, 1, "2", 3. Gli elementi nel secondo array che corrispondono agli elementi identici nel primo array (100 e 100) vengono pure ordinati.

Esempio 2. Ordinare un array multi-dimensionale

<?php
$ar = array(array ("10", 100, 100, "a"), array (1, 3, "2", 1));
array_multisort($ar[0], SORT_ASC, SORT_STRING,
                $ar[1], SORT_NUMERIC, SORT_DESC);
?>

In questo esempio, dopo l'ordinamento, il primo array conterrà 10, 100, 100, "a" (ordinato come stringhe ordine crescente), e il secondo conterrà 1, 3, "2", 1 (ordinati come numeri, in ordine decrescente).

array_pad

(PHP 4 , PHP 5)

array_pad --  Riempie con un valore un array fino alla lunghezza specificata

Descrizione

array array_pad ( array input, int pad_size, mixed pad_value)

array_pad() restituisce una copia di input allungato alla dimensione sepcificata da pad_size con il valore pad_value. Se pad_size è positivo l'array è riempito sulla destra, se è negativo sulla sinistra. Se il valore assoluto di pad_size è minore o uguale alla lunghezza di input non viene effettuata alcuna modifica.

Esempio 1. esempio di array_pad()

<?php
$input = array(12, 10, 9);

$risultato = array_pad($input, 5, 0);
// risultato diventa array(12, 10, 9, 0, 0)

$risultato = array_pad($input, -7, -1);
// risultato diventa array(-1, -1, -1, -1, 12, 10, 9)

$risultato = array_pad($input, 2, "noop");
// ridimensionamento non efettuato
?>

Vedere anche array_fill() e range().

array_pop

(PHP 4 , PHP 5)

array_pop -- Estrae l'elemento alla fine dell'array

Descrizione

mixed array_pop ( array array)

array_pop() estrae e restituisce l'ultimo valore di array, accorciando array di un elemento. Se array è vuoto (o non è un array), viene restituito NULL.

Nota: Questa funzione farà il reset() del puntatore dell'array dopo l'uso.

Esempio 1. esempio di array_pop()

<?php
$pila = array("arancia", "banana", "mela", "lampone");
$frutto = array_pop($pila);
print_r($pila);
?>

Dopo questa istruzione, $pila avrà solo 3 elementi:

Array
(
    [0] => arancia
    [1] => banana
    [2] => mela
)

e lampone verrà assegnato alla variabile $frutto.

Avvertimento

Questa funzione può restituire il Booleano FALSE, ma può anche restituire un valore non-Booleano valutato come FALSE, come ad esempio 0 o "". Per favore fare riferimento alla sezione Booleans per maggiori informazioni. Usare l'operatore === per controllare il valore restituito da questa funzione.

Vedere anche array_push(), array_shift() e array_unshift().

array_push

(PHP 4 , PHP 5)

array_push --  Accoda uno o più elementi ad un array

Descrizione

int array_push ( array array, mixed var [, mixed ...])

array_push() tratta array come una pila, e accoda le variabili date alla fine di array. La lunghezza di array aumenta del numero di variabili accodate. Ha lo stesso effetto di:
<?php
$array[] = $var;
?>
ripetuto per ogni var.

Restituisce il nuovo numero di elementi nell'array.

Esempio 1. esempio di array_push()

<?php
$pila = array("arancia", "banana");
array_push($pila, "mela", "lampone");
print_r($pila);
?>

In questo esempio $pila avrà i seguenti elementi:

Array
(
    [0] => arancia
    [1] => banana
    [2] => mela
    [3] => lampone
)

Nota: Se si utilizza array_push() per aggiungere un elemento all'array, è preferibile piuttosto utilizzare $array[] = poiché in questo modo non c'è il tempo d'attesa per la chiamata di funzione.

Vedere anche array_pop(), array_shift() e array_unshift().

array_rand

(PHP 4 , PHP 5)

array_rand --  Estrae a caso uno o più elementi da un array

Descrizione

mixed array_rand ( array input [, int num_req])

array_rand() è piuttosto utile quando si vuole estrarre a caso uno o più elementi da un array. Prende un array (input) e un argomento ozpionale (num_req) che specifica quanti elementi estrarre - se non è specificato, è 1 per default.

Se si sta estraendo solo un elemento, array_rand() restituisce la chiave di un elemento. Altrimenti, restituisce un array di chiavi. Questo viene fatto in modo da permettere di estrarre dall'array sia le chiavi che i valori.

Nota: Come in PHP 4.2.0, non vi è necessità di inizializzare il generatore di numeri casuali con srand() oppure con mt_srand() poichè viene eseguito in modo automatico.

Esempio 1. esempio di array_rand()

<?
srand((float) microtime() * 10000000);
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$chiavi = array_rand($input, 2);
echo $input[$chiavi[0]] . "\n";
echo $input[$chiavi[1]] . "\n";
?>

Vedere anche shuffle().

array_reduce

(PHP 4 >= 4.0.5, PHP 5)

array_reduce --  Riduce iterativamente l'array a un singolo valore utilizzando una funzione callback

Descrizione

mixed array_reduce ( array input, callback funzione [, int initial])

array_reduce() applica iterativamente la funzione callback agli elementi dell'array input, riducendo l'array a un singolo valore. Seil parametro opzionale intial è specificato, viene usato come valore iniziale all'inizio del processo, o come risultato finale nel caso l'array sia vuoto.

Esempio 1. esempio di array_reduce()

<?php
function rsum($v, $w) 
{
    $v += $w;
    return $v;
}

function rmul($v, $w) 
{
    $v *= $w;
    return $v;
}

$a = array(1, 2, 3, 4, 5);
$x = array();
$b = array_reduce($a, "rsum");
$c = array_reduce($a, "rmul", 10);
$d = array_reduce($x, "rsum", 1);
?>

In questo modo $b conterrà 15, $c conterrà 1200 (= 1*2*3*4*5*10) e $d conterrà 1.

Vedere anche array_filter() e array_map(), array_unique() e array_count_values().

array_reverse

(PHP 4 , PHP 5)

array_reverse --  Restituisce un array con gli elementi in ordine invertito

Descrizione

array array_reverse ( array array [, bool mantieni_chiavi])

array_reverse() prende array e restituisce un nuovo array con l'ordine degli elementi invertito, mantenendo le chiavi sie mantieni_chiavi è TRUE.

Esempio 1. esempio di array_reverse()

<?php
$input  = array("php", 4.0, array("verde", "rosso"));
$risultato = array_reverse($input);
$resultato_chiavi = array_reverse($input, true);
?>

Questo fa sì che sia $risultato che $risultato_chiavi abbiano gli stessi elementi, ma si noti la differenza tra le chiavi. La stampa di $risultato e $risultato_chiavi sarà:

Array
(
    [0] => Array
        (
            [0] => verde
            [1] => rosso
        )

    [1] => 4
    [2] => php
)
Array
(
    [2] => Array
        (
            [0] => verde
            [1] => rosso
        )

    [1] => 4
    [0] => php
)

Nota: Il secondo parametro è stato aggiunto in PHP 4.0.3.

Vedere anche array_flip().

array_search

(PHP 4 >= 4.0.5, PHP 5)

array_search --  Ricerca un dato valore in un array e ne restituisce la chiave corrispondente, se la ricerca ha successo.

Descrizione

mixed array_search ( mixed ago, array pagliaio [, bool strict])

Cerca in pagliaio per trovare ago e restituisce la chiave se viene trovato nell'array, FALSE altrimenti.

Nota: Se ago è una stringa, il confronto è fatto tenendo conto delle maiuscole/minuscole.

Nota: Nelle versioni di PHP antecedenti la 4.2.0, array_search() restituisce NULL invece di FALSE in caso di fallimento.

Se il terzo parametro opzionale strict è impostato a TRUE la funzione array_search() controllerà anche il tipo di ago nell'array pagliaio.

Se ago viene ritrovato in pagliaio più di una nolta, viene restituita la prima chiave trovata. Per restituire le chiavi di tutti i valori, utilizzare array_keys() con il parametro opzionale valore_ricerca.

Esempio 1. esempio di array_search()

<?php
$array = array(0 => 'blu', 1 => 'rosso', 2 => 'verde', 3 => 'rosso');

$chiave = array_search('verde', $array); // $chiave = 2;
$chiave = array_search('rosso', $array); // $chiave = 1;
?>

Avvertimento

Questa funzione può restituire il Booleano FALSE, ma può anche restituire un valore non-Booleano valutato come FALSE, come ad esempio 0 o "". Per favore fare riferimento alla sezione Booleans per maggiori informazioni. Usare l'operatore === per controllare il valore restituito da questa funzione.

Vedere anche array_keys(), array_values(), array_key_exists() e in_array().

array_shift

(PHP 4 , PHP 5)

array_shift --  Estrae l'elemento alla testa dell'array

Descrizione

mixed array_shift ( array array)

array_shift() estrae il primo elemento di array e lo restituisce, accorciando array di un elemento e spostando tutti gli altri all'indietro. Tutte le chiavi numeriche verranno modificate al fine di iniziare il conteggio da zero, mentre gli indici alfabetici non verranno modificati. Se array è vuoto (o non è un array), viene restituito NULL.

Nota: Questa funzione farà il reset() del puntatore dell'array dopo l'uso.

Esempio 1. esempio di array_shift()

<?php
$pila = array("arancia", "banana", "mela", lampone");
$frutto = array_shift($pila);
print_r($pila);
?>

In questo modo $pila rimarrà con 3 elementi:

Array
(
    [0] => banana
    [1] => mela
    [2] => lampone
)

e arancia sarà assegnata a $frutto.

Vedere anche array_unshift(), array_push() e array_pop().

array_slice

(PHP 4 , PHP 5)

array_slice -- Estrae un sottoinsieme da un array

Descrizione

array array_slice ( array array, int offset [, int length])

array_slice() restituisce la sequenza di elementi dell'array array come specificato dai parametri offset e length .

Se offset è positivo, la sequenza comincerà da quell'offset in array. Se offset è negativo, la sequenza comincerà alla distanza offset dalla fine di array.

Se length è specificata ed è positiva, la sequenza conterrà quel numero di elementi. Se length è specificata ed è negativa la sequenza si fermerà a quel numero di elementi dalla fine dell'array. Se viene omessa, la sequenza conterrà tutto da offset fino alla fine di array.

Si noti che array_slice() ignorerà le chiavi dell'array, e calcolerè gli spiazzamenti e le lunghezze basandosi sulle posizioni correnti degli elementi nell'array.

Esempio 1. esempi di array_slice()

<?php
$input = array("a", "b", "c", "d", "e");

$output = array_slice($input, 2);      // restituisce "c", "d" e "e"
$output = array_slice($input, 2, -1);  // restituisce "c", "d"
$output = array_slice($input, -2, 1);  // restituisce "d"
$output = array_slice($input, 0, 3);   // restituisce "a", "b" e "c"
?>

Vedere anche array_splice() e unset().

array_splice

(PHP 4 , PHP 5)

array_splice --  Rimuove una porzione dell'array e la sostituisce con altro

Descrizione

array array_splice ( array input, int offset [, int length [, array replacement]])

array_splice() rimuove gli elementi specificati da offset e length dall'array input, e li sostituisce con gli elementi dell'array replacement, se fornito. Restituisce un array contenente gli elementi estratti.

Se offset è positivo l'inizio della porzione rimossa è a quella distanza dall'inizio dell'array input. Se offset è negativo inizia a quella distanza dalla fine dell'array input.

Se length è omessa, rimuove tutti gli elementi da offset alla fine dell'array. Se length è specificata a positiva, quel numero di elementi vengono rimossi. Se length è specificata e negativa la porzione da rimuovere terminerà a length elementi dalla fine dell'array. Suggerimento: per rimuovere tutti gli elementi tra offset e la fine dell'array quando è specificato pure replacement, usare count($input) nel parametro length.

Se l'array replacement è specificato, gli elementi rimossi sono sostituiti dagli elementi di questo array. Se offset e length sono tali per cui niente viene rimosso, gli elementi dell'array replacement sono inseriti nella posizione specificata da offset. Suggerimento: se replacement è composto solo da un elemento non è necessario porlo nel costrutto array(), a meno che l'elemento stesso non sia un array.

Valgono le seguenti equivalenze:

Tabella 1. array_splice() equivalents

array_push($input, $x, $y) array_splice($input, count($input), 0, array($x, $y))
array_pop($input) array_splice($input, -1)
array_shift($input) array_splice($input, -1)
array_unshift($input, $x, $y) array_splice($input, 0, 0, array($x, $y))
$a[$x] = $y array_splice($input, $x, 1, $y)

Restituisce un array contenente gli elementi rimossi.

Esempio 1. esempi di array_splice()

<?php
$input = array("rosso", "verde", "blu", "giallo");
array_splice($input, 2);
// $input è ora array("rosso", "verde")

$input = array("rosso", "verde", "blu", "giallo");
array_splice($input, 1, -1);
// $input è ora array("rosso", "giallo")

$input = array("rosso", "verde", "blu", "giallo");
array_splice($input, 1, count($input), "arancio");
// $input è ora array("rosso", "arancio")

$input = array("rosso", "verde", "blu", "giallo");
array_splice($input, -1, 1, array("nero", "marrone"));
// $input è ora array("rosso", "verde",
//          "blu", "nero", "marrone")

$input = array("rosso", "verde", "blu", "giallo");
array_splice($input, 3, 0, "viola");
// $input è ora array("rosso", "verde",
//          "blu", "viola", "giallo");
?>

Vedere anche array_slice()i, unset() e array_merge().

array_sum

(PHP 4 >= 4.0.4, PHP 5)

array_sum --  Calcola la somma dei valori di un array.

Descrizione

mixed array_sum ( array array)

array_sum() restituisce la somma dei valori dell'array sotto forma di integer o float.

Esempio 1. esempi di array_sum()

<?php
$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";

$b = array("a" => 1.2, "b" => 2.3, "c" => 3.4);
echo "sum(b) = " . array_sum($b) . "\n";
?>

Il risultato di questo programma sarà:

sum(a) = 20
sum(b) = 6.9

Nota: Le versioni di PHP antecedenti alla 4.2.1 modificavano l'array stesso e convertivano le stringhe in numeri (le quali erano convertite in zeri la maggior parte delle volte, a seconda dal valore).

array_udiff_assoc

(PHP 5)

array_udiff_assoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function.

Description

array array_udiff_assoc ( array array1, array array2 [, array ..., callback data_compare_func])

array_udiff_assoc() returns an array containing all the values from array1 that are not present in any of the other arguments. Note that the keys are used in the comparison unlike array_diff() and array_udiff(). The comparison of arrays' data is performed by using an user-supplied callback. In this aspect the behaviour is opposite to the behaviour of array_diff_assoc() which uses internal function for comparison.

Esempio 1. array_udiff_assoc() example

<?php
class cr {
    private $priv_member;
    function cr($val) 
    {
        $this->priv_member = $val;
    }
    
    function comp_func_cr($a, $b) 
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
}

$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),);
$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr"));
print_r($result);
?>

The result is:

Array
(
    [0.1] => cr Object
        (
            [priv_member:private] => 9
        )

    [0.5] => cr Object
        (
            [priv_member:private] => 12
        )

    [0] => cr Object
        (
            [priv_member:private] => 23
        )
)

In our example above you see the "1" => new cr(4) pair is present in both arrays and thus it is not in the ouput from the function.

For comparison is used the user supplied callback function. It must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

Nota: Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using, for example, array_udiff_assoc($array1[0], $array2[0], "some_comparison_func");.

See also array_diff(), array_diff_assoc(), array_diff_uassoc(), array_udiff(), array_udiff_uassoc(), array_intersect(), array_intersect_assoc(), array_uintersect(), array_uintersect_assoc() and array_uintersect_uassoc().

array_udiff_uassoc

(PHP 5)

array_udiff_uassoc -- Computes the difference of arrays with additional index check. The data is compared by using a callback function. The index check is done by a callback function also

Description

array array_udiff_uassoc ( array array1, array array2 [, array ..., callback data_compare_func, callback key_compare_func])

array_udiff_uassoc() returns an array containing all the values from array1 that are not present in any of the other arguments. Note that the keys are used in the comparison unlike array_diff() and array_udiff(). The comparison of arrays' data is performed by using an user-supplied callback : data_compare_func. In this aspect the behaviour is opposite to the behaviour of array_diff_assoc() which uses internal function for comparison. The comparison of keys (indices) is done also by the callback function key_compare_func. This behaviour is unlike what array_udiff_assoc() does, since the latter compares the indices by using an internal function.

Esempio 1. array_udiff_uassoc() example

<?php
class cr {
    private $priv_member;
    function cr($val) 
    {
        $this->priv_member = $val;
    }

    function comp_func_cr($a, $b) 
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
    
    function comp_func_key($a, $b) 
    {
        if ($a === $b) return 0;
        return ($a > $b)? 1:-1;
    }
}
$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),);
$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff_uassoc($a, $b, array("cr", "comp_func_cr"), array("cr", "comp_func_key"));
print_r($result);
?>

The result is:

Array
(
    [0.1] => cr Object
        (
            [priv_member:private] => 9
        )

    [0.5] => cr Object
        (
            [priv_member:private] => 12
        )

    [0] => cr Object
        (
            [priv_member:private] => 23
        )
)

In our example above you see the "1" => new cr(4) pair is present in both arrays and thus it is not in the ouput from the function. Keep in mind that you have to supply 2 callback functions.

For comparison is used the user supplied callback function. It must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

Nota: Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using, for example, array_udiff_uassoc($array1[0], $array2[0], "data_compare_func", "key_compare_func");.

See also array_diff(), array_diff_assoc(), array_diff_uassoc(), array_udiff(), array_udiff_assoc(), array_intersect(), array_intersect_assoc(), array_uintersect(), array_uintersect_assoc() and array_uintersect_uassoc().

array_udiff

(PHP 5)

array_udiff -- Computes the difference of arrays by using a callback function for data comparison.

Description

array array_udiff ( array array1, array array2 [, array ..., callback data_compare_func])

array_udiff() returns an array containing all the values of array1 that are not present in any of the other arguments. Note that keys are preserved. For the comparison of the data data_compare_func is used. It must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. This is unlike array_diff() which uses an internal function for comparing the data.

Esempio 1. array_udiff() example

<?php
class cr {
    private $priv_member;
    function cr($val) 
    {
        $this->priv_member = $val;
    }
    
    function comp_func_cr($a, $b) 
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
}
$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),);
$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff($a, $b, array("cr", "comp_func_cr"));
print_r($result);
?>

The result is:

Array
(
    [0.5] => cr Object
        (
            [priv_member:private] => 12
        )

    [0] => cr Object
        (
            [priv_member:private] => 23
        )

)

Nota: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.

Nota: Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using array_udiff($array1[0], $array2[0], "data_compare_func");.

See also array_diff(), array_diff_assoc(), array_diff_uassoc(), array_udiff_assoc(), array_udiff_uassoc(), array_intersect(), array_intersect_assoc(), array_uintersect(), array_uintersect_assoc() and array_uintersect_uassoc().

array_unique

(PHP 4 >= 4.0.1, PHP 5)

array_unique -- Rimuove i valori duplicati di un array

Descrizione

array array_unique ( array array)

array_unique() prende array e restituisce un nuovo array senza i valori duplicati.

Si noti che le chiavi sono mantenute. array_unique() ordina i valori trattandoli come stringhe, quindi mantiene la prima chiave trovata per ogni valore, e ignorerà tutte le altre chiavi. Questo non significa che la chiave del primo valore dell'array non ancora ordinato verrà mantenuta.

Nota: Due elementi sono considerati uguali se e solo se (string) $elem1 === (string) $elem2. Ovvero: quando la rappresentazione sotto forma di stringa è la stessa.

Verrà usato il primo elemento.

Esempio 1. esempio di array_unique()

<?php
$input = array("a" => "verde", "rosso", "b" => "verde", "blu", "rosso");
$risultato = array_unique($input);
print_r($result);
?>

Questo mostrerà:

Array
(
    [b] => verde
    [1] => blu
    [2] => rosso
)

Esempio 2. array_unique() e i tipi

<?php
$input = array(4, "4", "3", 4, 3, "3");
$risultato = array_unique($input);
var_dump($risultato);
?>

Questo script mostrerà:

array(2) {
  [0] => int(4)
  [2] => string(1) "3"
}

array_unshift

(PHP 4 , PHP 5)

array_unshift --  Inserisce uno o più elementi all'inizio dell'array

Descrizione

int array_unshift ( array array, mixed var [, mixed ...])

array_unshift() aggiunge gli elementi specificati in testa ad array. Si noti che la lista di elementi è aggiunta in blocco, in modo tale che gli elementi rimangano nello stesso ordine. Tutte le chiavi numeriche vengono modificate per iniziare da zero mentre le chiavi alfabetiche non sono modificate.

Restituisce il nuovo numero di elementi in array.

Esempio 1. esempio di array_unshift()

<?php
$lista = array("arancia", "banana");
array_unshift($lista, "mela", "lampone");
?>

In questo modo $lista conterrà i seguenti elementi:

Array
(
    [0] => mela
    [1] => lampone
    [2] => arancia
    [3] => banana
)

Vedere anche array_shift(), array_push() e array_pop().

array_values

(PHP 4 , PHP 5)

array_values -- Restituisce tutti i valori di un array

Descrizione

array array_values ( array input)

array_values() restituisce tutti i valori dell'array input e indicizza numericamente l'array.

Esempio 1. esempio di array_values()

<?php
$array = array("taglia" => "XL", "colore" => "oro");
print_r(array_values($array));
?>

Questo mostrerà:

Array
(
    [0] => XL
    [1] => oro
)

Vedere anche array_keys().

array_walk_recursive

(PHP 5)

array_walk_recursive --  Apply a user function recursively to every member of an array

Description

bool array_walk_recursive ( array input, string funcname [, mixed userdata])

Avvertimento

Questa funzione, al momento non è documentata; è disponibile soltanto la lista degli argomenti.

array_walk

(PHP 3>= 3.0.3, PHP 4 , PHP 5)

array_walk --  Esegue una funzione su ogni elemento dell'array

Descrizione

bool array_walk ( array array, callback funzione [, mixed datiutente])

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esegue la funzione definita dall'utente identificata da funzione su ogni elemento di array. Normalmente funzione accetta due parametri. Il valore del parametro array viene passato per primo, la chiave/indice per secondo. Se il parametro datiutente è specificato, verrà passato come terzo parametro alla funzione callback.

Se funzione richiede più parametri di quanti gliene vengono passati, un errore di livello E_WARNING verrà generato ogni volta che array_walk() la chiama. Questi avvertimenti possono essere soppressi apponendo l'operatore d'errore @ alla chiamata di array_walk(), oppure usando error_reporting().

Nota: Se funzione deve lavorare con i reali valori dell'array, specificare che il primo parametro di funzione deve essere passato come riferimento. A qesto punto ogni modifica a questi elementi verrà effettuata sull'array stesso.

Nota: Il passaggio della chiave e di datiutente a func è stato aggiunto nella versione 4.0.

array_walk() non è influenzato dal puntatore interno dell'array array. array_walk() percorrerà l'intero array indipendentemente dalla posizione del puntatore. Per reinizializzare il puntatore, utilizzare reset(). In PHP 3, array_walk() reinizializza il puntatore.

Gli utenti non possono modificare l'array attraverso la funzione di callback, ad esempio aggiungere/togliere un elemento, o cancellare l'array su cui array_walk() è applicata. Se l'array viene cambiato, il comportamento di questa funzione non è definito ed è imprevedibile.

Esempio 1. esempio di array_walk()

<?php
$frutta = array("d"=>"limone", "a"=>"arancia", "b"=>"banana", "c"=>"mela");

function modifica(&$elemento1, $chiave, $prefisso) 
{
    $elemento1 = "$prefisso: $elemento1";
}

function stampa($elemento2, $chiave) 
{
    echo "$chiave. $elemento2<br />\n";
}

echo "Prima ...:\n";
array_walk($frutta, 'stampa');

array_walk($frutta, 'modifica', 'frutto');
echo "... e dopo:\n";

array_walk($frutta, 'stampa');
?>

Il risultato del programma sarà:

Prima ...:
d. limone
a. arancia
b. banana
c. mela
... e dopo:
d. frutto: limone
a. frutto: arancia
b. frutto: banana
c. frutto: mela

Vedere anche create_function(), list(), foreach, each() e call_user_func_array().

array

(PHP 3, PHP 4, PHP 5 )

array --  Crea un array

Descrizione

array array ( [mixed ...])

Restituisce un array contenente i parametri. Ai parametri si può dare un indice con l'operatore =>. Leggere la sezione relativa ai tipi per ulteriori informazioni sugli array.

Nota: array() è un costrutto del linguaggio usato per rappresentare array letterali, e non una normale funzione.

La sintassi "indice => valori", separati da virgole, definisce indici e valori. indice può essere di tipo string o numerico. Quando l'indice è omesso, viene generato automaticamente un indice intero, a partire da 0. Se l'indice è un intero, il successivo indice generato sarà l'indice intero più grande + 1. Si noti che quando due indici identici vengono definiti, l'ultimo sovrascrive il primo.

L'esempio seguente dimostra come creare un array bidimensionale, come specificare le chiavi per gli array associativi, e come modificare la serie degli indici numerici negli array normali.

Esempio 1. Esempio di array()

<?php
$frutta = array (
    "frutta"  => array("a" => "arancia", "b" => "banana", "c" => "mela"),
    "numeri"  => array(1, 2, 3, 4, 5, 6),
    "buche"   => array("prima", 5 => "seconda", "terza")
)
?>

Esempio 2. Indice automatico con array()

<?php
$array = array(1, 1, 1, 1,  1, 8 => 1,  4 => 1, 19, 3 => 13);
print_r($array);
?>

che stamperà:

Array
(
    [0] => 1
    [1] => 1
    [2] => 1
    [3] => 13
    [4] => 1
    [8] => 1
    [9] => 19
)

Si noti che l'indice '3' è definito due volte, e che mantiene il valore finale 13. L'indice 4 è definito dopo l'indice 8, e il successivo indice generato (valore 19) è 9, dal momento che l'indice più grande era 8.

Questo esempio crea un array che parte da 1 (1-based).

Esempio 3. Indice 1-based con array()

<?php
$primotrimestre = array(1 => 'Gennaio', 'Febbraio', 'Marzo');
print_r($primotrimestre);
?>

che stamperà:

Array
(
    [1] => Gennaio
    [2] => Febbraio
    [3] => Marzo
)

Vedere anche array_pad(), list(), foreach e range().

arsort

(PHP 3, PHP 4 , PHP 5)

arsort --  Ordina un array in ordine decrescente e mantiene le associazioni degli indici

Descrizione

bool arsort ( array array [, int sort_flags])

Questa funzione ordina un array in modo tale che i suoi indici mantengano la loro correlazione con gli elementi ai quali sono associati. Viene usata principalmente nell'ordinamento degli array associativi, quando la disposizione originaria degli elementi è importante.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di arsort()

<?php
$frutta = array("d" => "limone", "a" => "arancia", "b" => "banana", "c" => "mela");
arsort($frutta);
reset($frutta);
while (list($chiave, $valore) = each($frutta)) {
    echo "$chiave = $valore\n";
}
?>

Questo esempio mostrerà:

c = mela
d = limone
b = banana
a = arancia

I frutti sono ordinati in ordine alfabetico decrescente, e l'indice associato a ogni elemento è stato mantenuto.

È possibile modificare il comportamento dell'ordinamento usando il parametro opzionale sort_flags, per maggiori dettagli vedere sort().

vedere anche asort(), rsort(), ksort() e sort().

asort

(PHP 3, PHP 4 , PHP 5)

asort -- Ordina un array e mantiene le associazioni degli indici

Descrizione

bool asort ( array array [, int sort_flags])

Questa funzione ordina un array in modo tale che i suoi indici mantengano la loro correlazione con gli elementi ai quali sono associati. Viene usata principalmente nell'ordinamento degli array associativi, quando la disposizione originaria degli elementi è importante.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di asort()

<?php
$frutta = array("d"=>"limone", "a"=>"arancia", "b"=>"banana", "c"=>"mela");
asort($frutta);
reset($frutta);
while (list($chiave, $valore) = each($frutta)) {
    echo "$chiave = $valore\n";
}
?>

Questo esempio mostrerà:

a = arancia
b = banana
d = limone
c = mela

I frutti sono ordinati in ordine alfabetico, e l'indice associato ad ogni elemento è stato mantenuto.

È possibile modificare il comportamento dell'ordinamento usando il parametro opzionale sort_flags, per maggiori dettagli vedere sort().

Vedere anche arsort(), rsort(), ksort() e sort().

compact

(PHP 4 , PHP 5)

compact --  Crea un array contenente variabili e il loro valore

Descrizione

array compact ( mixed varname [, mixed ...])

compact() accetta un numero variabile di parametri. Ogni parametro può essere una stringa contenente il nome della variabile, o un array di nomi di variabile. L'array può contenere altri array di nomi di variabile; compact() se ne occupa in modo ricorsivo.

Per ognuno di questi, compact() cerca la variabile con quel nome nella tabella dei simboli corrente, e la aggiunge all'array di output in modo tale che il nome della variabile diventi la chiave e i contenuti della variabile diventino il valore associato a quella chiave. In breve, compact() è l'opposto di extract(). Restituisce l'array di output con tutte le variabili aggiunte a quest'ultimo.

Qualsiasi stringa non valorizzata verrà semplicemente ignorata.

Esempio 1. esempio di compact()

<?php
$citta = "Milano";
$provincia = "MI";
$evento = "SMAU";

$var_luoghi = array("citta", "provincia");

$risultato = compact("evento", "niente", $var_luoghi);
?>

In questo modo, $risultato sarà:

Array
(
    [event] => SMAU
    [citta] => Milano
    [provincia] => MI
)

Vedere anche extract().

count

(PHP 3, PHP 4 , PHP 5)

count -- Conta gli elementi in una variabile

Descrizione

int count ( mixed var [, int mode])

Restituisce il numero di elementi in var, la quale è di norma un array (dal momento che qualsiasi altro oggetto avrà un elemento).

Se var non è un array, verrà restituito 1 (eccezione: count(NULL) restituisce 0).

Nota: Il parametro opzionale mode è disponibile da PHP 4.2.0.

Se il parametro opzionale mode è impostato a COUNT_RECURSIVE (o 1), count() conterà ricorsivamente l'array. Questo è utile in particolare per contare tutti gli elementi di un array multidimensionale. Il valore di default per mode è 0.

Attenzione

count() può restituire 0 per una variabile che non è impostata, ma può anche restituire 0 per una variabile che è stata inizializzata con un array vuoto. Usare isset() per verificare se una variabile è impostata.

Vedere la sezione Arrays nel manuale per una spiegazione dettagliata di come gli array siano implementati ed usati in PHP.

Esempio 1. esempio di count()

<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
$risultato = count($a);
//$risultato == 3

$b[0]  = 7;
$b[5]  = 9;
$b[10] = 11;
$risultato = count($b);
// $risultato == 3;
?>

Esempio 2. esempio di count() ricorsiva (PHP >= 4.2.0)

<?php
$cibo = array('frutta' => array('arancia', 'banana', 'mela'),
              'verdura' => array('carota', 'zucchina', 'piselli'));

// conteggio ricorsivo
echo count($cibp,COUNT_RECURSIVE); // output 8

// conteggio normale
echo count($cibo);                 // output 2

?>

Nota: La funzione sizeof() è un alias per count().

Vedere anche is_array(), isset() e strlen().

current

(PHP 3, PHP 4 , PHP 5)

current -- Restituisce l'elemento corrente di un array

Descrizione

mixed current ( array array)

Ogni array ha un puntatore interno all'elemento "corrente", che è inizializzato al primo elemento inserito nell'array.

La funzione current() restituisce il valore dell'elemento che è attualmente puntato dal puntatore interno. In ogni caso non muove il puntatore. Se il puntatore interno punta oltre la fine della lista di elementi, current() restituisce FALSE.

Avvertimento

Se l'array contiene elementi vuoti (0 o "", la stringa vuota) la funzione restituirà FALSE pure per questi elementi. Questo rende impossibile stabilire se si è veramente alla fine della lista in un array di questo tipo usando current(). Per attraversare in modo corretto un array che può contenere elementi vuoti, usare la funzione each().

Esempio 1. Esempio di current() e funzioni relative

<?php
$trasporti = array('piedi', 'bicicletta', 'automobile', 'aereo');
$mode = current($trasporti); // $mode = 'piedi';
$mode = next($trasporti);    // $mode = 'bicicletta';
$mode = current($trasporti); // $mode = 'bicicletta';
$mode = prev($trasporti);    // $mode = 'piedi';
$mode = end($trasporti);     // $mode = 'aereo';
$mode = current($trasporti); // $mode = 'aereo';
?>

Vedere anche end(), key(), next(), prev() e reset().

each

(PHP 3, PHP 4 , PHP 5)

each --  Restituisce la corrente coppia chiave/valore di un array e incrementa il puntatore dell'array

Descrizione

array each ( array array)

Restituisce la corrente coppia chiave/valore corrente di array e incrementa il puntatore interno dell'array. Questa coppia è restituita in un array di quattro elementi, con le chiavi 0, 1, key, and value. Gli elementi 0 e key contengono il nome della chiave dell'elemento dell'array, mentre 1 e value contengono i dati.

Se il puntatore interno dell'array punta oltre la fine dei contenuti dell'array, each() restituisce FALSE.

Esempio 1. esempi dieach()

<?php
$foo = array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);
?>

$bar ora contiene la seguente coppia chiave/valore:

Array
(
    [1] => bob
    [value] => bob
    [0] => 0
    [key] => 0
)

<?php
$foo = array("Robert" => "Bob", "Seppo" => "Sepi");
$bar = each($foo);
print_r($bar);
?>

$bar ora contiene la seguente coppia chiave/valore:

Array
(
    [1] => Bob
    [value] => Bob
    [0] => Robert
    [key] => Robert
)

each() viene normalmente usata in congiunzione con list() nell'attraversamento di un array; ecco un esempio:

Esempio 2. Attraversamento di un array con each()

<?php
$frutta = array('a' => 'albicocca', 'b' => 'banana', 'c' => 'ciliegia');

reset($frutta);
while (list($chiave, $valore) = each($frutta)) {
    echo "$chiave => $valore\n";
}
?>

Outputs:

a => albicocca
b => banana
c => ciliegia

Dopo l'esecuzione di each(), il puntatore dell'array viene lasciato sull'elemento successivo, o sull'ultimo elemento se si è alla fine dell'array. Si deve utilizzare reset() se si vuole riattraversare l'array usando each().

Attenzione

Poiché assegnare un array ad un'altra variabile reimposta il puntatore, il nostro esempio diventerebbe un loop infinito se assegnassimo $frutta ad un'altra variabile all'interno del ciclo.

Vedere anche key(), list(), current(), reset(), next(), prev() e foreach.

end

(PHP 3, PHP 4 , PHP 5)

end --  Sposta il puntatore interno dell'array all'ultimo elemento

Descrizione

mixed end ( array array)

end() fa avanzare il puntatore di array all'ultimo elemento, e restituisce il suo valore.

Esempio 1. Un semplice esempio di end()

<?php

$frutti = array('mela', 'banana', 'mirtillo');
echo end($frutti); // mirtillo
      
?>

Vedere anche current(), each(), prev(), next() e reset().

extract

(PHP 3>= 3.0.7, PHP 4 , PHP 5)

extract --  Importa le variabili nella tabella dei simboli

Descrizione

int extract ( array var_array [, int extract_type [, string prefix]])

Questa funzione viene usata per importare delle variabili da un array nella tabella dei simbloi corrente. Riceve un array associativo var_array e interpreta le chiavi come nomi di variabile e i valori come valori di variabile. Per ogni coppia chiave/valore verrà creata una variabile nella tabella dei simboli corrente, coerentemente con i parametri extract_type e prefix.

Nota: Dalla versione 4.0.5 questa funzione restituisce il numero di variabili estratte.

Nota: EXTR_IF_EXISTS e EXTR_PREFIX_IF_EXISTS sono stati introdotti nella versione 4.2.0.

Nota: EXTR_REFS è stata introdotta nella versione 4.3.0.

extract() controlla ogni chiave per stabilire se costituisce un nome valido di variabile e se ci sono collisioni con variabili già esistenti nella tabella dei simboli. Il modo in cui vengono trattate le chiavi invalide/numeriche e le collisioni è determinato da extract_type. Può essere uno dei seguenti valori:

EXTR_OVERWRITE

Se avviene una collisione, sovrascrive la variabile esistente.

EXTR_SKIP

Se avviene una collisione, non sovrascrive la variabile esistente.

EXTR_PREFIX_SAME

Se avviene una collisione, mette come prefisso al nome della variabile il parametro prefix.

EXTR_PREFIX_ALL

Mette come prefisso di tutte le variabili il parametro prefix. Dal PHP 4.0.5 questo avviene anche per i valori numerici.

EXTR_PREFIX_INVALID

Mette come prefisso, solo per i nomi di variabili invalidi/numerici, il parametro prefix. Questa opzione è stata aggiunta in PHP 4.0.5.

EXTR_IF_EXISTS

Sovrascrive la variabile solo se già esiste nella tabella dei simboli, altrimenti non fa nulla. Questo è utile per definire una lista di variabili valide e quindi estrarre solo quelle variabili definite in $_REQUEST, per esempio. Questa opzione è stata aggiunta in PHP 4.2.0.

EXTR_PREFIX_IF_EXISTS

Crea nomi di variabili con il prefisso solo se la versione senza prefisso della stessa variable esiste nella tabella dei simboli. Questa opzione è stata aggiunta in PHP 4.2.0.

EXTR_REFS

Estrae le variabili come riferimenti. Questo in effetti significa che i valori delle variabili importate referenziano i valori del parametro var_array. Si può usare questo flag da solo o combinarlo con gli altri mediante un OR nel parametro extract_type. Questo flag è stato aggiunto nel PHP 4.3.0.

Se extract_type non è specificato, si assume che sia EXTR_OVERWRITE.

Si noti che prefix è richiesto solo se extract_type è EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID o EXTR_PREFIX_IF_EXISTS. Se il risultato non è un nome di variabile valido, non viene importato nella tabella dei simboli.

extract() restituisce il numero di variabili importate con successo nella tabella dei simboli.

Avvertimento

Non utilizzare extract() su dati non convalidati, come gli input degli utenti ($_GET, ...). Se lo si deve fare, ad esempio per eseguire temporaneamente vecchio codice basato su register_globals, sincerarsi di utilizzare uno dei valori di extract_type come EXTR_SKIP e ricordarsi che occorre estrarre $_SERVER, $_SESSION, $_COOKIE, $_POST e $_GET in questo ordine.

Un possibile uso di extract() è quello di importare nella tabella dei simboli variabili contenute in un array associativo restituito da wddx_deserialize().

Esempio 1. esempio diextract()

<?php

/* Si supponga che $array_variabili sia un array restituito da
   wddx_deserialize */

$dimensione = "grande";
$array_variabili = array("colore" => "blu",
                         "dimensione"  => "media",
                         "forma" => "sfera");
extract($array_variabili, EXTR_PREFIX_SAME, "wddx");

echo "$colore, $dimensione, $forma, $wddx_dimensione\n";

?>

L'esempio mostrerà:

blu, grande, sfera, media

La variabile $dimensione non è stata sovrascritta, in quanto è specificato EXTR_PREFIX_SAME, che ha portato alla creazione di $wddx_dimensione. Se fosse stato specificato EXTR_SKIP, $wddx_dimensione non sarebbe stata creata. EXTR_OVERWRITE avrebbe portato $dimensione ad assumere il valore "medio", e EXTR_PREFIX_ALL avrebbe fatto creare nuove variabili chiamate $wddx_colore, $wddx_dimensione e $wddx_forma.

Si deve usare un array associativo, un array indicizzato numericamente non produce risultati a meno di non usare EXTR_PREFIX_ALL o EXTR_PREFIX_INVALID.

Vedere anche compact().

in_array

(PHP 4 , PHP 5)

in_array -- Controlla se un valore è presente in un array

Descrizione

bool in_array ( mixed ago, array pagliaio [, bool strict])

Cerca in pagliaio per trovare ago e restituisce TRUE se viene trovato nell'array, FALSE altrimenti.

Se il terzo parametro strict è TRUE la funzione in_array() controllerà anche il tipo di ago nell'array haystack.

Nota: Se ago è una stringa, il confronto è effettuato tenendo conto delle maiuscole/minuscole.

Nota: Nelle versioni di PHP precedenti la 4.2.0. ago non poteva essere un array.

Esempio 1. esempio di in_array()

<?
$os = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $os)) {
    echo "Trovato Irix";
}
if (in_array("mac", $os)) {
    echo "Trovato mac";
}
?>

La seconda condizione fallisce perché in_array() tiene conto di maiuscole e minuscole, quindi il programma mostrerà:

Trovato Irix

Esempio 2. esempio di in_array() con strict

<?php
$a = array('1.10', 12.4, 1.13);

if (in_array('12.4', $a, true)) {
    echo "'12.4' trovato con controllo strict\n"
}

if (in_array(1.13, $a, true)) {
    echo "1.13 trovato con controllo strict\n"
}
?>

Questo mostrerà:

1.13 trovato con controllo strict

Esempio 3. in_array() con un array come ago

<?php
$a = array(array('p', 'h'), array('p', 'r'), 'o');

if (in_array(array('p', 'h'), $a)) {
    echo "'ph' trovato\n";
}

if (in_array(array('f', 'i'), $a)) {
    echo "'fi' non trovato\n";
}

if (in_array('o', $a)) {
    echo "'o' trovato\n";
}
?>

Questo ritornerà:

'ph' trovato
  'o' trovato

Vedere anche array_search(), array_key_exists() e isset().

key

(PHP 3, PHP 4 , PHP 5)

key -- Estrae la chiave corrente da un array associativo

Descrizione

mixed key ( array array)

key() restituisce la chiave corrispondente all'attuale posizione del puntatore interno all'array.

Esempio 1. esempio di key()

<?php
$array = array(
    'frutto1' => 'mela',
    'frutto2' => 'arancia',
    'frutto3' => 'uva',
    'frutto4' => 'mela',
    'frutto5' => 'mela');

// questo ciclo mostra tutte le chiavi
// dell'array associativo che sono uguali a 'mela'
while ($nome_frutto = current($array)( {
    if ($nome_frutto == 'mela') {
        echo key($array).'<br />';
    }
    next($array);
}
?>

Vedere anche current() e next().

krsort

(PHP 3>= 3.0.13, PHP 4 , PHP 5)

krsort -- Ordina rispetto alle chiavi di un array in ordine inverso

Descrizione

bool krsort ( array array [, int sort_flags])

Ordina un array rispetto alle sue chiavi, in ordine inverso, mantenendo le associazioni. Questa funzione è utile con gli array associativi.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. Esempio di krsort()

<?php
$frutti = array("d"=>"limone", "a"=>"arancio", "b"=>"banana", "c"=>"mela");
krsort($frutti);
reset($frutti);
while (list($chiave, $valore) = each($frutti)) {
    echo "$chiave = $valore\n";
}
?>

Questo esempio mostrerà:

d = limone
c = mela
b = banana
a = arancio

Si può modificare il comportamento dell'ordinamento usando il parametro opzionale sort_flags, per ulteriori dettagli vedere sort().

Vedere anche asort(), arsort(), ksort(), sort(), natsort() e rsort().

ksort

(PHP 3, PHP 4 , PHP 5)

ksort -- Ordina rispetto alle chiavi di un array

Descrizione

bool ksort ( array array [, int sort_flags])

Ordina un array rispetto alle sue chiavi, mantenendo le associazioni. Questa funzione è utile con gli array associativi.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di ksort()

<?php
$frutti = array("d"=>"limone", "a"=>"arancia", "b"=>"banana", "c"=>"mela");
ksort($frutti);
reset($frutti);
while (list($chiave, $valore) = each($frutti)) {
    echo "$chiave = $valore\n";
}
?>

Questo esempio mostrerà:

a = arancia
b = banana
c = mela
d = limone

Si può modificare il comportamento dell'ordinamento usando il parametro opzionale sort_flags, per ulteriori dettagli vedere sort().

Vedere anche asort(), arsort(), krsort(), uksort(), sort(), natsort() e rsort().

Nota: Il secondo parametro è stato aggiunto in PHP 4.

list

(PHP 3, PHP 4, PHP 5 )

list --  Assegna valori a delle variabili come se fossero un array

Descrizione

void list ( mixed ...)

Come array(), questa non è in realtà una funzione, bensì un costrutto del linguaggio. list() è usata per assegnare valori ad una lista di variabili in una sola operazione.

Nota: list() funziona solo su array numerici e si aspetta che gli indici numerici partano da 0.

Esempio 1. esempio di list()

<?php

$info = array('caffè', 'scuro', 'caffeina');

// assegna a tutte le variabili
list($bevanda, $colore, $componente) = $info;
echo "Il $bevanda è $colore e la $componente lo rende speciale.\n";

// assegna solo in parte
list($bevanda, , $componente) = $info;
echo "Il $bevanda ha la $componente.\n";

// oppure assegnamo solo l'ultima variabile
list( , , $componente) = $info;
echo"Ho voglia di $bevanda!\n";

?>

Esempio 2. Esempio di uso di list()

<table>
 <tr>
  <th>Nome dell'impiegato</th>
  <th>Stipendio</th>
 </tr>

<?php

$risultato = mysql_query("SELECT id, nome, stipendio FROM impiegati", $conn);
while (list($id, $nome, $stipendio) = mysql_fetch_row ($risultato)) {
    echo (" <tr>\n".
          "  <td><a href=\"info.php?id=$id\">$nome</a></td>\n".
          "  <td>$stipendio</td>\n".
          " </tr>\n");
}

?>

</table>

Avvertimento

list() assegna i valori cominciando dal parametro più a destra. Se si stanno usando variabili semplici, non ci si deve preoccupare di questo fatto. Ma se si stanno usando array con indici di solito ci si aspetta che l'ordine degli indici negli array sia quello scritto negli argomenti della funzione list(), da sinistra a destra; non è così. L'ordine è invertito.

Esempio 3. Utilizzo di list() con gli indici

<?php

$info = array('caffè', 'nero', 'caffeina');

list($a[0], $a[1], $a[2]) = $info;

var_dump($a);

?>

Restituisce il segente risultato (si noti l'ordine degli elementi rispetto all'ordine con cui sono stati scritti nella sintassi di list()).

array(3) {
  [2]=>
  string(8) "caffeina"
  [1]=>
  string(4) "nero"
  [0]=>
  string(5) "caffè"
}

Vedere anche each() e array() e extract().

natcasesort

(PHP 4 , PHP 5)

natcasesort --  Ordina un array usando un algoritmo di "ordine naturale" non sensibile alle maiuscole/minuscole

Descrizione

void natcasesort ( array array)

Questa funziona implementa un algoritmo di ordinamento che ordina le stringhe alfanumeriche come lo farebbe un essere umano, mantenendo le associazioni chiavi/valori. Questo è chiamato "ordine naturale".

natcasesort() è una versione, non sensibile alle maiuscole/minuscole, di natsort().

Esempio 1. esempio di natcasesort()

<?php
$array1 = $array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');

sort($array1);
echo "Ordinamento standard\n";
print_r($array1);

natcasesort($array2);
echo "\nOrdinamento naturale (con maiuscole non significative)\n";
print_r($array2);
?>

Questo codice genererà il seguente risultato:

Ordinamento standard
Array
(
    [0] => IMG0.png
    [1] => IMG3.png
    [2] => img1.png
    [3] => img10.png
    [4] => img12.png
    [5] => img2.png
)

Ordinamento naturale (con maiuscole non significative)
Array
(
    [0] => IMG0.png
    [4] => img1.png
    [3] => img2.png
    [5] => IMG3.png
    [2] => img10.png
    [1] => img12.png
)

Per maggiori informazioni vedere la pagina di Martin Pool Natural Order String Comparison .

Vedere anche sort(), natsort(), strnatcmp() e strnatcasecmp().

natsort

(PHP 4 , PHP 5)

natsort --  Ordina un array usando un algoritmo di "ordine naturale"

Descrizione

void natsort ( array array)

Questa funzione implementa un algoritmo di ordinamento che ordina le stringhe alfanumeriche come lo farebbe un essere umano, mantenendo l'associazione chiavi/valori. Questo è chiamato "ordine naturale". Un esempio della differenza tra questo algoritmo e quello normalmente usato dai computer (usato in sort()) è dato qui sotto:

Esempio 1. esempio di natsort()

<?php
$array1 = $array2 = array("img12.png", "img10.png", "img2.png", "img1.png");

sort($array1);
echo "Ordinamento standard\n";
print_r($array1);

natsort($array2);
echo "\nOrdinamento naturale\n";
print_r($array2);
?>

Questo codice genererà il seguente risultato:

Ordinamento standard
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Ordinamento naturale
Array
(
    [3] => img1.png
    [2] => img2.png
    [1] => img10.png
    [0] => img12.png
)

Per ulteriori informazioni vedere la pagina di Martin Pool Natural Order String Comparison .

Vedere anche natcasesort(), strnatcmp() e strnatcasecmp().

next

(PHP 3, PHP 4 , PHP 5)

next --  Incrementa il puntatore interno dell'array

Descrizione

mixed next ( array array)

Restituisce l'elemento dell'array che sta nella posizione successiva a quella attuale indicata dal puntatore interno, oppure FALSE se non ci sono altri elementi.

next() si comporta come current(), con una differenza. Incrementa il puntatore interno dell'array di una posizione, prima di restituire il valore dell'elemento. Ciò significa che restituisce l'elemento successivo e incrementa il puntatore di una posizione. Se l'incremento fa sì che il puntatore vada oltre la fine della lista di elementi, next() restituisce FALSE.

Avvertimento

Se l'array contiene elementi vuoti, o elementi che hanno il valore chiave uguale a 0 allora questa funzione restituisce FALSE anche per questi elementi. Per esplorare correttamente un array che può contenere elementi vuoti o con chiave uguale a 0 vedere la funzione each().

Esempio 1. Esempio di next() e funzioni relative

<?php
$trasporti = array('piedi', 'bicicletta', 'automobile', 'aereo');
$mode = current($trasporti); // $mode = 'piedi';
$mode = next($trasporti);    // $mode = 'bicicletta';
$mode = next($trasporti);    // $mode = 'automobile';
$mode = prev($trasporti);    // $mode = 'piedi';
$mode = end($trasporti);     // $mode = 'aereo';
?>

Vedere anche current(), end(), prev() e reset().

pos

pos -- Restituisce l'elemento corrente di un array

Descrizione

Questo è un alias di current().

prev

(PHP 3, PHP 4 , PHP 5)

prev -- Decrementa il puntatore interno dell'array

Descrizione

mixed prev ( array array)

Restituisce l'elemento dell'array che sta nella posizione precedente a quella attuale indicata dal puntatore interno, oppure FALSE se non ci sono altri elementi.

Avvertimento

Se l'array contiene degli elementi vuoti la funzione restituirà FALSE per questi valori. Per esplorare correttamente un array che può contenere elementi vuoti vedere la funzione each().

prev() si comporta come next(), tranne per il fatto di decrementare il puntatore interno di una posizione, invece che incrementarlo.

Esempio 1. Esempio di prev() e funzioni relative

<?php
$trasporti = array('piedi', 'bicicletta', 'automobile', 'aereo');
$mode = current($trasporti); // $mode = 'piedi';
$mode = next($trasporti);    // $mode = 'bicicletta';
$mode = next($trasporti);    // $mode = 'automobile';
$mode = prev($trasporti);    // $mode = 'piedi';
$mode = end($trasporti);     // $mode = 'aereo';
?>

Vedere anche current(), end(), next() e reset().

range

(PHP 3>= 3.0.8, PHP 4 , PHP 5)

range --  Crea un array contenente una serie di elementi

Descrizione

array range ( int min, int max [, int step])

range() restituisce una serie di elementi da min a max, inclusiva. Se min > max, la sequenza sarà decrescente.

Nuovo parametro: Il parametro opzionale step è stato aggiunto nel PHP 5.0.0.

Se il valore step è specificato, verrà utilizzato come incremento tra gli elementi della sequenza. step deve essere un numero positivo. Se non specificato, il valore predefinito per step è 1.

Esempio 1. esempi di range()

<?php
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
foreach (range(0, 12) as $numero) {
    echo $numero;
}

// Il parametro step è stato introdotto nel PHP 5.0.0
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
foreach (range(0, 100, 10) as $numero) {
    echo $numero;
}

// L'utilizzo dei caratteri è stato aggiunto nel PHP 4.1.0
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
foreach (range('a', 'i') as $lettera) {
    echo $lettera;
}
// array('c', 'b', 'a');
foreach (range('c', 'a') as $lettera) {
    echo $lettera;
}
?>

Nota: Prima della versione 4.1.0 la funzione range() generava solo array crescenti di interi. Il supporto per le sequenze di caratteri e array decrescenti è stata aggiunta nella 4.1.0. I valori delle sequenze di caratteri sono limitati alla lunghezza di 1 carattere. Se viene inserito un valore con una lunghezza maggiore, viene utilizzato solo il primo carattere.

Attenzione

Nel PHP dalla versione 4.1.0 alla 4.3.2, range() vede le stringhe numeriche come stringhe e non come interi. Quindi, verranno utilizzate come sequenze di caratteri. Per esempio, "4242" viene trattato come "4".

Vedere shuffle(), array_fill() e foreach.

reset

(PHP 3, PHP 4 , PHP 5)

reset --  Reimposta il puntatore interno di un array sulla posizione iniziale

Descrizione

mixed reset ( array array)

reset() riporta il puntatore di array sul primo elemento e ne restituisce il valore.

Esempio 1. esempio di reset()

<?php

$array = array('passo uno', 'passo due', 'passo tre', 'passo quattro');
  
// di default, il puntatore è sul primo elemento  
echo current($array) . "<br />\n"; // "passo uno"

// salta due passi    
next($array);                                 
next($array);
echo current($array) . "<br />\n"; // "passo tre"
  
// reset del puntatore, ricomincia dal passo uno
reset($array);
echo current($array) . "<br />\n"; // "passo uno"
  
?>

Vedere anche current(), each(), next(), e prev().

rsort

(PHP 3, PHP 4 , PHP 5)

rsort -- Ordina un array in ordine decrescente

Descrizione

bool rsort ( array array [, int sort_flags])

Questa funzione ordina un array in ordine decrescente.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di rsort()

<?php
$frutti = array("limone", "arancia", "banana", "mela");
rsort($frutti);
reset($frutti);
while (list($chiave, $valore) = each($frutti)) {
    echo "$chiave = $valore\n";
}
?>

Questo esempio mostrerà:

0 = mela
1 = limone
2 = banana
3 = arancia

I frutti sono stati ordinati in ordine alfabetico decrescente.

Si può modificare il comportamento dell'ordinamento usando il parametro opzionale sort_flags, per maggiori dettagli vedere sort().

Vedere anche arsort(), asort(), ksort(), sort() e usort().

shuffle

(PHP 3>= 3.0.8, PHP 4 , PHP 5)

shuffle -- Mescola un array

Descrizione

void shuffle ( array array)

Questa funzione mescola un array (rende casuale l'ordine degli elementi).

Esempio 1. esempio di shuffle()

<?php
$numeri = range(1, 20);
srand((float)microtime() * 1000000);
shuffle($numeri);
while (list(, $numero) = each($numeri)) {
    echo "$numero ";
}
?>

Nota: Come in PHP 4.2.0, non vi è necessità di inizializzare il generatore di numeri casuali con srand() oppure con mt_srand() poichè viene eseguito in modo automatico.

Vedere anche arsort(), asort(), ksort(), rsort(), sort() e usort().

sizeof

sizeof -- Alias di count()

Descrizione

La funzione è un alias di count().

sort

(PHP 3, PHP 4 , PHP 5)

sort -- Ordina un array

Descrizione

bool sort ( array array [, int sort_flags])

Questa funzione ordina un array. Gli elementi vengono disposti dal più piccolo al più grande.

Nota: Questa funzione assegna nuove chiavi agli elementi di array. Quindi non si limita a riordinare le chiavi, ma rimuove tutte le chiavi che siano state assegnate.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di sort()

<?php

$frutti = array("limone", "arancia", "banana", "mela");
sort($frutti);
reset($frutti);
while (list($chiave, $valore) = each($frutti)) {
    echo "frutti[" . $chiave . "] = " . $valore . "\n";
}

?>

Questo esempio mostrerà:

frutti[0] = arancia
frutti[1] = banana
frutti[2] = limone
frutti[3] = mela

I frutti sono stati ordinati in ordine alfabetico.

Il secondo parametro opzionale sort_flags può essere usato per modificare il comportamento dell'ordinamento, usando i seguenti valori:

flag d'ordinamento:

  • SORT_REGULAR - compara gli elementi in modo normale

  • SORT_NUMERIC - compara gli elementi numericamente

  • SORT_STRING - compara gli elementi convertiti in stringa

Nota: Il secondo parametro è stato aggiunto in PHP 4.

Vedere anche arsort(), asort(), ksort(), natsort(), natcasesort(), rsort(), usort(), array_multisort() e uksort().

uasort

(PHP 3>= 3.0.4, PHP 4 , PHP 5)

uasort --  Ordina un array mediante una funzione definita dall'utente e mantiene le associazioni

Descrizione

bool uasort ( array array, callback cmp_function)

Questa funzione ordina un array in modo tale che le chiavi mantengano la loro correlazione con gli elementi dell'array a cui sono associate. Questo è utile quando si ordinano array associativi in cui l'ordine degli elementi è importante. La funzione di comparazione deve essere fornita dall'utente.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Nota: Vedere usort() e uksort() per esempio di funzioni di comparazione.

Vedere anche usort(), uksort(), sort(), asort(), arsort(), ksort() e rsort().

uksort

(PHP 3>= 3.0.4, PHP 4 , PHP 5)

uksort --  Ordina rispetto alle chiavi di un array mediante una funzione definita dall'utente

Descrizione

bool uksort ( array array, callback cmp_function)

uksort() ordina rispetto alle chiavi di un array mediante una funzione di comparazione definita dall'utente. Se si vuole ordinare un array con dei criteri non usuali, si deve usare questa funzione.

La funzione cmp_function deve accettare due parametri che saranno valorizzati con coppie di chiavi di array. La funzione di confronto deve restituire un intero minore, uguale o maggiore di zero se il primo argomento è considerato minore, uguale o maggiore del secondo.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di uksort()

<?php
function cmp($a, $b) 
{
    if ($a == $b) {
        return 0;
    }
    return ($a > $b) ? -1 : 1;
}

$a = array(4 => "quattro", 3 => "tre", 20 => "venti", 10 => "dieci");

uksort($a, "cmp");

while (list($chiave, $valore) = each($a)) {
    echo "$chiave: $valore\n";
}
?>

Questo esempio mostrerà:

20: venti
10: dieci
4: quattro
3: tre

Vedere anche usort(), uasort(), sort(), asort(), arsort(), ksort(), natsort() e rsort().

usort

(PHP 3>= 3.0.3, PHP 4 , PHP 5)

usort --  Ordina un array mediante una funzione definita dall'utente

Descrizione

bool usort ( array array, callback cmp_function)

Ordina i valori di un array mediante una funzione di comparazione definita dall'utente. Se si vuole ordinare un array con dei criteri non usuali, si deve usare questa funzione.

La funzione di comparazione deve restituire un intero minore, uguale o superiore a zero se il primo elemento è da considerarsi rispettivamente minore, uguale o maggiore del secondo.

Nota: Se due parametri vengono valutati come uguali, il loro ordinamento nell'array ordinato è indefinito. Fino al PHP 4.0.6 le funzioni definite dall'utente mantenevano l'ordine originario per questi elementi, ma con il nuovo algoritmo di ordinamento introdotto con la versione 4.1.0 questo non succede più dal momento che non c'è un modo per ottenerlo in maniera efficiente.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di usort()

<?php
function cmp($a, $b) 
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

while (list($chiave, $valore) = each($a)) {
    echo "$chiave: $valore\n";
}
?>

Questo esempio mostrerà:

0: 1
1: 2
2: 3
3: 5
4: 6

Nota: Ovviamente, in questo caso banale di ordinamento decrescente la funzione sort() sarebbe stata più appropriata.

Esempio 2. esempio di usort() con un array multidimensionale

<?php
function cmp($a, $b) 
{
    return strcmp($a["frutto"], $b["frutto"]);
}

$frutti[0]["frutto"] = "limoni";
$frutti[1]["frutto"] = "arance";
$frutti[2]["frutto"] = "uva";

usort($frutti, "cmp");

while (list($chiave, $valore) = each($frutti)) {
    echo "\$frutti[$chiave]: " . $valore["frutto"] . "\n";
}
?>

Quando si ordina un array multidimensionale, $a e $b contengono riferimenti al primo indice dell'array.

Questo esempio mostrerà:

$frutti[0]: arance
$frutti[1]: limoni
$frutti[2]: uva

Esempio 3. esempio di usort() usando una funzione membro di un oggetto

<?php
class OggettoTest {
    var $nome;

    function OggettoTest($nome) 
    {
        $this->nome = $nome;
    }

    /* Questa è la funzione statica di comparazione: */
    function comp_ogg($a, $b) 
    {
        $al = strtolower($a->nome);
        $bl = strtolower($b->nome);
        if ($al == $bl) {
            return 0;
        }
        return ($al > $bl) ? +1 : -1;
    }
}

$a[] = new OggettoTest("c");
$a[] = new OggettoTest("b");
$a[] = new OggettoTest("d");

usort($a, array("OggettoTest", "comp_ogg"));

foreach ($a as $voce) {
    echo $voce->nome."\n";
}
?>

Questo esempio mostrerà:

b
c
d

Vedere anche uasort(), uksort(), sort(), asort(), arsort(),ksort(), natsort() e rsort().

III. Funzioni Aspell [deprecated]

Introduzione

Le funzioni aspell() permettono di controllare la correttezza di una parola e di offrire suggerimenti.

Nota: Questa estensione è stata rimossa da PHP e non è più disponibile dal PHP 4.3.0. Se si desidera utilizzare le funzioni di correzione ortografica in PHP, utilizzare pspell, che utilizza la libreria pspell e funziona anche con le nuove versioni di aspell.


Requisiti

aspell funziona solo con versioni molto vecchie (più o meno fino alla .27.*) della libreria aspell. Né il presente modulo, né quelle versioni della libreria sono più supportate. Necessita della libreria aspell, disponibile da: http://aspell.sourceforge.net/.


Installazione

In PHP 4, these functions are only available if PHP was configured with --with-aspell=[DIR].


Vedere anche

Vedere anche pspell.

Sommario
aspell_check_raw --  Controlla una parola senza togliere le maiuscole o cercare di eliminare gli spazi inutili [deprecated]
aspell_check -- Controlla una parola [deprecated]
aspell_new -- Carca un nuovo dizionario [deprecated]
aspell_suggest -- Suggerisce correzioni di una parola [deprecated]

aspell_check_raw

(PHP 3>= 3.0.7, PHP 4 <= 4.2.3)

aspell_check_raw --  Controlla una parola senza togliere le maiuscole o cercare di eliminare gli spazi inutili [deprecated]

Descrizione

bool aspell_check_raw ( int link_dizionario, string parola)

aspell_check_raw() controlla la correttezza di una parola, senza modificare le maiuscole/minusciole o cercare di eliminare gli spazi inutili e restituisce TRUE se è corretta, FALSE altrimenti.

Esempio 1. aspell_check_raw()

<?php

$aspell_link = aspell_new("italiano");

if (aspell_check_raw($aspell_link, "prova")) {
    echo "La parola &grave; corretta";
} else {
    echo "Spiacente, parola non corretta";
}

?>

aspell_check

(PHP 3>= 3.0.7, PHP 4 <= 4.2.3)

aspell_check -- Controlla una parola [deprecated]

Descrizione

bool aspell_check ( int link_dizionario, string parola)

aspell_check() controlla la compitazione di una parola e restituisce TRUE se è corretta, FALSE altrimenti.

Esempio 1. aspell_check()

<?php

$aspell_link = aspell_new("italiano");

if (aspell_check($aspell_link, "provva")) {
    echo "La parola &egrave; corretta";
} else {
    echo "Spiacente, parola non corretta";
}

?>

aspell_new

(PHP 3>= 3.0.7, PHP 4 <= 4.2.3)

aspell_new -- Carca un nuovo dizionario [deprecated]

Descrizione

int aspell_new ( string master [, string personal])

aspell_new() apre un nuovo dizionario e restituisce un puntatore (link) identificatore del dizionario, da utilizzare in altre funzioni aspell. Restituisce FALSE in caso di errore.

Esempio 1. aspell_new()

<?
$aspell_link = aspell_new("italiano");
?>

aspell_suggest

(PHP 3>= 3.0.7, PHP 4 <= 4.2.3)

aspell_suggest -- Suggerisce correzioni di una parola [deprecated]

Descrizione

array aspell_suggest ( int link_dizionario, string parola)

aspell_suggest() restituisce un array di possibili correzioni per la parola data.

Esempio 1. aspell_suggest()

<?php

$aspell_link = aspell_new("italiano");

if (!aspell_check($aspell_link, "prova")) {
    $suggerimenti = aspell_suggest($aspell_link, "prova");

    foreach ($suggerimenti as $suggerimento) {
        echo "Possibile parola corretta: $suggerimento<br>\n"; 
    }
}

?>

IV. Funzioni Matematiche BCMath a precisione arbitraria

Introduzione

Per la matematica a precisione arbitraria PHP offre il Binary Calculator che supporta numeri di qualsiasi dimensione e precisione, rappresentati da stringhe;


Requisiti

Dalla versione 4.0.4 del PHP, libbcmath è inclusa nella distribuzione. Non c'è bisogno di altre librerie esterne per questa estensione.


Installazione

Nel PHP 4, queste funzioni sono disponibili solo se PHP è stato configurato con --enable-bcmath. Nel PHP 3, queste funzioni sono disponibili solo se PHP NON è stato configurato con --disable-bcmath.

La versione per Windows di PHP ha già compilato il supporto per questo modulo. Non occorre caricare alcun modulo addizionale per potere utilizzare queste funzioni.


Configurazione di Runtime

Il comportamento di queste funzioni è influenzato dalle impostazioni di php.ini.

Tabella 1. Opzioni di configurazione di BC math

NomeDefaultModificabile in
bcmath.scale0PHP_INI_ALL
Per ulteriori dettagli e definizioni delle costanti PHP_INI_* vedere ini_set().

Breve descrizione dei parametri di configurazione.

bcmath.scale integer

Numero di cifre decimali per tutte le funzioni bcmath. Vedere anche bcscale().


Tipi di risorse

Questa estensione non definisce alcun tipo di risorsa.


Costanti predefinite

Questa estensione non definisce alcuna costante.

Sommario
bcadd -- Somma due numeri a precisione arbitraria
bccomp -- Confronta due numeri a precisione arbitraria
bcdiv -- Divide due numeri a precisione arbitraria
bcmod --  Ricava il modulo di un numero a precisione arbitraria
bcmul -- Moltiplica due numeri a precisione arbitraria
bcpow --  Effettua l'elevamento a potenza
bcpowmod --  Effettua l'elevamento a potenza, applicando quindi il modulo.
bcscale --  Imposta il valore di precisione di default per tutte le funzioni matematich BCMath
bcsqrt --  Ottiene la radice quadrata di un numero a precisione arbitraria
bcsub --  Sottrae un numero a precisione arbitraria da un altro

bcadd

(PHP 3, PHP 4 , PHP 5)

bcadd -- Somma due numeri a precisione arbitraria

Descrizione

string bcadd ( string primo operando, string secondo operando [, int precisione])

Somma il primo operando con il secondo operando e restituisce la somma sotto forma di stringa. Il parametro opzionale precisione è utilizzato per impostare il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. Esempio di bcadd()

<?php

$a = 1.234;
$b = 5;

echo bcadd($a, $b);     // 6
echo bcadd($a, $b, 4);  // 6.2340

?>

Vedere anche bcsub().

bccomp

(PHP 3, PHP 4 , PHP 5)

bccomp -- Confronta due numeri a precisione arbitraria

Descrizione

int bccomp ( string primo_operando, string secondo_operando [, int precisione])

Confronta il primo_operando e il secondo_operando e restituisce il risultato sotto forma di intero. Il parametro opzionale precisione è utilizzato per impostare il numero di cifre dopo il punto decimale che verranno usate nel confronto. Il valore restituito è 0 se i due operandi sono uguali. Se il primo_operando è più grande del secondo_operando il valore restituito è +1 e se il primo_operando è minore del secondo_operando il valore restituito è -1.

Esempio 1. esempio di bccomp()

<?php
echo bccomp('1', '2') . "\n";

echo bccomp('1.00001', '1', 3) . "\n";
echo bccomp('1.00001', '1', 5);
?>

Questo mostrerà:

-1
0
1

bcdiv

(PHP 3, PHP 4 , PHP 5)

bcdiv -- Divide due numeri a precisione arbitraria

Descrizione

string bcdiv ( string primo operando, string secondo operando [, int precisione])

Divide il primo operando per il secondo operando e restituisce il risultato. Il parametro opzionale precisione imposta il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. esempio di bcdiv()

<?php

echo bcdiv(105, 6.55957, 3);  // 16.007

?>

Vedere anche bcmul().

bcmod

(PHP 3, PHP 4 , PHP 5)

bcmod --  Ricava il modulo di un numero a precisione arbitraria

Descrizione

string bcmod ( string operando, string modulo)

Ricava il modulo di operando usando modulo.

Esempio 1. esempio di bcmod()

<?php
echo bcmod(4, 2) . "\n";
echo bcmod(2, 4);
?>

L'esempio mostrerà:

0
2

Vedere anche bcdiv().

bcmul

(PHP 3, PHP 4 , PHP 5)

bcmul -- Moltiplica due numeri a precisione arbitraria

Descrizione

string bcmul ( string primo operando, string secondo operando [, int precisione])

Moltiplica il primo operando per il secondo operando e restituisce il risultato. Il parametro opzionale precisione imposta il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. esempio di bcmul()

<?php
echo bcmul(1.34747474747, 35, 3) . "\n";
echo bcmul(2, 4);
?>

L'esempio mostrerà:

47.162
8

Vedere anche bcdiv().

bcpow

(PHP 3, PHP 4 , PHP 5)

bcpow --  Effettua l'elevamento a potenza

Descrizione

string bcpow ( string x, string y [, int precisione])

Eleva x alla potenza y. Il parametro opzionale precisione può essere usato per impostare il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. bcpow() example

<?php

echo bcpow(4.2, 3, 2); // 74.08

?>

Vedere anche bcsqrt() e bcsqrt().

bcpowmod

(PHP 5)

bcpowmod --  Effettua l'elevamento a potenza, applicando quindi il modulo.

Descrizione

string bcpowmod ( string x, string y, string modulo [, int precisione])

Utilizza il metodo di esponenziazione veloce per elevare x alla potenza y rispetto al modulo modulo. Il parametro opzionale precisione può essere utilizzato per impostare il numero di cifre dopo il punto decimale.

Le seguenti istruzioni sono funzionalmente identiche. La versione bcpowmod(), comunque, esegue in meno tempo e può accettare parametri più grandi.

<?php
$a = bcpowmod($x, $y, $mod);

$b = bcmod(bcpow($x, $y), $mod);

// $a e $b sono uguali. 

?>

Nota: Dal momento che questo metodo utilizza l'operatore modulo, numeri non naturali possono dare risultati indefiniti. Un numero naturale è un intero positivo maggiore di zero.

Vedere anche bcpow() e bcmod().

bcscale

(PHP 3, PHP 4 , PHP 5)

bcscale --  Imposta il valore di precisione di default per tutte le funzioni matematich BCMath

Descrizione

bool bcscale ( int precisione)

Questa funzione imposta il valore di default del parametro precisione per tutte le funzioni BCMath susseguenti, che non specifichino esplicitamente un parametro di precisione numerica. Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Esempio 1. esempio di bcscale()

<?php

// precisione di default : 3
bcscale(3);
echo bcdiv(105, 6.55957); // 16.007

// la stessa cosa, senza utilizzare bcscale()
echo bcdiv(105, 6.55957, 3); // 16.007

?>

bcsqrt

(PHP 3, PHP 4 , PHP 5)

bcsqrt --  Ottiene la radice quadrata di un numero a precisione arbitraria

Descrizione

string bcsqrt ( string operando [, int precisione])

Restituisce la radice quadrata di operando. Il parametro opzionale precisione imposta il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. esempio di bcsqrt()

<?php

echo bcsqrt(2, 3); // 1.414

?>

Vedere anche bcpow().

bcsub

(PHP 3, PHP 4 , PHP 5)

bcsub --  Sottrae un numero a precisione arbitraria da un altro

Descrizione

string bcsub ( string primo operando, string secondo operando [, int precisione])

Sottrae il primo operando dal secondo operando e retituisce il risultato in una stringa. Il parametro opzionale scale è usato per impostare il numero di cifre dopo il punto decimale nel risultato.

Esempio 1. esempio di bcsub()

<?php

$a = 1.234;
$b = 5;
 
echo bcsub($a, $b);     // -3
echo bcsub($a, $b, 4);  // -3.7660

?>

Vedere anche bcadd().

V. Funzioni di compressione Bzip2

Introduzione

Le funzioni bzip2 sono utilizzate per leggere e scrivere in modo trasparente i file compressi con bzip2 (.bz2).


Requisiti

Questo modulo tuilizza le funzioni della libreria bzip2 di Julian Seward. Questo modulo richiede che la versione di bzip2/libbzip2 sia >= 1.0.x.


Installazione

Il supporto di bzip2 in PHP non è abilitato di default. Si deve utilizzare l'opzione --with-bz2[=DIR] quando si compila PHP, per abilitare il supporto bzip2.


Configurazione di Runtime

Questa estensione non definisce alcuna direttiva di configurazione in php.ini


Tipi di risorse

Questa estensione definisce un tipo di risorsa: un puntatore a file che identifica il file bz2 su cui lavorare.


Costanti predefinite

Questa estensione non definisce alcuna costante.


Esempi

Questo esempio apre un file temporaneo e scrive una stringa di prova su di esso, quindi stampa il contenuto del file.

Esempio 1. breve esempio di bzip2

<?php

$nomefile = "/tmp/filediprova.bz2";
$str = "Questa è una stringa di prova.\n";

// apre il file in lettura
$bz = bzopen($nomefile, "w");

// scrive la stringa sul file
bzwrite($bz, $str);

// chiude il file
bzclose($bz);

// apre il file in lettura
$bz = bzopen($nomefile, "r");

// legge 10 caratteri
echo bzread($bz, 10);

// stampa fino alla fine del file (o fino ai prossimi 1024 caratteri) e chiude il file.
echo bzread($bz);

bzclose($bz);

?>
Sommario
bzclose -- Chiude un puntatore a un file bzip2
bzcompress -- Comprime una stringa nel formato bzip2
bzdecompress -- Decomprime dati codificati con bzip2
bzerrno -- Restituisce il codice d'errore bzip2
bzerror -- Restituisce il codice d'errore bzip2 e la stringa corrispondente in un array
bzerrstr -- restituisce la stringa di errore bzip2
bzflush -- Forza la scrittura di tutti i dati nel buffer
bzopen -- Apre un file compresso bzip2
bzread -- Esegue la lettura binaria di un file bzip2
bzwrite -- Esegue la scrittura binaria di un file bzip2

bzclose

(PHP 4 >= 4.0.4, PHP 5)

bzclose -- Chiude un puntatore a un file bzip2

Descrizione

int bzclose ( resource bz)

Chiude il file bzip2 referenziato dal puntatore bz.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Il puntatore al file deve essere valido, e deve puntare a un file gi$agrave; aperto con bzopen().

Vedere anche bzopen().

bzcompress

(PHP 4 >= 4.0.4, PHP 5)

bzcompress -- Comprime una stringa nel formato bzip2

Descrizione

string bzcompress ( string sorgente [, int dimblocco [, int workfactor]])

bzcompress() comprime la stringa sorgente e la restituisce come dati codificati in bzip2.

Il parametro opzionale dimblocco specifica la dimensione del blocco usato durante la compressione e dovrebbe essere un numero tra 1 e 9 dove 9 dà la compressione migliore, ma usando più risorse. dimblocco ha come valore predefinito 4.

Il parametro opzionale workfactor controlla il comportamento della fase di compressione quando deve trattare col caso peggiore, ovvero dati in ingresso molto ripetitivi. Il valore può variare tra 0 e 250, dove 0 è un caso speciale e 30 è il valore di default. Indipendentemente dal parametro workfactor, i dat generati sono gli stessi.

Esempio 1. Esempio di bzcompress()

<?php
$str = "dati di prova";
$bzstr = bzcompress($str, 9);
echo $bzstr;
?>

See also bzdecompress().

bzdecompress

(PHP 4 >= 4.0.4, PHP 5)

bzdecompress -- Decomprime dati codificati con bzip2

Descrizione

string bzdecompress ( string sorgente [, int small])

bzdecompress() decomprime la stringa sorgente contenente dati codificati in bzip2 e li restituisce. Se il parametro opzionale small è TRUE, verrà usato un algoritmo di decompressione alternativo che richiede meno memoria (la maximum quantità massima di memoria richiesta scende a 2300K) ma funziona a circa la metà della velocità. Vedere la documentazione di bzip2 per maggiori informazioni su questa funzionalità.

Esempio 1. bzdecompress()

<?php
$stringa_iniziale = "Sto facendo il mio lavoro?";
$bzstr = bzcompress($start_str);

echo "Stirnga Compressa: ";
echo $bzstr;
echo "\n<br />\n";

$stringa = bzdecompress($bzstr);
echo "Stringa Decompressa: ";
echo $str;
echo "\n<br />\n";
?>

See also bzcompress().

bzerrno

(PHP 4 >= 4.0.4, PHP 5)

bzerrno -- Restituisce il codice d'errore bzip2

Descrizione

int bzerrno ( resource bz)

Restituisce il codice di un qualsiasi errore bzip2 restituito dal puntatore al file bz.

Vedere anche bzerror() e bzerrstr().

bzerror

(PHP 4 >= 4.0.4, PHP 5)

bzerror -- Restituisce il codice d'errore bzip2 e la stringa corrispondente in un array

Descrizione

array bzerror ( resource bz)

Restituisce il codice e la stringa di errore, sotto forma di array associativo, di un errore bzip2 restituito dal puntatore bz.

Esempio 1. Esempio di bzerror()

<?php
$errore = bzerror($bz);

echo $errore["errno"];
echo $errore["errstr"];
?>

Vedere anche bzerrno() e bzerrstr().

bzerrstr

(PHP 4 >= 4.0.4, PHP 5)

bzerrstr -- restituisce la stringa di errore bzip2

Descrizione

string bzerrstr ( resource bz)

Resituisce la stringa di errore bzip2 restituito dal puntatore bz.

Vedere anche bzerrno() e bzerror().

bzflush

(PHP 4 >= 4.0.4, PHP 5)

bzflush -- Forza la scrittura di tutti i dati nel buffer

Descrizione

int bzflush ( resource bz)

Forza la scrittura di tutti i dati che sono nel buffer del puntatore bz.

Restituisce TRUE in caso di successo, FALSE in caso di fallimento.

Vedere anche bzread() e bzwrite().

bzopen

(PHP 4 >= 4.0.4, PHP 5)

bzopen -- Apre un file compresso bzip2

Descrizione

resource bzopen ( string nomefile, string modo)

Apre un file bzip2 (.bz2) in lettura o scrittura. nomefile è il nome del file da aprire. Il parametro modo è simile a quello della funzione fopen() (`r' per lettura, `w' per scrittura, ecc.).

Se l'operazione fallisce, la funzione restituisce FALSE, altrimenti restituisce un puntatore al file appena aperto.

Esempio 1. Esempio dibzopen()

<?php

$file = "/tmp/foo.bz2";
$bz = bzopen($file, "r") or die("non sono riuscito ad aprire in lettura $file");

bzclose($bz);

?>

Vedere anche bzclose().

bzread

(PHP 4 >= 4.0.4, PHP 5)

bzread -- Esegue la lettura binaria di un file bzip2

Descrizione

string bzread ( resource bz [, int lunghezza])

bzread() legge fino a lunghezza byte dal puntatore bzip2 specificato da bz. La pettura termina quando lunghezza byte (decompressi) sono stati letti o quando viene raggiunto l'EOF. Se il parametro opzionale lunghezza è omesso, bzread() leggerà 1024 byte (decompressi) ogni volta.

Esempio 1. Esempio di bzread()

<?php

$file = "/tmp/foo.bz2";
$bz = bzopen($file, "r") or die("Non ho potuto aprire $file");

$File_decompresso = '';
while (!feof($bz)) {
   $file_decompresso .= bzread($bz, 4096);
}
bzclose($bz);

echo "Il contenuto di $file è: <br />\n";
echo $file_decompresso;

?>

Vedere anche bzwrite(), feof() e bzopen().

bzwrite

(PHP 4 >= 4.0.4, PHP 5)

bzwrite -- Esegue la scrittura binaria di un file bzip2

Descrizione

int bzwrite ( resource bz, string dati [, int lunghezza])

bzwrite() scrie il contenuto della stringa dati nel file bzip2 puntato da bz. Se il parametro opzionale lunghezza è specificato, la scrittura si fermerà dopo che siano stati scritti lunghezza byte (decompressi) o al raggiungimento della fine della stringa.

Esempio 1. Esempio di bzwrite()

<?php
$str = "dati non compressi";
$bz = bzopen("/tmp/foo.bz2", "w");
bzwrite($bz, $str, strlen($str));
bzclose($bz);
?>

Vedere anche bzread() e bzopen().

VI. Funzioni Calendar

Introduzione

L'estensione calendar presenta una serie di funzioni che semplificano la conversione tra differenti formati di calendario. Il formato intermedio o standard è basato sul Conteggio del Giorno Giuliano. Il Conteggio Giuliano è un conteggio di giorni che parte molto prima di qualsiasi data la maggior parte della gente potrebbe usare (circa il 4000 a.C.). Per convertire tra i sistemi di calendario, si deve prima convertire nel sistema del Giorno Giuliano, poi nel sistema di calendario scelto. Il Conteggio del Giorno Giuliano è molto diverso dal Calendario Giulano! Per maggiori informazioni sui sistemi di calendario vedere http://www.boogle.com/info/cal-overview.html. Parti di questa pagina sono inclusi in queste istruzioni, citate tra virgolette.


Installazione

Affinché queste funzioni siano disponibili, occorre compilare PHP con l'opzione --enable-calendar.

La versione per Windows di PHP ha già compilato il supporto per questo modulo. Non occorre caricare alcun modulo addizionale per potere utilizzare queste funzioni.


Configurazione di Runtime

Questa estensione non definisce alcuna direttiva di configurazione in php.ini


Tipi di risorse

Questa estensione non definisce alcun tipo di risorsa.


Costanti predefinite

Queste costanti sono definite da questa estensione e sono disponibili solo se l'estensione è stata compilata nel PHP o se è stata caricata dinamicamente a runtime.

CAL_GREGORIAN (integer)

CAL_JULIAN (integer)

CAL_JEWISH (integer)

CAL_FRENCH (integer)

CAL_NUM_CALS (integer)

CAL_DOW_DAYNO (integer)

CAL_DOW_SHORT (integer)

CAL_DOW_LONG (integer)

CAL_MONTH_GREGORIAN_SHORT (integer)

CAL_MONTH_GREGORIAN_LONG (integer)

CAL_MONTH_JULIAN_SHORT (integer)

CAL_MONTH_JULIAN_LONG (integer)

CAL_MONTH_JEWISH (integer)

CAL_MONTH_FRENCH (integer)

Le seguenti costanti sono disponibili dal PHP 4.3.0 :

CAL_EASTER_DEFAULT (integer)

CAL_EASTER_ROMAN (integer)

CAL_EASTER_ALWAYS_GREGORIAN (integer)

CAL_EASTER_ALWAYS_JULIAN (integer)

Le seguenti costanti sono disponibili dal PHP 5.0.0 :

CAL_JEWISH_ADD_ALAFIM_GERESH (integer)

CAL_JEWISH_ADD_ALAFIM (integer)

CAL_JEWISH_ADD_GERESHAYIM (integer)

Sommario
cal_days_in_month -- Restituisce il numero di giorni di un mese per un dato anno e calendario
cal_from_jd -- Converte dal Giorno Giuliano ad un calendario
cal_info -- Restituisce informazioni su un particolare calendario
cal_to_jd -- Converte da un calendario a un Giorno Giuliano
easter_date --  Restituisce un timestamp Unix della mezzanotte del giorno di Pasqua di un dato anno
easter_days --  Restituisce il numero di giorni tra il 21 Marzo e Pasqua, dato un anno
FrenchToJD --  Converte una data del Calendario Repubblicano Francese in un Giorno Giuliano
GregorianToJD --  Converte una data Gregoriana in un Giorno Giuliano
JDDayOfWeek -- Restituisce il giorno della settimana
JDMonthName -- Restituisce il nome di un mese
JDToFrench --  Converte un Giorno Giuliano in una data del Calendario Repubblicano Francese
JDToGregorian -- Converte il Giorno Giuliano in data Gregoriana
jdtojewish --  Converte un Giorno Giuliano nel Calendario Giudeo
JDToJulian --  Converte un Giorno Giuliano in una data Giuliana
jdtounix -- Converte un Giorno Giuliano in un timestamp Unix
JewishToJD --  Converte una data del Calendario Giudeo in Giorno Giuliano
JulianToJD --  Converte una data Giuliana in un Giorno Giuliano
unixtojd -- Converte un timestamp Unix in un Giorno Giuliano

cal_days_in_month

(PHP 4 >= 4.1.0, PHP 5)

cal_days_in_month -- Restituisce il numero di giorni di un mese per un dato anno e calendario

Descrizione

int cal_days_in_month ( int calendario, int mese, int anno)

Questa funzione restituisce il numero di giorni che compongono il mese dell'anno nel calendar specificato.

Esempio 1. esempio di cal_days_in_month()

<?php
$num = cal_days_in_month(CAL_GREGORIAN, 8, 2003); // 31
echo "C'erano $num giorni nell'agosto del 2003";
?>

Vedere anche jdtounix().

cal_from_jd

(PHP 4 >= 4.1.0, PHP 5)

cal_from_jd -- Converte dal Giorno Giuliano ad un calendario

Descrizione

array cal_from_jd ( int giornogiuliano, int calendario)

cal_from_jd() converte il Giorno Giuliano specificato in giornogiuliano in una data del calendario specificato. I valori ammessi di calendario sono CAL_GREGORIAN, CAL_JULIAN, CAL_JEWISH e CAL_FRENCH.

Esempio 1. esempio di cal_from_jd()

<?php
$today = unixtojd(mktime(0, 0, 0, 8, 16, 2003));
print_r(cal_from_jd($today, CAL_GREGORIAN));
?>

Questo mostrerà:

Array
(
    [date] => 8/16/2003
    [month] => 8
    [day] => 16
    [year] => 2003
    [dow] => 6
    [abbrevdayname] => Sat
    [dayname] => Saturday
    [abbrevmonth] => Aug
    [monthname] => August
)

Vedere anche cal_to_jd().

cal_info

(PHP 4 >= 4.1.0, PHP 5)

cal_info -- Restituisce informazioni su un particolare calendario

Descrizione

array cal_info ( [int calendario])

cal_info() restituisce informazioni sullo specifico calendario o su tutti i calendari supportati se il parametro calendario non è specificato.

Lei informazioni sul calendario sono restituite in un array contenente gli elementi calname, calsymbol, month, abbrevmonth e maxdaysinmonth.

Se calendario non è specificato, le informazioni su tutti i calendari supportati sono restituite nell'array. Questa funzionalità sarà disponibile dal PHP 5.

cal_to_jd

(PHP 4 >= 4.1.0, PHP 5)

cal_to_jd -- Converte da un calendario a un Giorno Giuliano

Descrizione

int cal_to_jd ( int calendario, int mese, int giorno, int anno)

cal_to_jd() calcola il Giorno Giuliano per una data del calendario specificato. I valori supportati per calendario sono CAL_GREGORIAN, CAL_JULIAN, CAL_JEWISH e CAL_FRENCH.

Vedere anche cal_to_jd().

easter_date

(PHP 3>= 3.0.9, PHP 4 , PHP 5)

easter_date --  Restituisce un timestamp Unix della mezzanotte del giorno di Pasqua di un dato anno

Descrizione

int easter_date ( [int anno])

Restituisce il timestamp Unix corrispondente alla mezzanotte del giorno di Pasqua dell'anno specificato.

Dal PHP 4.3.0, il parametro anno è opzionale e ha come default l'anno corrente, se omesso.

Esempio 1. esempio di easter_date()

<?php

echo date("d M Y", easter_date(1999));        // 04 Apr 1999
echo date("d M Y", easter_date(2000));        // 23 Apr 2000
echo date("d M Y", easter_date(2001));        // 15 Apr 2001

?>

Avvertimento

Questa funzione gerererà un allarme (warning) se l'anno è fuori dall'escursione di validità dei timestamp UNIX (cioè prima del 1970 o dopo il 2037).

La data della Pasqua fu definita dal Concilio di Nicea nel 325 d.C. come la Domenica successiva alla prima luna piena dopo l'Equinozio di Primavera. Si assume che l'Equinozio cada sempre il 21 Marzo, quindi il calcolo si riduce alla determinazione della data della luna piena e la data della Domenica seguente. L'algoritmo qui usato fu proposto attorno all'anno 532 d.C. da Dionysius Exiguus (Dionigi il Piccolo). Nel Calendario Giuliano (for years before 1753) un semplice ciclo di 19 anni è usato per tracciare le fasi della Luna. Nel Calendario Gregoriano (per gli anni dopo il 1753 - ideato da Clavius e Lilius, e introdotto da Papa Gregorio XIII nell'Ottobre 1582, e in Gran Bretagna e nelle sue colonie nel Settembre 1752) due fattori correttivi sono aggiunti per rendere più accurato il ciclo.

(Il codice è basato su un programma in C di Simon Kershaw, <webmaster at ely.anglican dot org>)

Vedere easter_days() per il calcolo della Pasqua prima del 1970 o dopo il 2037.

easter_days

(PHP 3>= 3.0.9, PHP 4 , PHP 5)

easter_days --  Restituisce il numero di gio