home *** CD-ROM | disk | FTP | other *** search
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <HTML
- ><HEAD
- ><TITLE
- >PHP Manual</TITLE
- ><META
- NAME="GENERATOR"
- CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><META
- HTTP-EQUIV="Content-type"
- CONTENT="text/html; charset=ISO-8859-1"></HEAD
- ><BODY
- CLASS="book"
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#840084"
- ALINK="#0000FF"
- ><DIV
- CLASS="BOOK"
- ><A
- NAME="manual"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- ><A
- NAME="bookinfo"
- >PHP Manual</A
- ></H1
- ><DIV
- CLASS="author"
- >Mehdi Achour</DIV
- ><DIV
- CLASS="author"
- >Friedhelm Betz</DIV
- ><DIV
- CLASS="author"
- >Antony Dovgal</DIV
- ><DIV
- CLASS="author"
- >Nuno Lopes</DIV
- ><DIV
- CLASS="author"
- >Philip Olson</DIV
- ><DIV
- CLASS="author"
- >Georg Richter</DIV
- ><DIV
- CLASS="author"
- >Damien Seguy</DIV
- ><DIV
- CLASS="author"
- >Jakub Vrana</DIV
- ><SPAN
- CLASS="collab"
- ><SPAN
- CLASS="collabname"
- >
<A
- HREF="#contributors"
- >And several others</A
- >
- </SPAN
- ><BR></SPAN
- ><H2
- CLASS="EDITEDBY"
- >Edited by</H2
- ><DIV
- CLASS="editor"
- >Gabor Hojtsy</DIV
- ><P
- CLASS="pubdate"
- >03-01-2005<BR></P
- ><P
- CLASS="copyright"
- >Copyright © 1997-2005 the PHP Documentation Group</P
- ><DIV
- CLASS="legalnotice"
- ><A
- NAME="copyright"
- ></A
- ><P
- ><B
- >Copyright</B
- ></P
- ><P
- >
Copyright © 1997 - 2005 by the PHP Documentation Group.
- This material may be distributed only subject to the terms and
- conditions set forth in the Open Publication License, v1.0 or
- later. A copy of the <A
- HREF="#opl.license"
- >Open Publication
- License</A
- > is distributed with this manual, the latest version
- is presently available at <A
- HREF="http://www.opencontent.org/openpub/"
- TARGET="_top"
- >http://www.opencontent.org/openpub/</A
- >.
- </P
- ><P
- >
Distribution of substantively modified versions of this document
- is prohibited without the explicit permission of the copyright
- holder.
- </P
- ><P
- >
Distribution of the work or derivative of the work in any
- standard (paper) book form is prohibited unless prior permission
- is obtained from the copyright holder.
- </P
- ><P
- >
In case you are interested in redistribution or republishing of this document
- in whole or in part, either modified or unmodified, and you have questions,
- please contact the copyright holders at
- <A
- HREF="mailto:doc-license@lists.php.net"
- TARGET="_top"
- >doc-license@lists.php.net</A
- >.
- Note that this address is mapped to a publicly archived mailing list.
- </P
- ><P
- >
The 'Extending PHP 4.0' section of this manual is copyright © 2000 by
- Zend Technologies, Ltd. This material may be distributed only subject to
- the terms and conditions set forth in the Open Publication License, v1.0
- or later (the latest version is presently available at
- <A
- HREF="http://www.opencontent.org/openpub/"
- TARGET="_top"
- >http://www.opencontent.org/openpub/</A
- >).
- </P
- ></DIV
- ><HR></DIV
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- ><A
- HREF="#preface"
- >Preface</A
- ></DT
- ><DD
- ><DL
- ><DT
- ><A
- HREF="#contributors"
- >Authors and Contributors</A
- ></DT
- ></DL
- ></DD
- ><DT
- >I. <A
- HREF="#getting-started"
- >Getting Started</A
- ></DT
- ><DD
- ><DL
- ><DT
- >1. <A
- HREF="#introduction"
- >Introduction</A
- ></DT
- ><DT
- >2. <A
- HREF="#tutorial"
- >A simple tutorial</A
- ></DT
- ></DL
- ></DD
- ><DT
- >II. <A
- HREF="#install"
- >Installation and Configuration</A
- ></DT
- ><DD
- ><DL
- ><DT
- >3. <A
- HREF="#install.general"
- >General Installation Considerations</A
- ></DT
- ><DT
- >4. <A
- HREF="#install.unix"
- >Installation on Unix systems</A
- ></DT
- ><DT
- >5. <A
- HREF="#install.macosx"
- >Installation on Mac OS X</A
- ></DT
- ><DT
- >6. <A
- HREF="#install.windows"
- >Installation on Windows systems</A
- ></DT
- ><DT
- >7. <A
- HREF="#install.pecl"
- >Installation of PECL extensions</A
- ></DT
- ><DT
- >8. <A
- HREF="#install.problems"
- >Problems?</A
- ></DT
- ><DT
- >9. <A
- HREF="#configuration"
- >Runtime Configuration</A
- ></DT
- ></DL
- ></DD
- ><DT
- >III. <A
- HREF="#langref"
- >Language Reference</A
- ></DT
- ><DD
- ><DL
- ><DT
- >10. <A
- HREF="#language.basic-syntax"
- >Basic syntax</A
- ></DT
- ><DT
- >11. <A
- HREF="#language.types"
- >Types</A
- ></DT
- ><DT
- >12. <A
- HREF="#language.variables"
- >Variables</A
- ></DT
- ><DT
- >13. <A
- HREF="#language.constants"
- >Constants</A
- ></DT
- ><DT
- >14. <A
- HREF="#language.expressions"
- >Expressions</A
- ></DT
- ><DT
- >15. <A
- HREF="#language.operators"
- >Operators</A
- ></DT
- ><DT
- >16. <A
- HREF="#language.control-structures"
- >Control Structures</A
- ></DT
- ><DT
- >17. <A
- HREF="#language.functions"
- >Functions</A
- ></DT
- ><DT
- >18. <A
- HREF="#language.oop"
- >Classes and Objects (PHP 4)</A
- ></DT
- ><DT
- >19. <A
- HREF="#language.oop5"
- >Classes and Objects (PHP 5)</A
- ></DT
- ><DT
- >20. <A
- HREF="#language.exceptions"
- >Exceptions</A
- ></DT
- ><DT
- >21. <A
- HREF="#language.references"
- >References Explained</A
- ></DT
- ></DL
- ></DD
- ><DT
- >IV. <A
- HREF="#security"
- >Security</A
- ></DT
- ><DD
- ><DL
- ><DT
- >22. <A
- HREF="#security.intro"
- >Introduction</A
- ></DT
- ><DT
- >23. <A
- HREF="#security.general"
- >General considerations</A
- ></DT
- ><DT
- >24. <A
- HREF="#security.cgi-bin"
- >Installed as CGI binary</A
- ></DT
- ><DT
- >25. <A
- HREF="#security.apache"
- >Installed as an Apache module</A
- ></DT
- ><DT
- >26. <A
- HREF="#security.filesystem"
- >Filesystem Security</A
- ></DT
- ><DT
- >27. <A
- HREF="#security.database"
- >Database Security</A
- ></DT
- ><DT
- >28. <A
- HREF="#security.errors"
- >Error Reporting</A
- ></DT
- ><DT
- >29. <A
- HREF="#security.globals"
- >Using Register Globals</A
- ></DT
- ><DT
- >30. <A
- HREF="#security.variables"
- >User Submitted Data</A
- ></DT
- ><DT
- >31. <A
- HREF="#security.magicquotes"
- >Magic Quotes</A
- ></DT
- ><DT
- >32. <A
- HREF="#security.hiding"
- >Hiding PHP</A
- ></DT
- ><DT
- >33. <A
- HREF="#security.current"
- >Keeping Current</A
- ></DT
- ></DL
- ></DD
- ><DT
- >V. <A
- HREF="#features"
- >Features</A
- ></DT
- ><DD
- ><DL
- ><DT
- >34. <A
- HREF="#features.http-auth"
- >HTTP authentication with PHP</A
- ></DT
- ><DT
- >35. <A
- HREF="#features.cookies"
- >Cookies</A
- ></DT
- ><DT
- >36. <A
- HREF="#features.sessions"
- >Sessions</A
- ></DT
- ><DT
- >37. <A
- HREF="#features.xforms"
- >Dealing with XForms</A
- ></DT
- ><DT
- >38. <A
- HREF="#features.file-upload"
- >Handling file uploads</A
- ></DT
- ><DT
- >39. <A
- HREF="#features.remote-files"
- >Using remote files</A
- ></DT
- ><DT
- >40. <A
- HREF="#features.connection-handling"
- >Connection handling</A
- ></DT
- ><DT
- >41. <A
- HREF="#features.persistent-connections"
- >Persistent Database Connections</A
- ></DT
- ><DT
- >42. <A
- HREF="#features.safe-mode"
- >Safe Mode</A
- ></DT
- ><DT
- >43. <A
- HREF="#features.commandline"
- >Using PHP from the command line</A
- ></DT
- ></DL
- ></DD
- ><DT
- >VI. <A
- HREF="#funcref"
- >Function Reference</A
- ></DT
- ><DD
- ><DL
- ><DT
- >I. <A
- HREF="#ref.apache"
- >Apache-specific Functions</A
- ></DT
- ><DT
- >II. <A
- HREF="#ref.apd"
- >Advanced PHP debugger</A
- ></DT
- ><DT
- >III. <A
- HREF="#ref.array"
- >Array Functions</A
- ></DT
- ><DT
- >IV. <A
- HREF="#ref.aspell"
- >Aspell functions [deprecated]</A
- ></DT
- ><DT
- >V. <A
- HREF="#ref.bc"
- >BCMath Arbitrary Precision Mathematics Functions</A
- ></DT
- ><DT
- >VI. <A
- HREF="#ref.bcompiler"
- >PHP bytecode Compiler</A
- ></DT
- ><DT
- >VII. <A
- HREF="#ref.bzip2"
- >Bzip2 Compression Functions</A
- ></DT
- ><DT
- >VIII. <A
- HREF="#ref.calendar"
- >Calendar Functions</A
- ></DT
- ><DT
- >IX. <A
- HREF="#ref.ccvs"
- >CCVS API Functions [deprecated]</A
- ></DT
- ><DT
- >X. <A
- HREF="#ref.com"
- >COM and .Net (Windows)</A
- ></DT
- ><DT
- >XI. <A
- HREF="#ref.classkit"
- >Classkit Functions</A
- ></DT
- ><DT
- >XII. <A
- HREF="#ref.classobj"
- >Class/Object Functions</A
- ></DT
- ><DT
- >XIII. <A
- HREF="#ref.cpdf"
- >ClibPDF Functions</A
- ></DT
- ><DT
- >XIV. <A
- HREF="#ref.crack"
- >Crack Functions</A
- ></DT
- ><DT
- >XV. <A
- HREF="#ref.curl"
- >CURL, Client URL Library Functions</A
- ></DT
- ><DT
- >XVI. <A
- HREF="#ref.cybercash"
- >Cybercash Payment Functions</A
- ></DT
- ><DT
- >XVII. <A
- HREF="#ref.cyrus"
- >Cyrus IMAP administration Functions</A
- ></DT
- ><DT
- >XVIII. <A
- HREF="#ref.ctype"
- >Character Type Functions</A
- ></DT
- ><DT
- >XIX. <A
- HREF="#ref.dba"
- >Database (dbm-style) Abstraction Layer Functions</A
- ></DT
- ><DT
- >XX. <A
- HREF="#ref.datetime"
- >Date and Time Functions</A
- ></DT
- ><DT
- >XXI. <A
- HREF="#ref.dbase"
- >dBase Functions</A
- ></DT
- ><DT
- >XXII. <A
- HREF="#ref.dbm"
- >DBM Functions [deprecated]</A
- ></DT
- ><DT
- >XXIII. <A
- HREF="#ref.dbx"
- >dbx Functions</A
- ></DT
- ><DT
- >XXIV. <A
- HREF="#ref.dbplus"
- >DB++ Functions</A
- ></DT
- ><DT
- >XXV. <A
- HREF="#ref.dio"
- >Direct IO Functions</A
- ></DT
- ><DT
- >XXVI. <A
- HREF="#ref.dir"
- >Directory Functions</A
- ></DT
- ><DT
- >XXVII. <A
- HREF="#ref.dom"
- >DOM Functions</A
- ></DT
- ><DT
- >XXVIII. <A
- HREF="#ref.domxml"
- >DOM XML Functions</A
- ></DT
- ><DT
- >XXIX. <A
- HREF="#ref.dotnet"
- >.NET Functions</A
- ></DT
- ><DT
- >XXX. <A
- HREF="#ref.errorfunc"
- >Error Handling and Logging Functions</A
- ></DT
- ><DT
- >XXXI. <A
- HREF="#ref.exif"
- >Exif Functions</A
- ></DT
- ><DT
- >XXXII. <A
- HREF="#ref.fam"
- >File Alteration Monitor Functions</A
- ></DT
- ><DT
- >XXXIII. <A
- HREF="#ref.fbsql"
- >FrontBase Functions</A
- ></DT
- ><DT
- >XXXIV. <A
- HREF="#ref.filepro"
- >filePro Functions</A
- ></DT
- ><DT
- >XXXV. <A
- HREF="#ref.filesystem"
- >Filesystem Functions</A
- ></DT
- ><DT
- >XXXVI. <A
- HREF="#ref.fdf"
- >Forms Data Format Functions</A
- ></DT
- ><DT
- >XXXVII. <A
- HREF="#ref.fribidi"
- >FriBiDi Functions</A
- ></DT
- ><DT
- >XXXVIII. <A
- HREF="#ref.ftp"
- >FTP Functions</A
- ></DT
- ><DT
- >XXXIX. <A
- HREF="#ref.funchand"
- >Function Handling Functions</A
- ></DT
- ><DT
- >XL. <A
- HREF="#ref.gettext"
- >Gettext</A
- ></DT
- ><DT
- >XLI. <A
- HREF="#ref.gmp"
- >GMP Functions</A
- ></DT
- ><DT
- >XLII. <A
- HREF="#ref.http"
- >HTTP Functions</A
- ></DT
- ><DT
- >XLIII. <A
- HREF="#ref.hw"
- >Hyperwave Functions</A
- ></DT
- ><DT
- >XLIV. <A
- HREF="#ref.hwapi"
- >Hyperwave API Functions</A
- ></DT
- ><DT
- >XLV. <A
- HREF="#ref.iconv"
- >iconv Functions</A
- ></DT
- ><DT
- >XLVI. <A
- HREF="#ref.image"
- >Image Functions</A
- ></DT
- ><DT
- >XLVII. <A
- HREF="#ref.imap"
- >IMAP, POP3 and NNTP Functions</A
- ></DT
- ><DT
- >XLVIII. <A
- HREF="#ref.ifx"
- >Informix Functions</A
- ></DT
- ><DT
- >XLIX. <A
- HREF="#ref.ibase"
- >Firebird/InterBase Functions</A
- ></DT
- ><DT
- >L. <A
- HREF="#ref.id3"
- >ID3 Functions</A
- ></DT
- ><DT
- >LI. <A
- HREF="#ref.ingres"
- >Ingres II Functions</A
- ></DT
- ><DT
- >LII. <A
- HREF="#ref.ircg"
- >IRC Gateway Functions</A
- ></DT
- ><DT
- >LIII. <A
- HREF="#ref.java"
- >PHP / Java Integration</A
- ></DT
- ><DT
- >LIV. <A
- HREF="#ref.ldap"
- >LDAP Functions</A
- ></DT
- ><DT
- >LV. <A
- HREF="#ref.lzf"
- >LZF Functions</A
- ></DT
- ><DT
- >LVI. <A
- HREF="#ref.mail"
- >Mail Functions</A
- ></DT
- ><DT
- >LVII. <A
- HREF="#ref.mailparse"
- >mailparse Functions</A
- ></DT
- ><DT
- >LVIII. <A
- HREF="#ref.math"
- >Mathematical Functions</A
- ></DT
- ><DT
- >LIX. <A
- HREF="#ref.mbstring"
- >Multibyte String Functions</A
- ></DT
- ><DT
- >LX. <A
- HREF="#ref.mcal"
- >MCAL Functions</A
- ></DT
- ><DT
- >LXI. <A
- HREF="#ref.mcrypt"
- >Mcrypt Encryption Functions</A
- ></DT
- ><DT
- >LXII. <A
- HREF="#ref.mcve"
- >MCVE Payment Functions</A
- ></DT
- ><DT
- >LXIII. <A
- HREF="#ref.memcache"
- >Memcache Functions</A
- ></DT
- ><DT
- >LXIV. <A
- HREF="#ref.mhash"
- >Mhash Functions</A
- ></DT
- ><DT
- >LXV. <A
- HREF="#ref.mime-magic"
- >Mimetype Functions</A
- ></DT
- ><DT
- >LXVI. <A
- HREF="#ref.mssql"
- >Microsoft SQL Server Functions</A
- ></DT
- ><DT
- >LXVII. <A
- HREF="#ref.ming"
- >Ming functions for Flash</A
- ></DT
- ><DT
- >LXVIII. <A
- HREF="#ref.misc"
- >Miscellaneous Functions</A
- ></DT
- ><DT
- >LXIX. <A
- HREF="#ref.mnogosearch"
- >mnoGoSearch Functions</A
- ></DT
- ><DT
- >LXX. <A
- HREF="#ref.msql"
- >mSQL Functions</A
- ></DT
- ><DT
- >LXXI. <A
- HREF="#ref.mysql"
- >MySQL Functions</A
- ></DT
- ><DT
- >LXXII. <A
- HREF="#ref.mysqli"
- >Improved MySQL Extension</A
- ></DT
- ><DT
- >LXXIII. <A
- HREF="#ref.msession"
- >Mohawk Software Session Handler Functions</A
- ></DT
- ><DT
- >LXXIV. <A
- HREF="#ref.muscat"
- >muscat Functions</A
- ></DT
- ><DT
- >LXXV. <A
- HREF="#ref.network"
- >Network Functions</A
- ></DT
- ><DT
- >LXXVI. <A
- HREF="#ref.ncurses"
- >Ncurses Terminal Screen Control Functions</A
- ></DT
- ><DT
- >LXXVII. <A
- HREF="#ref.notes"
- >Lotus Notes Functions</A
- ></DT
- ><DT
- >LXXVIII. <A
- HREF="#ref.nsapi"
- >NSAPI-specific Functions</A
- ></DT
- ><DT
- >LXXIX. <A
- HREF="#ref.uodbc"
- >ODBC Functions (Unified)</A
- ></DT
- ><DT
- >LXXX. <A
- HREF="#ref.objaggregation"
- >Object Aggregation/Composition Functions</A
- ></DT
- ><DT
- >LXXXI. <A
- HREF="#ref.oci8"
- >Oracle 8 functions</A
- ></DT
- ><DT
- >LXXXII. <A
- HREF="#ref.openal"
- >OpenAL Audio Bindings</A
- ></DT
- ><DT
- >LXXXIII. <A
- HREF="#ref.openssl"
- >OpenSSL Functions</A
- ></DT
- ><DT
- >LXXXIV. <A
- HREF="#ref.oracle"
- >Oracle Functions</A
- ></DT
- ><DT
- >LXXXV. <A
- HREF="#ref.ovrimos"
- >Ovrimos SQL Functions</A
- ></DT
- ><DT
- >LXXXVI. <A
- HREF="#ref.outcontrol"
- >Output Control Functions</A
- ></DT
- ><DT
- >LXXXVII. <A
- HREF="#ref.overload"
- >Object property and method call overloading</A
- ></DT
- ><DT
- >LXXXVIII. <A
- HREF="#ref.parsekit"
- >Parsekit Functions</A
- ></DT
- ><DT
- >LXXXIX. <A
- HREF="#ref.pdf"
- >PDF functions</A
- ></DT
- ><DT
- >XC. <A
- HREF="#ref.pdo"
- >PDO Functions</A
- ></DT
- ><DT
- >XCI. <A
- HREF="#ref.pfpro"
- >Verisign Payflow Pro Functions</A
- ></DT
- ><DT
- >XCII. <A
- HREF="#ref.info"
- >PHP Options&Information</A
- ></DT
- ><DT
- >XCIII. <A
- HREF="#ref.posix"
- >POSIX Functions</A
- ></DT
- ><DT
- >XCIV. <A
- HREF="#ref.pgsql"
- >PostgreSQL Functions</A
- ></DT
- ><DT
- >XCV. <A
- HREF="#ref.pcntl"
- >Process Control Functions</A
- ></DT
- ><DT
- >XCVI. <A
- HREF="#ref.exec"
- >Program Execution Functions</A
- ></DT
- ><DT
- >XCVII. <A
- HREF="#ref.printer"
- >Printer Functions</A
- ></DT
- ><DT
- >XCVIII. <A
- HREF="#ref.pspell"
- >Pspell Functions</A
- ></DT
- ><DT
- >XCIX. <A
- HREF="#ref.readline"
- >GNU Readline</A
- ></DT
- ><DT
- >C. <A
- HREF="#ref.recode"
- >GNU Recode Functions</A
- ></DT
- ><DT
- >CI. <A
- HREF="#ref.pcre"
- >Regular Expression Functions (Perl-Compatible)</A
- ></DT
- ><DT
- >CII. <A
- HREF="#ref.qtdom"
- >qtdom Functions</A
- ></DT
- ><DT
- >CIII. <A
- HREF="#ref.rar"
- >Rar Functions</A
- ></DT
- ><DT
- >CIV. <A
- HREF="#ref.regex"
- >Regular Expression Functions (POSIX Extended)</A
- ></DT
- ><DT
- >CV. <A
- HREF="#ref.ssh2"
- >Secure Shell2 Functions</A
- ></DT
- ><DT
- >CVI. <A
- HREF="#ref.sem"
- >Semaphore, Shared Memory and IPC Functions</A
- ></DT
- ><DT
- >CVII. <A
- HREF="#ref.sesam"
- >SESAM Database Functions</A
- ></DT
- ><DT
- >CVIII. <A
- HREF="#ref.session"
- >Session Handling Functions</A
- ></DT
- ><DT
- >CIX. <A
- HREF="#ref.shmop"
- >Shared Memory Functions</A
- ></DT
- ><DT
- >CX. <A
- HREF="#ref.simplexml"
- >SimpleXML functions</A
- ></DT
- ><DT
- >CXI. <A
- HREF="#ref.soap"
- >SOAP Functions</A
- ></DT
- ><DT
- >CXII. <A
- HREF="#ref.sqlite"
- >SQLite</A
- ></DT
- ><DT
- >CXIII. <A
- HREF="#ref.swf"
- >Shockwave Flash Functions</A
- ></DT
- ><DT
- >CXIV. <A
- HREF="#ref.snmp"
- >SNMP Functions</A
- ></DT
- ><DT
- >CXV. <A
- HREF="#ref.sockets"
- >Socket Functions</A
- ></DT
- ><DT
- >CXVI. <A
- HREF="#ref.spl"
- >Standard PHP Library (SPL) Functions</A
- ></DT
- ><DT
- >CXVII. <A
- HREF="#ref.stream"
- >Stream Functions</A
- ></DT
- ><DT
- >CXVIII. <A
- HREF="#ref.strings"
- >String Functions</A
- ></DT
- ><DT
- >CXIX. <A
- HREF="#ref.sybase"
- >Sybase Functions</A
- ></DT
- ><DT
- >CXX. <A
- HREF="#ref.tcpwrap"
- >TCP Wrappers Functions</A
- ></DT
- ><DT
- >CXXI. <A
- HREF="#ref.tidy"
- >Tidy Functions</A
- ></DT
- ><DT
- >CXXII. <A
- HREF="#ref.tokenizer"
- >Tokenizer Functions</A
- ></DT
- ><DT
- >CXXIII. <A
- HREF="#ref.url"
- >URL Functions</A
- ></DT
- ><DT
- >CXXIV. <A
- HREF="#ref.var"
- >Variable Functions</A
- ></DT
- ><DT
- >CXXV. <A
- HREF="#ref.vpopmail"
- >vpopmail Functions</A
- ></DT
- ><DT
- >CXXVI. <A
- HREF="#ref.w32api"
- >W32api Functions</A
- ></DT
- ><DT
- >CXXVII. <A
- HREF="#ref.wddx"
- >WDDX Functions</A
- ></DT
- ><DT
- >CXXVIII. <A
- HREF="#ref.xattr"
- >xattr Functions</A
- ></DT
- ><DT
- >CXXIX. <A
- HREF="#ref.xml"
- >XML Parser Functions</A
- ></DT
- ><DT
- >CXXX. <A
- HREF="#ref.xmlrpc"
- >XML-RPC Functions</A
- ></DT
- ><DT
- >CXXXI. <A
- HREF="#ref.xdiff"
- >xdiff Functions</A
- ></DT
- ><DT
- >CXXXII. <A
- HREF="#ref.xsl"
- >XSL functions</A
- ></DT
- ><DT
- >CXXXIII. <A
- HREF="#ref.xslt"
- >XSLT Functions</A
- ></DT
- ><DT
- >CXXXIV. <A
- HREF="#ref.yaz"
- >YAZ Functions</A
- ></DT
- ><DT
- >CXXXV. <A
- HREF="#ref.nis"
- >YP/NIS Functions</A
- ></DT
- ><DT
- >CXXXVI. <A
- HREF="#ref.zip"
- >Zip File Functions (Read Only Access)</A
- ></DT
- ><DT
- >CXXXVII. <A
- HREF="#ref.zlib"
- >Zlib Compression Functions</A
- ></DT
- ></DL
- ></DD
- ><DT
- >VII. <A
- HREF="#zend"
- >Zend API</A
- ></DT
- ><DD
- ><DL
- ><DT
- >44. <A
- HREF="#zend.overview"
- >Overview</A
- ></DT
- ><DT
- >45. <A
- HREF="#zend.possibilities"
- >Extension Possibilities</A
- ></DT
- ><DT
- >46. <A
- HREF="#zend.layout"
- >Source Layout</A
- ></DT
- ><DT
- >47. <A
- HREF="#zend.build"
- >PHP's Automatic Build System</A
- ></DT
- ><DT
- >48. <A
- HREF="#zend.creating"
- >Creating Extensions</A
- ></DT
- ><DT
- >49. <A
- HREF="#zend.using"
- >Using Extensions</A
- ></DT
- ><DT
- >50. <A
- HREF="#zend.troubleshooting"
- >Troubleshooting</A
- ></DT
- ><DT
- >51. <A
- HREF="#zend.structure"
- >Source Discussion</A
- ></DT
- ><DT
- >52. <A
- HREF="#zend.arguments"
- >Accepting Arguments</A
- ></DT
- ><DT
- >53. <A
- HREF="#zend.variables"
- >Creating Variables</A
- ></DT
- ><DT
- >54. <A
- HREF="#zend.copy-constructor"
- >Duplicating Variable Contents: The Copy Constructor</A
- ></DT
- ><DT
- >55. <A
- HREF="#zend.returning"
- >Returning Values</A
- ></DT
- ><DT
- >56. <A
- HREF="#zend.printing"
- >Printing Information</A
- ></DT
- ><DT
- >57. <A
- HREF="#zend.startup-and-shutdown"
- >Startup and Shutdown Functions</A
- ></DT
- ><DT
- >58. <A
- HREF="#zend.calling-user-functions"
- >Calling User Functions</A
- ></DT
- ><DT
- >59. <A
- HREF="#zend.ini-file-support"
- >Initialization File Support</A
- ></DT
- ><DT
- >60. <A
- HREF="#zend.where-to-go"
- >Where to Go from Here</A
- ></DT
- ><DT
- >61. <A
- HREF="#zend.configuration-macros"
- >Reference: Some Configuration Macros</A
- ></DT
- ><DT
- >62. <A
- HREF="#zend.api-macros"
- >API Macros</A
- ></DT
- ></DL
- ></DD
- ><DT
- >VIII. <A
- HREF="#api"
- >PHP API: Interfaces for extension writers</A
- ></DT
- ><DD
- ><DL
- ><DT
- >63. <A
- HREF="#streams"
- >Streams API for PHP Extension Authors</A
- ></DT
- ></DL
- ></DD
- ><DT
- >IX. <A
- HREF="#faq"
- >FAQ: Frequently Asked Questions</A
- ></DT
- ><DD
- ><DL
- ><DT
- >64. <A
- HREF="#faq.general"
- >General Information</A
- ></DT
- ><DT
- >65. <A
- HREF="#faq.mailinglist"
- >Mailing lists</A
- ></DT
- ><DT
- >66. <A
- HREF="#faq.obtaining"
- >Obtaining PHP</A
- ></DT
- ><DT
- >67. <A
- HREF="#faq.databases"
- >Database issues</A
- ></DT
- ><DT
- >68. <A
- HREF="#faq.installation"
- >Installation</A
- ></DT
- ><DT
- >69. <A
- HREF="#faq.build"
- >Build Problems</A
- ></DT
- ><DT
- >70. <A
- HREF="#faq.using"
- >Using PHP</A
- ></DT
- ><DT
- >71. <A
- HREF="#faq.html"
- >PHP and HTML</A
- ></DT
- ><DT
- >72. <A
- HREF="#faq.com"
- >PHP and COM</A
- ></DT
- ><DT
- >73. <A
- HREF="#faq.languages"
- >PHP and other languages</A
- ></DT
- ><DT
- >74. <A
- HREF="#faq.migration"
- >Migrating from PHP 2 to PHP 3</A
- ></DT
- ><DT
- >75. <A
- HREF="#faq.migration4"
- >Migrating from PHP 3 to PHP 4</A
- ></DT
- ><DT
- >76. <A
- HREF="#faq.migration5"
- >Migrating from PHP 4 to PHP 5</A
- ></DT
- ><DT
- >77. <A
- HREF="#faq.misc"
- >Miscellaneous Questions</A
- ></DT
- ></DL
- ></DD
- ><DT
- >X. <A
- HREF="#appendixes"
- >Appendixes</A
- ></DT
- ><DD
- ><DL
- ><DT
- >A. <A
- HREF="#history"
- >History of PHP and related projects</A
- ></DT
- ><DT
- >B. <A
- HREF="#migration5"
- >Migrating from PHP 4 to PHP 5</A
- ></DT
- ><DT
- >C. <A
- HREF="#migration4"
- >Migrating from PHP 3 to PHP 4</A
- ></DT
- ><DT
- >D. <A
- HREF="#migration"
- >Migrating from PHP/FI 2 to PHP 3</A
- ></DT
- ><DT
- >E. <A
- HREF="#debugger"
- >Debugging PHP</A
- ></DT
- ><DT
- >F. <A
- HREF="#phpdevel"
- >Extending PHP 3</A
- ></DT
- ><DT
- >G. <A
- HREF="#configure"
- >Configure options</A
- ></DT
- ><DT
- >H. <A
- HREF="#ini"
- >List of core <TT
- CLASS="filename"
- >php.ini</TT
- > directives</A
- ></DT
- ><DT
- >I. <A
- HREF="#aliases"
- >List of Function Aliases</A
- ></DT
- ><DT
- >J. <A
- HREF="#reserved"
- >List of Reserved Words</A
- ></DT
- ><DT
- >K. <A
- HREF="#resource"
- >List of Resource Types</A
- ></DT
- ><DT
- >L. <A
- HREF="#wrappers"
- >List of Supported Protocols/Wrappers</A
- ></DT
- ><DT
- >M. <A
- HREF="#filters"
- >List of Available Filters</A
- ></DT
- ><DT
- >N. <A
- HREF="#transports"
- >List of Supported Socket Transports</A
- ></DT
- ><DT
- >O. <A
- HREF="#types.comparisons"
- >PHP type comparison tables</A
- ></DT
- ><DT
- >P. <A
- HREF="#tokens"
- >List of Parser Tokens</A
- ></DT
- ><DT
- >Q. <A
- HREF="#about"
- >About the manual</A
- ></DT
- ><DT
- >R. <A
- HREF="#opl.license"
- >Open Publication License</A
- ></DT
- ><DT
- >S. <A
- HREF="#indexes"
- >Function Index</A
- ></DT
- ><DT
- >T. <A
- HREF="#missing-stuff"
- >Missing Stuff</A
- ></DT
- ></DL
- ></DD
- ></DL
- ></DIV
- ><DIV
- CLASS="preface"
- ><HR><H1
- ><A
- NAME="preface"
- >Preface</A
- ></H1
- ><BLOCKQUOTE
- CLASS="ABSTRACT"
- ><DIV
- CLASS="abstract"
- ><P
- ></P
- ><A
- NAME="AEN54"
- ></A
- ><P
- >
<ACRONYM
- CLASS="acronym"
- >PHP</ACRONYM
- >, which stands for "PHP: Hypertext
- Preprocessor" is a widely-used Open Source general-purpose
- scripting language that is especially suited for Web
- development and can be embedded into HTML. Its syntax draws
- upon C, Java, and Perl, and is easy to learn. The main goal of
- the language is to allow web developers to write dynamically
- generated webpages quickly, but you can do much more with PHP.
- </P
- ><P
- ></P
- ></DIV
- ></BLOCKQUOTE
- ><P
- >
This manual consists primarily of a <A
- HREF="#funcref"
- >
function reference</A
- >, but also contains a
- <A
- HREF="#langref"
- >language reference</A
- >, explanations
- of some of PHP's major <A
- HREF="#features"
- >features</A
- >,
- and other <A
- HREF="#appendixes"
- >supplemental</A
- >
- information.
- </P
- ><P
- >
You can download this manual in several formats at <A
- HREF="http://www.php.net/download-docs.php"
- TARGET="_top"
- >http://www.php.net/download-docs.php</A
- >.
- More information about how this manual is developed can be found in the
- <A
- HREF="#about"
- >'About the manual'</A
- > appendix. If you are
- interested in the <A
- HREF="#history"
- >history of PHP</A
- >,
- visit the relevant appendix.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="contributors"
- >Authors and Contributors</A
- ></H2
- ><P
- > We highlight the currently most active
- people on the manual frontpage, but there are many more contributors who
- currently help in our work or provided a great amount of help to the project
- in the past. There are a lot of unnamed people who help out with their user
- notes on manual pages, which continually get included in the references, the
- work of whom we are also very thankful for. All the lists provided below are in
- alphabetical order.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="AEN69"
- >Authors and Editors</A
- ></H3
- ><P
- >
The following contributors should be
- recognized for the impact they have made and/or continue to make by adding
- content to the manual:
- Jouni Ahto,
- Alexander Aulbach,
- Daniel Beckham,
- Stig Bakken,
- Jesus M. Castagnetto,
- Ron Chmara,
- John Coggeshall,
- Simone Cortesi,
- Markus Fischer,
- Wez Furlong,
- Sara Golemon,
- Rui Hirokawa,
- Brad House,
- Moriyoshi Koizumi,
- Rasmus Lerdorf,
- Andrew Lindeman,
- Stanislav Malyshev,
- Rafael Martinez,
- Yasuo Ohgaki,
- Derick Rethans,
- Sander Roobol,
- Egon Schmid,
- Thomas Schoefbeck,
- Sascha Schumann,
- Lars Torben Wilson,
- Jim Winstead,
- Jeroen van Wolffelaar and
- Andrei Zmievski.
- </P
- ><P
- >
The following contributors have done
- significant work editing the manual:
- Stig Bakken,
- Hartmut Holzgraefe and
- Egon Schmid.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="AEN73"
- >User Note Maintainers</A
- ></H3
- ><P
- >
The currently most active maintainers are:
- Mehdi Achour,
- Friedhelm Betz,
- Vincent Gevers,
- Aidan Lister,
- Nuno Lopes and
- Tom Sommer.
- </P
- ><P
- >
These people have also put a lot of effort
- into managing user notes:
- Daniel Beckham,
- Victor Boivie,
- Jesus M. Castagnetto,
- Nicolas Chaillan,
- Ron Chmara,
- James Cox,
- Sara Golemon,
- Zak Greant,
- Szabolcs Heilig,
- Oliver Hinckel,
- Hartmut Holzgraefe,
- Rasmus Lerdorf,
- Andrew Lindeman,
- Maxim Maletsky,
- James Moore,
- Sebastian Picklum,
- Derick Rethans,
- Sander Roobol,
- Damien Seguy,
- Jason Sheets,
- Jani Taskinen,
- Yasuo Ohgaki,
- Philip Olson,
- Lars Torben Wilson,
- Jim Winstead,
- Jared Wyles and
- Jeroen van Wolffelaar.
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="getting-started"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >I. Getting Started</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >1. <A
- HREF="#introduction"
- >Introduction</A
- ></DT
- ><DT
- >2. <A
- HREF="#tutorial"
- >A simple tutorial</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="introduction"
- >Chapter 1. Introduction</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="intro-whatis"
- >What is PHP?</A
- ></H2
- ><P
- >
<ACRONYM
- CLASS="acronym"
- >PHP</ACRONYM
- > (recursive acronym for "PHP: Hypertext
- Preprocessor") is a widely-used Open Source general-purpose
- scripting language that is especially suited for Web
- development and can be embedded into HTML.
- </P
- ><P
- >
Simple answer, but what does that mean? An example:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN87"
- ></A
- ><P
- ><B
- >Example 1-1. An introductory example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><html>
- <head>
- <title>Example</title>
- </head>
- <body>
-
- <?php
- echo "Hi, I'm a PHP script!";
- ?>
-
- </body>
- </html></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Notice how this is different from a script written in other
- languages like Perl or C -- instead of writing a program with lots
- of commands to output HTML, you write an HTML script with some
- embedded code to do something (in this case, output some
- text). The PHP code is enclosed in special <A
- HREF="#language.basic-syntax.phpmode"
- >start and end tags</A
- >
- that allow you to jump into and out of "PHP mode".
- </P
- ><P
- >
What distinguishes PHP from something like client-side JavaScript
- is that the code is executed on the server. If you were to have a
- script similar to the above on your server, the client would receive
- the results of running that script, with no way of determining what
- the underlying code may be. You can even configure your web server
- to process all your HTML files with PHP, and then there's really no
- way that users can tell what you have up your sleeve.
- </P
- ><P
- >
The best things in using PHP are that it is extremely simple
- for a newcomer, but offers many advanced features for
- a professional programmer. Don't be afraid reading the long
- list of PHP's features. You can jump in, in a short time, and
- start writing simple scripts in a few hours.
- </P
- ><P
- >
Although PHP's development is focused on server-side scripting,
- you can do much more with it. Read on, and see more in the
- <A
- HREF="#intro-whatcando"
- >What can PHP do?</A
- > section,
- or go right to the <A
- HREF="#tutorial"
- >introductory
- tutorial</A
- > if you are only interested in web programming.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="intro-whatcando"
- >What can PHP do?</A
- ></H2
- ><P
- >
Anything. PHP is mainly focused on server-side scripting,
- so you can do anything any other CGI program can do, such
- as collect form data, generate dynamic page content, or
- send and receive cookies. But PHP can do much more.
- </P
- ><P
- >
There are three main areas where PHP scripts are used.
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Server-side scripting. This is the most traditional
- and main target field for PHP. You need three things
- to make this work. The PHP parser (CGI or server
- module), a webserver and a web browser. You need to
- run the webserver, with a connected PHP installation.
- You can access the PHP program output with a web browser,
- viewing the PHP page through the server. All these can
- run on your home machine if you are just experimenting
- with PHP programming. See the
- <A
- HREF="#install"
- >installation instructions</A
- >
- section for more information.
- </P
- ></LI
- ><LI
- ><P
- >
Command line scripting. You can make a PHP script
- to run it without any server or browser.
- You only need the PHP parser to use it this way.
- This type of usage is ideal for scripts regularly
- executed using cron (on *nix or Linux) or Task Scheduler (on
- Windows). These scripts can also be used for simple text
- processing tasks. See the section about
- <A
- HREF="#features.commandline"
- >Command line usage of PHP</A
- >
- for more information.
- </P
- ></LI
- ><LI
- ><P
- >
Writing desktop applications. PHP is probably
- not the very best language to create a desktop
- application with a graphical user interface, but if
- you know PHP very well, and would like to use some
- advanced PHP features in your client-side applications
- you can also use PHP-GTK to write such programs. You also
- have the ability to write cross-platform applications this
- way. PHP-GTK is an extension to PHP, not available in
- the main distribution. If you are interested
- in PHP-GTK, visit <A
- HREF="http://gtk.php.net/"
- TARGET="_top"
- >its
- own website</A
- >.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
PHP can be used on all major operating systems, including
- Linux, many Unix variants (including HP-UX, Solaris and OpenBSD),
- Microsoft Windows, Mac OS X, RISC OS, and probably others.
- PHP has also support for most of the web servers today. This
- includes Apache, Microsoft Internet Information Server,
- Personal Web Server, Netscape and iPlanet servers, Oreilly
- Website Pro server, Caudium, Xitami, OmniHTTPd, and many
- others. For the majority of the servers PHP has a module,
- for the others supporting the CGI standard, PHP can work
- as a CGI processor.
- </P
- ><P
- >
So with PHP, you have the freedom of choosing an operating
- system and a web server. Furthermore, you also have the choice
- of using procedural programming or object oriented
- programming, or a mixture of them. Although not every
- standard OOP feature is implemented in PHP 4,
- many code libraries and large applications (including
- the PEAR library) are written only using OOP code. PHP 5 fixes the
- OOP related weaknesses of PHP 4, and introduces a complete object
- model.
- </P
- ><P
- >
With PHP you are not limited to output HTML. PHP's abilities
- includes outputting images, PDF files and even Flash movies
- (using libswf and Ming) generated on the fly. You can also
- output easily any text, such as XHTML and any other XML file.
- PHP can autogenerate these files, and save them in the file
- system, instead of printing it out, forming a server-side
- cache for your dynamic content.
- </P
- ><P
- >
One of the strongest and most significant features in PHP is its
- support for a wide range of databases. Writing a database-enabled
- web page is incredibly simple. The following databases are currently
- supported:
- <A
- NAME="AEN115"
- ></A
- ><BLOCKQUOTE
- CLASS="BLOCKQUOTE"
- ><P
- ></P
- ><TABLE
- BORDER="0"
- ><TBODY
- ><TR
- ><TD
- >Adabas D</TD
- ><TD
- >InterBase</TD
- ><TD
- >PostgreSQL</TD
- ></TR
- ><TR
- ><TD
- >dBase</TD
- ><TD
- >FrontBase</TD
- ><TD
- >SQLite</TD
- ></TR
- ><TR
- ><TD
- >Empress</TD
- ><TD
- >mSQL</TD
- ><TD
- >Solid</TD
- ></TR
- ><TR
- ><TD
- >FilePro (read-only)</TD
- ><TD
- >Direct MS-SQL</TD
- ><TD
- >Sybase</TD
- ></TR
- ><TR
- ><TD
- >Hyperwave</TD
- ><TD
- >MySQL</TD
- ><TD
- >Velocis</TD
- ></TR
- ><TR
- ><TD
- >IBM DB2</TD
- ><TD
- >ODBC</TD
- ><TD
- >Unix dbm</TD
- ></TR
- ><TR
- ><TD
- >Informix</TD
- ><TD
- >Oracle (OCI7 and OCI8)</TD
- ><TD
- > </TD
- ></TR
- ><TR
- ><TD
- >Ingres</TD
- ><TD
- >Ovrimos</TD
- ><TD
- > </TD
- ></TR
- ></TBODY
- ></TABLE
- ><P
- ></P
- ></BLOCKQUOTE
- >
- We also have a DBX database abstraction extension allowing you
- to transparently use any database supported by that extension.
- Additionally PHP supports ODBC, the Open Database Connection
- standard, so you can connect to any other database supporting
- this world standard.
- </P
- ><P
- >
PHP also has support for talking to other services using protocols
- such as LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (on Windows) and
- countless others. You can also open raw network sockets and
- interact using any other protocol. PHP has support for the WDDX
- complex data exchange between virtually all Web programming
- languages. Talking about interconnection, PHP has support for
- instantiation of Java objects and using them transparently
- as PHP objects. You can also use our CORBA extension to
- access remote objects.
- </P
- ><P
- >
PHP has extremely useful text processing features, from the
- POSIX Extended or Perl regular expressions to parsing XML
- documents. For parsing and accessing XML documents, PHP 4
- supports the SAX and DOM standards, and you can also use the
- XSLT extension to transform XML documents. PHP 5 standardizes
- all the XML extensions on the solid base of libxml2 and extends
- the feature set adding SimpleXML and XMLReader support.
- </P
- ><P
- >
While using PHP in the e-commerce field, you'll find
- the Cybercash payment, CyberMUT, VeriSign Payflow
- Pro and MCVE functions useful for your online payment
- programs.
- </P
- ><P
- >
At last but not least, we have many other interesting
- extensions, the mnoGoSearch search engine functions,
- the IRC Gateway functions, many compression utilities
- (gzip, bz2), calendar conversion, translation...
- </P
- ><P
- >
As you can see this page is not enough to list all
- the features and benefits PHP can offer. Read on in
- the sections about <A
- HREF="#install"
- >installing
- PHP</A
- >, and see the <A
- HREF="#funcref"
- >function
- reference</A
- > part for explanation of the extensions
- mentioned here.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="tutorial"
- >Chapter 2. A simple tutorial</A
- ></H1
- ><P
- >
Here we would like to show the very basics of PHP in a short, simple
- tutorial. This text only deals with dynamic webpage creation with
- PHP, though PHP is not only capable of creating webpages. See
- the section titled <A
- HREF="#intro-whatcando"
- >What can PHP
- do</A
- > for more information.
- </P
- ><P
- >
PHP-enabled web pages are treated just like regular HTML pages and
- you can create and edit them the same way you normally create
- regular HTML pages.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.requirements"
- >What do I need?</A
- ></H2
- ><P
- >
In this tutorial we assume that your server has activated support
- for PHP and that all files ending in <TT
- CLASS="filename"
- >.php</TT
- >
- are handled by PHP. On most servers, this is the default extension
- for PHP files, but ask your server administrator to be sure. If
- your server supports PHP, then you do not need to do anything. Just
- create your <TT
- CLASS="filename"
- >.php</TT
- > files, put them in your
- web directory and the server will automatically parse them for you.
- There is no need to compile anything nor do you need to install
- any extra tools. Think of these PHP-enabled files as simple HTML
- files with a whole new family of magical tags that let you do all
- sorts of things. Most web hosts offer PHP support, but if your
- host does not, consider reading the <A
- HREF="http://www.php.net/links.php"
- TARGET="_top"
- >
PHP Links</A
- > section for resources on finding PHP enabled
- web hosts.
- </P
- ><P
- >
Let us say you want to save precious bandwidth and develop locally.
- In this case, you will want to install a web server, such as
- <A
- HREF="http://www.apache.org/"
- TARGET="_top"
- >Apache</A
- >, and of course
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >PHP</A
- >. You will most likely
- want to install a database as well, such as
- <A
- HREF="http://dev.mysql.com/doc/"
- TARGET="_top"
- >MySQL</A
- >.
- </P
- ><P
- >
You can either install these individually or choose a simpler way. Our
- manual has <A
- HREF="#install"
- >installation instructions for
- PHP</A
- > (assuming you already have some webserver set up). In case
- you have problems with installing PHP yourself, we would suggest you ask
- your questions on our <A
- HREF="http://www.php.net/mailing-lists.php"
- TARGET="_top"
- >installation
- mailing list</A
- >. If you choose to go on the simpler route, then
- <A
- HREF="http://www.hotscripts.com/PHP/Software_and_Servers/Installation_Kits/"
- TARGET="_top"
- >locate a pre-configured package</A
- >
- for your operating system, which automatically installs all of these
- with just a few mouse clicks. It is easy to setup a web server with PHP
- support on any operating system, including MacOSX, Linux and Windows.
- On Linux, you may find <A
- HREF="http://www.rpmfind.net/"
- TARGET="_top"
- >rpmfind</A
- > and
- <A
- HREF="http://rpm.pbone.net/"
- TARGET="_top"
- >PBone</A
- > helpful for
- locating RPMs. You may also want to visit <A
- HREF="http://www.apt-get.org/"
- TARGET="_top"
- >apt-get</A
- > to find packages for Debian.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.firstpage"
- >Your first PHP-enabled page</A
- ></H2
- ><P
- >
Create a file named <TT
- CLASS="filename"
- >hello.php</TT
- > and put it
- in your web server's root directory (<VAR
- CLASS="varname"
- >DOCUMENT_ROOT</VAR
- >)
- with the following content:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN174"
- ></A
- ><P
- ><B
- >Example 2-1. Our first PHP script: <TT
- CLASS="filename"
- >hello.php</TT
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><html>
- <head>
- <title>PHP Test</title>
- </head>
- <body>
- <?php echo '<p>Hello World</p>'; ?>
- </body>
- </html></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Use your browser to access the file with your web server's URL, ending
- with the "/hello.php" file reference. When developing locally this
- URL will be something like <VAR
- CLASS="literal"
- >http://localhost/hello.php</VAR
- >
- or <VAR
- CLASS="literal"
- >http://127.0.0.1/hello.php</VAR
- > but this depends on the
- web server's configuration. If everything is configured correctly, this
- file will be parsed by PHP and the following output will be sent to
- your browser:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><html>
- <head>
- <title>PHP Test</title>
- </head>
- <body>
- <p>Hello World</p>
- </body>
- </html></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This program is extremely simple and you really did not need to use
- PHP to create a page like this. All it does is display:
- <VAR
- CLASS="literal"
- >Hello World</VAR
- > using the PHP <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- >
- statement. Note that the file <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >does not need to be executable</I
- ></SPAN
- >
- or special in any way. The server finds out that this file needs to be interpreted
- by PHP because you used the ".php" extension, which the server is configured
- to pass on to PHP. Think of this as a normal HTML file which happens to have
- a set of special tags available to you that do a lot of interesting things.
- </P
- ><P
- >
If you tried this example and it did not output anything, it prompted
- for download, or you see the whole file as text, chances are that the
- server you are on does not have PHP enabled, or is not configured properly.
- Ask your administrator to enable it for you using the
- <A
- HREF="#install"
- >Installation</A
- > chapter
- of the manual. If you are developing locally, also read the
- installation chapter to make sure everything is configured
- properly. Make sure that you access the file via http with the server
- providing you the output. If you just call up the file from your file
- system, then it will not be parsed by PHP. If the problems persist anyway,
- do not hesitate to use one of the many
- <A
- HREF="http://www.php.net/support.php"
- TARGET="_top"
- >PHP support</A
- > options.
- </P
- ><P
- >
The point of the example is to show the special PHP tag format.
- In this example we used <VAR
- CLASS="literal"
- ><?php</VAR
- > to indicate the
- start of a PHP tag. Then we put the PHP statement and left PHP mode by
- adding the closing tag, <VAR
- CLASS="literal"
- >?></VAR
- >. You may jump in
- and out of PHP mode in an HTML file like this anywhere you want. For more
- details, read the manual section on the <A
- HREF="#language.basic-syntax"
- >
basic PHP syntax</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >A Note on Text Editors: </B
- >
- There are many text editors and Integrated Development Environments (IDEs)
- that you can use to create, edit and manage PHP files. A partial list of
- these tools is maintained at <A
- HREF="http://www.thelinuxconsultancy.co.uk/phpeditors/"
- TARGET="_top"
- >PHP Editors
- List</A
- >. If you wish to recommend an editor, please visit the above
- page and ask the page maintainer to add the editor to the list. Having
- an editor with syntax highlighting can be helpful.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >A Note on Word Processors: </B
- >
- Word processors such as StarOffice Writer, Microsoft Word and Abiword are
- not optimal for editing PHP files. If you wish to use one for this
- test script, you must ensure that you save the file as <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >plain
- text</I
- ></SPAN
- > or PHP will not be able to read and execute the script.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >A Note on Windows Notepad: </B
- >
- If you are writing your PHP scripts using Windows Notepad, you will need
- to ensure that your files are saved with the .php extension. (Notepad adds
- a .txt extension to files automatically unless you take one of the
- following steps to prevent it.) When you save the file and are prompted
- to provide a name for the file, place the filename in quotes
- (i.e. "<TT
- CLASS="filename"
- >hello.php</TT
- >"). Alternatively, you can click on the
- 'Text Documents' drop-down menu in the 'Save' dialog box and change the setting
- to "All Files". You can then enter your filename without quotes.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Now that you have successfully created a working PHP script, it is
- time to create the most famous PHP script! Make a call to the
- <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > function and you will see a lot of useful
- information about your system and setup such as available
- <A
- HREF="#language.variables.predefined"
- >predefined variables</A
- >,
- loaded PHP modules, and <A
- HREF="#configuration"
- >configuration</A
- >
- settings. Take some time and review this important information.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN210"
- ></A
- ><P
- ><B
- >Example 2-2. Get system information from PHP</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php phpinfo(); ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.useful"
- >Something Useful</A
- ></H2
- ><P
- >
Let us do something more useful now. We are going to check
- what sort of browser the visitor is using.
- For that, we check the user agent string the browser
- sends as part of the HTTP request. This information is stored in a <A
- HREF="#language.variables"
- >variable</A
- >. Variables always start
- with a dollar-sign in PHP. The variable we are interested in right now
- is <VAR
- CLASS="varname"
- >$_SERVER['HTTP_USER_AGENT']</VAR
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="#reserved.variables.server"
- >$_SERVER</A
- > is a
- special reserved PHP variable that contains all web server information.
- It is known as an autoglobal (or superglobal). See the related manual page on
- <A
- HREF="#language.variables.superglobals"
- >superglobals</A
- >
- for more information. These special variables were introduced in PHP
- <A
- HREF="http://www.php.net/release_4_1_0.php"
- TARGET="_top"
- >4.1.0</A
- >. Before this time, we used
- the older <VAR
- CLASS="varname"
- >$HTTP_*_VARS</VAR
- > arrays instead,
- such as <VAR
- CLASS="varname"
- >$HTTP_SERVER_VARS</VAR
- >. Although deprecated,
- these older variables still exist. (See also the note on
- <A
- HREF="#tutorial.oldcode"
- >old code</A
- >.)
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
To display this variable, you can simply do:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN228"
- ></A
- ><P
- ><B
- >Example 2-3. Printing a variable (Array element)</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php echo $_SERVER['HTTP_USER_AGENT']; ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
A sample output of this script may be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- >Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
There are many <A
- HREF="#language.types"
- >types</A
- > of
- variables available in PHP. In the above example we printed
- an <A
- HREF="#language.types.array"
- >Array</A
- > element.
- Arrays can be very useful.
- </P
- ><P
- >
<VAR
- CLASS="varname"
- >$_SERVER</VAR
- > is just one variable that PHP automatically
- makes available to you. A list can be seen in the
- <A
- HREF="#reserved.variables"
- >Reserved Variables</A
- > section
- of the manual or you can get a complete list of them by looking at
- the output of the <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > function used in the
- example in the previous section.
- </P
- ><P
- >
You can put multiple PHP statements inside a PHP tag and create
- little blocks of code that do more than just a single echo.
- For example, if you want to check for Internet Explorer you
- can do this:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN242"
- ></A
- ><P
- ><B
- >Example 2-4. Example using <A
- HREF="#language.control-structures"
- >control
- structures</A
- > and <A
- HREF="#language.functions"
- >functions</A
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
- echo 'You are using Internet Explorer.<br />';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
A sample output of this script may be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- >You are using Internet Explorer.<br /></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Here we introduce a couple of new concepts. We have an
- <A
- HREF="#control-structures.if"
- >if</A
- > statement.
- If you are familiar with the basic syntax used by the C
- language, this should look logical to you. Otherwise, you
- should probably pick up an introductory PHP book and read the first
- couple of chapters, or read the <A
- HREF="#langref"
- >Language
- Reference</A
- > part of the manual. You can find a list of PHP books
- at <A
- HREF="http://www.php.net/books.php"
- TARGET="_top"
- >http://www.php.net/books.php</A
- >.
- </P
- ><P
- >
The second concept we introduced was the <A
- HREF="#function.strpos"
- ><B
- CLASS="function"
- >strpos()</B
- ></A
- >
- function call. <A
- HREF="#function.strpos"
- ><B
- CLASS="function"
- >strpos()</B
- ></A
- > is a function built into
- PHP which searches a string for another string. In this case we are
- looking for <VAR
- CLASS="literal"
- >'MSIE'</VAR
- > (so-called needle) inside
- <VAR
- CLASS="varname"
- >$_SERVER['HTTP_USER_AGENT']</VAR
- > (so-called haystack). If
- the needle is found inside the haystack, the function returns the position
- of the needle relative to the start of the haystack. Otherwise, it
- returns <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >. If it does not return <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, the <A
- HREF="#control-structures.if"
- >if</A
- > expression evaluates to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >
- and the code within its {braces} is executed. Otherwise, the code is not
- run. Feel free to create similar examples,
- with <A
- HREF="#control-structures.if"
- >if</A
- >,
- <A
- HREF="#control-structures.else"
- >else</A
- >, and other
- functions such as <A
- HREF="#function.strtoupper"
- ><B
- CLASS="function"
- >strtoupper()</B
- ></A
- > and
- <A
- HREF="#function.strlen"
- ><B
- CLASS="function"
- >strlen()</B
- ></A
- >. Each related manual page contains examples
- too. If you are unsure how to use functions, you will want to read both
- the manual page on <A
- HREF="#about.prototypes"
- >how to read a
- function definition</A
- > and the section about
- <A
- HREF="#language.functions"
- >PHP functions</A
- >.
- </P
- ><P
- >
We can take this a step further and show how you can jump in and out
- of PHP mode even in the middle of a PHP block:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN270"
- ></A
- ><P
- ><B
- >Example 2-5. Mixing both HTML and PHP modes</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
- ?>
- <h3>strpos() must have returned non-false</h3>
- <p>You are using Internet Explorer</p>
- <?php
- } else {
- ?>
- <h3>strpos() must have returned false</h3>
- <p>You are not using Internet Explorer</p>
- <?php
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
A sample output of this script may be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><h3>strpos() must have returned non-false</h3>
- <p>You are using Internet Explorer</p></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Instead of using a PHP echo statement to output something, we jumped out
- of PHP mode and just sent straight HTML. The important and powerful point
- to note here is that the logical flow of the script remains intact. Only
- one of the HTML blocks will end up getting sent to the viewer depending on
- the result of <A
- HREF="#function.strpos"
- ><B
- CLASS="function"
- >strpos()</B
- ></A
- >. In other words, it depends on
- whether the string <VAR
- CLASS="literal"
- >MSIE</VAR
- > was found or not.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.forms"
- >Dealing with Forms</A
- ></H2
- ><P
- >
One of the most powerful features of PHP is the way it handles HTML
- forms. The basic concept that is important to understand is that any
- form element will automatically be available to your PHP
- scripts. Please read the manual section on
- <A
- HREF="#language.variables.external"
- >Variables from outside
- of PHP</A
- > for more information and examples on using forms
- with PHP. Here is an example HTML form:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN283"
- ></A
- ><P
- ><B
- >Example 2-6. A simple HTML form</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><form action="action.php" method="post">
- <p>Your name: <input type="text" name="name" /></p>
- <p>Your age: <input type="text" name="age" /></p>
- <p><input type="submit" /></p>
- </form></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
There is nothing special about this form. It is a straight HTML form
- with no special tags of any kind. When the user fills in this form
- and hits the submit button, the <TT
- CLASS="filename"
- >action.php</TT
- > page
- is called. In this file you would write something like this:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN289"
- ></A
- ><P
- ><B
- >Example 2-7. Printing data from our form</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Hi <?php echo $_POST['name']; ?>.
- You are <?php echo $_POST['age']; ?> years old.</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
A sample output of this script may be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- >Hi Joe. You are 22 years old.</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
It should be obvious what this does. There is nothing more to it.
- The <VAR
- CLASS="varname"
- >$_POST['name']</VAR
- > and <VAR
- CLASS="varname"
- >$_POST['age']</VAR
- >
- variables are automatically set for you by PHP. Earlier we
- used the <VAR
- CLASS="varname"
- >$_SERVER</VAR
- > autoglobal; above we just
- introduced the <A
- HREF="#reserved.variables.post"
- >$_POST</A
- >
- autoglobal which contains all POST data. Notice how the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >method</I
- ></SPAN
- > of our form is POST. If we used the
- method <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >GET</I
- ></SPAN
- > then our form information would live in
- the <A
- HREF="#reserved.variables.get"
- >$_GET</A
- > autoglobal instead.
- You may also use the <A
- HREF="#reserved.variables.request"
- >$_REQUEST</A
- >
- autoglobal, if you do not care about the source of your request data. It
- contains the merged information of GET, POST and COOKIE data. Also see the
- <A
- HREF="#function.import-request-variables"
- ><B
- CLASS="function"
- >import_request_variables()</B
- ></A
- > function.
- </P
- ><P
- >
You can also deal with XForms input in PHP, although you will find yourself
- comfortable with the well supported HTML forms for quite some time.
- While working with XForms is not for beginners, you might be interested
- in them. We also have a <A
- HREF="#features.xforms"
- >short introduction
- to handling data received from XForms</A
- > in our features section.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.oldcode"
- >Using old code with new versions of PHP</A
- ></H2
- ><P
- >
Now that PHP has grown to be a popular scripting language, there are
- a lot of public repositories and libraries containing code you can reuse.
- The PHP developers have largely tried to preserve backwards compatibility,
- so a script written for an older version will run (ideally) without changes
- in a newer version of PHP. In practice, some changes will usually be needed.
- </P
- ><P
- >
Two of the most important recent changes that affect old code are:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
The deprecation of the old <VAR
- CLASS="varname"
- >$HTTP_*_VARS</VAR
- > arrays
- (which need to be indicated as global when used inside a function or
- method). The following
- <A
- HREF="#language.variables.superglobals"
- >autoglobal arrays</A
- >
- were introduced in PHP <A
- HREF="http://www.php.net/release_4_1_0.php"
- TARGET="_top"
- >4.1.0</A
- >.
- They are: <VAR
- CLASS="varname"
- >$_GET</VAR
- >, <VAR
- CLASS="varname"
- >$_POST</VAR
- >,
- <VAR
- CLASS="varname"
- >$_COOKIE</VAR
- >, <VAR
- CLASS="varname"
- >$_SERVER</VAR
- >,
- <VAR
- CLASS="varname"
- >$_FILES</VAR
- >, <VAR
- CLASS="varname"
- >$_ENV</VAR
- >,
- <VAR
- CLASS="varname"
- >$_REQUEST</VAR
- >, and <VAR
- CLASS="varname"
- >$_SESSION</VAR
- >. The
- older <VAR
- CLASS="varname"
- >$HTTP_*_VARS</VAR
- > arrays, such as
- <VAR
- CLASS="varname"
- >$HTTP_POST_VARS</VAR
- >, still exist as they have since PHP 3.
- As of PHP 5.0.0, the long PHP
- <A
- HREF="#language.variables.predefined"
- >predefined variable</A
- >
- arrays may be disabled with the
- <A
- HREF="#ini.register-long-arrays"
- >register_long_arrays</A
- >
- directive.
- </P
- ></LI
- ><LI
- ><P
- >
External variables are no longer registered in the global scope by
- default. In other words, as of PHP
- <A
- HREF="http://www.php.net/release_4_2_0.php"
- TARGET="_top"
- >4.2.0</A
- > the PHP directive
- <A
- HREF="#ini.register-globals"
- >register_globals</A
- > is
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >off</I
- ></SPAN
- > by default in <TT
- CLASS="filename"
- >php.ini</TT
- >. The preferred
- method of accessing these values is via the autoglobal arrays mentioned
- above. Older scripts, books, and tutorials may rely on this
- directive being on. If it were on, for example, one could use
- <VAR
- CLASS="varname"
- >$id</VAR
- > from the URL
- <VAR
- CLASS="literal"
- >http://www.example.com/foo.php?id=42</VAR
- >. Whether on
- or off, <VAR
- CLASS="varname"
- >$_GET['id']</VAR
- > is available.
- </P
- ></LI
- ></UL
- >
- For more details on these changes, see the section on
- <A
- HREF="#language.variables.predefined"
- >predefined variables</A
- >
- and links therein.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="tutorial.whatsnext"
- >What's next?</A
- ></H2
- ><P
- >
With your new knowledge you should be able to understand most of
- the manual and also the various example scripts available in the
- example archives. You can also find other examples on the php.net
- websites in the links section:
- <A
- HREF="http://www.php.net/links.php"
- TARGET="_top"
- >http://www.php.net/links.php</A
- >.
- </P
- ><P
- >
To view various slide presentations that show more of what PHP can do,
- see the PHP Conference Material Sites: <A
- HREF="http://conf.php.net/"
- TARGET="_top"
- >
http://conf.php.net/</A
- > and <A
- HREF="http://talks.php.net/"
- TARGET="_top"
- >http://talks.php.net/
- </A
- >
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="install"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >II. Installation and Configuration</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >3. <A
- HREF="#install.general"
- >General Installation Considerations</A
- ></DT
- ><DT
- >4. <A
- HREF="#install.unix"
- >Installation on Unix systems</A
- ></DT
- ><DT
- >5. <A
- HREF="#install.macosx"
- >Installation on Mac OS X</A
- ></DT
- ><DT
- >6. <A
- HREF="#install.windows"
- >Installation on Windows systems</A
- ></DT
- ><DT
- >7. <A
- HREF="#install.pecl"
- >Installation of PECL extensions</A
- ></DT
- ><DT
- >8. <A
- HREF="#install.problems"
- >Problems?</A
- ></DT
- ><DT
- >9. <A
- HREF="#configuration"
- >Runtime Configuration</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.general"
- >Chapter 3. General Installation Considerations</A
- ></H1
- ><P
- >
Before starting the installation, first you need to know what do you
- want to use PHP for. There are three main fields you
- can use PHP, as described in the
- <A
- HREF="#intro-whatcando"
- >What can PHP do?</A
- >
- section:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >Server-side scripting</P
- ></LI
- ><LI
- ><P
- >Command line scripting</P
- ></LI
- ><LI
- ><P
- >Client-side GUI applications</P
- ></LI
- ></UL
- >
- </P
- ><P
- >
For the first and most common form, you need three things:
- PHP itself, a web server and a web browser. You
- probably already have a web browser, and depending on
- your operating system setup, you may also have a web
- server (e.g. Apache on Linux and MacOS X; IIS on Windows).
- You may also rent webspace at a company. This way, you
- don't need to set up anything on your own, only write
- your PHP scripts, upload it to the server you rent, and
- see the results in your browser.
- </P
- ><P
- >
While setting up the server and PHP on your own, you have
- two choices for the method of connecting PHP to the
- server. For many servers PHP has a direct module
- interface (also called SAPI). These servers include
- Apache, Microsoft Internet Information Server,
- Netscape and iPlanet servers. Many other servers
- have support for ISAPI, the Microsoft module
- interface (OmniHTTPd for example). If PHP has no
- module support for your web server, you can always
- use it as a CGI or FastCGI processor. This means you set up
- your server to use the CGI executable of
- PHP to process all PHP file requests on the server.
- </P
- ><P
- >
If you are also interested to use PHP for command line
- scripting (e.g. write scripts autogenerating some images
- for you offline, or processing text files depending
- on some arguments you pass to them), you always need
- the command line executable. For more information, read
- the section about <A
- HREF="#features.commandline"
- >writing
- command line PHP applications</A
- >. In this case,
- you need no server and no browser.
- </P
- ><P
- >
With PHP you can also write desktop GUI applications
- using the PHP-GTK extension. This is a completely
- different approach than writing web pages, as you
- do not output any HTML, but manage windows and objects
- within them. For more information about PHP-GTK, please
- <A
- HREF="http://gtk.php.net/"
- TARGET="_top"
- >visit the site dedicated to
- this extension</A
- >. PHP-GTK is not included in the
- official PHP distribution.
- </P
- ><P
- >
From now on, this section deals with setting up PHP
- for web servers on Unix and Windows with server module
- interfaces and CGI executables. You will also find
- information on the command line executable in the
- following sections.
- </P
- ><P
- >
PHP source code and binary distributions for Windows can be
- found at
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >http://www.php.net/downloads.php</A
- >.
- We recommend you to choose a
- <A
- HREF="http://www.php.net/mirrors.php"
- TARGET="_top"
- >mirror</A
- > nearest
- to you for downloading the distributions.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.unix"
- >Chapter 4. Installation on Unix systems</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
As our manual outlines in the <A
- HREF="#install.general"
- >General
- Installation Considerations</A
- > section, we are mainly dealing with
- web centric setups of PHP in this section, although we will cover
- setting up PHP for command line usage as well.
- </P
- ><P
- >
- 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. Many Unix like systems
- have some sort of package installation system. This can assist 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 webserver.
- If you are unfamiliar with building and compiling your own software,
- it is worth checking to see whether somebody has already built a
- packaged version of PHP with the features you need.
- </P
- ><P
- >
Prerequisite knowledge and software for compiling:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Basic Unix skills (being able to operate "make" and a C
- compiler)
- </P
- ></LI
- ><LI
- ><P
- >
An ANSI C compiler
- </P
- ></LI
- ><LI
- ><P
- >
flex: Version 2.5.4
- </P
- ></LI
- ><LI
- ><P
- >
bison: Version 1.28 (preferred), 1.35, or 1.75
- </P
- ></LI
- ><LI
- ><P
- >
A web server
- </P
- ></LI
- ><LI
- ><P
- >
Any module specific components (such as gd, pdf libs, etc.)
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
The initial PHP setup and configuration process is controlled by the
- use of the commandline options of the <B
- CLASS="command"
- >configure</B
- >
- script. You could get a list of all available options along with short
- explanations running <B
- CLASS="command"
- >./configure --help</B
- >.
- Our manual documents the different options separately. You will
- find the <A
- HREF="#configure"
- >core options in the appendix</A
- >,
- while the different extension specific options are descibed on the
- reference pages.
- </P
- ><P
- >
When PHP is configured, you are ready to build the module and/or
- executables. The command <B
- CLASS="command"
- >make</B
- > should
- take care of this. If it fails and you can't figure out why, see
- the <A
- HREF="#install.problems"
- >Problems section</A
- >.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.apache"
- >Apache 1.3.x on Unix systems</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Apache installs
- of PHP on Unix platforms. We also have <A
- HREF="#install.unix.apache2"
- >instructions and notes for Apache 2
- on a separate page</A
- >.
- </P
- ><P
- >
You can select arguments to add to the
- <B
- CLASS="command"
- >configure</B
- > on line 10 below from the <A
- HREF="#configure"
- >list of core configure options</A
- > and
- from extension specific options described at the respective
- places in the manual. The version numbers have been omitted here, to
- ensure the instructions are not incorrect. You will need to replace
- the 'xxx' here with the correct values from your files.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.apache.example"
- ></A
- ><P
- ><B
- >Example 4-1.
- Installation Instructions (Apache Shared Module Version) for PHP
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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. Now, configure your PHP. This is where you customize your PHP
- with various options, like which extensions will be enabled. Do a
- ./configure --help for a list of available options. In our example
- we'll do a simple configure with Apache 1 and MySQL support. Your
- path to apxs may differ from our example.
-
- ./configure --with-mysql --with-apxs=/www/bin/apxs
-
- 11. make
- 12. make install
-
- If you decide to change your configure options after installation,
- you only need to repeat the last three steps. You only need to
- restart apache for the new module to take effect. A recompile of
- Apache is not needed.
-
- Note that unless told otherwise, 'make install' will also install PEAR,
- various PHP tools such as phpize, install the PHP CLI, and more.
-
- 13. Setup your php.ini file:
-
- cp php.ini-dist /usr/local/lib/php.ini
-
- You may edit your .ini file to set PHP options. If you prefer your
- php.ini in another location, use --with-config-file-path=/some/path in
- step 10.
-
- If you instead choose php.ini-recommended, be certain to read the list
- of changes within, as they affect how PHP behaves.
-
- 14. Edit your httpd.conf to load the PHP module. The path on the right hand
- side of the LoadModule statement must point to the path of the PHP
- module on your system. The make install from above may have already
- added this for you, but be sure to check.
-
- For PHP 4:
-
- LoadModule php4_module libexec/libphp4.so
-
- For PHP 5:
-
- LoadModule php5_module libexec/libphp5.so
-
- 15. And in the AddModule section of httpd.conf, somewhere under the
- ClearModuleList, add this:
-
- For PHP 4:
-
- AddModule mod_php4.c
-
- For PHP 5:
-
- AddModule mod_php5.c
-
- 16. Tell Apache to parse certain extensions as PHP. For example,
- let's have Apache parse the .php extension as PHP. You could
- have any extension(s) parse as PHP by simply adding more, with
- each separated by a space. We'll add .phtml to demonstrate.
-
- AddType application/x-httpd-php .php .phtml
-
- It's also common to setup the .phps extension to show highlighted PHP
- source, this can be done with:
-
- AddType application/x-httpd-php-source .phps
-
- 17. Use your normal procedure for starting the Apache server. (You must
- stop and restart the server, not just cause the server to reload by
- using a HUP or USR1 signal.)</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Alternatively, to install PHP as a static object:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.apache.example-static"
- ></A
- ><P
- ><B
- >Example 4-2.
- Installation Instructions (Static Module Installation for Apache) for PHP
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >1. gunzip -c apache_1.3.x.tar.gz | tar xf -
- 2. cd apache_1.3.x
- 3. ./configure
- 4. cd ..
-
- 5. gunzip -c php-4.x.y.tar.gz | tar xf -
- 6. cd php-4.x.y
- 7. ./configure --with-mysql --with-apache=../apache_1.3.x
- 8. make
- 9. make install
-
- 10. cd ../apache_1.3.x
-
- 11. ./configure --prefix=/www --activate-module=src/modules/php4/libphp4.a
- (The above line is correct! Yes, we know libphp4.a does not exist at this
- stage. It isn't supposed to. It will be created.)
-
- 12. make
- (you should now have an httpd binary which you can copy to your Apache bin dir if
- is is your first install then you need to "make install" as well)
-
- 13. cd ../php-4.x.y
- 14. cp php.ini-dist /usr/local/lib/php.ini
-
- 15. You can edit /usr/local/lib/php.ini file to set PHP options.
- Edit your httpd.conf or srm.conf file and add:
- AddType application/x-httpd-php .php</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Depending on your Apache install and Unix variant, there are many
- possible ways to stop and restart the server. Below are some typical
- lines used in restarting the server, for different apache/unix
- installations. You should replace <VAR
- CLASS="literal"
- >/path/to/</VAR
- > with
- the path to these applications on your systems.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN412"
- ></A
- ><P
- ><B
- >Example 4-3. Example commands for restarting Apache</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >1. Several Linux and SysV variants:
- /etc/rc.d/init.d/httpd restart
-
- 2. Using apachectl scripts:
- /path/to/apachectl stop
- /path/to/apachectl start
-
- 3. httpdctl and httpsdctl (Using OpenSSL), similar to apachectl:
- /path/to/httpsdctl stop
- /path/to/httpsdctl start
-
- 4. Using mod_ssl, or another SSL server, you may want to manually
- stop and start:
- /path/to/apachectl stop
- /path/to/apachectl startssl</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The locations of the apachectl and http(s)dctl binaries often
- vary. If your system has <VAR
- CLASS="literal"
- >locate</VAR
- > or
- <VAR
- CLASS="literal"
- >whereis</VAR
- > or <VAR
- CLASS="literal"
- >which</VAR
- > commands,
- these can assist you in finding your server control programs.
- </P
- ><P
- >
Different examples of compiling PHP for apache are as follows:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN420"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --with-apxs --with-pgsql</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This will create a <TT
- CLASS="filename"
- >libphp4.so</TT
- > shared
- library that is loaded into Apache using a LoadModule line in
- Apache's <TT
- CLASS="filename"
- >httpd.conf</TT
- > file. The PostgreSQL
- support is embedded into this <TT
- CLASS="filename"
- >libphp4.so</TT
- >
- library.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN427"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --with-apxs --with-pgsql=shared</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This will create a <TT
- CLASS="filename"
- >libphp4.so</TT
- > shared
- library for Apache, but it will also create a
- <TT
- CLASS="filename"
- >pgsql.so</TT
- > shared library that is loaded into
- PHP either by using the extension directive in
- <TT
- CLASS="filename"
- >php.ini</TT
- > file or by loading it explicitly in
- a script using the <A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- > function.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN435"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --with-apache=/path/to/apache_source --with-pgsql</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This will create a <TT
- CLASS="filename"
- >libmodphp4.a</TT
- > library, a
- <TT
- CLASS="filename"
- >mod_php4.c</TT
- > and some accompanying files and
- copy this into the <VAR
- CLASS="literal"
- >src/modules/php4</VAR
- > directory
- in the Apache source tree. Then you compile Apache using
- <VAR
- CLASS="literal"
- >--activate-module=src/modules/php4/libphp4.a</VAR
- >
- and the Apache build system will create
- <TT
- CLASS="filename"
- >libphp4.a</TT
- > and link it statically into the
- <TT
- CLASS="filename"
- >httpd</TT
- > binary. The PostgreSQL support is
- included directly into this <TT
- CLASS="filename"
- >httpd</TT
- > binary,
- so the final result here is a single <TT
- CLASS="filename"
- >httpd</TT
- >
- binary that includes all of Apache and all of PHP.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN447"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --with-apache=/path/to/apache_source --with-pgsql=shared</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Same as before, except instead of including PostgreSQL support
- directly into the final <TT
- CLASS="filename"
- >httpd</TT
- > you will get
- a <TT
- CLASS="filename"
- >pgsql.so</TT
- > shared library that you can load
- into PHP from either the <TT
- CLASS="filename"
- >php.ini</TT
- > file or
- directly using <A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- >.
- </P
- ><P
- >
When choosing to build PHP in different ways, you should consider
- the advantages and drawbacks of each method. Building as a shared
- object will mean that you can compile apache separately, and don't
- have to recompile everything as you add to, or change, PHP.
- Building PHP into apache (static method) means that PHP will
- load and run faster. For more information, see the Apache
- <A
- HREF="http://httpd.apache.org/docs/dso.html"
- TARGET="_top"
- >webpage on DSO support</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Apache's default <TT
- CLASS="filename"
- >httpd.conf</TT
- > currently ships with a section that looks
- like this:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN459"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- >User nobody
- Group "#-1"</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- Unless you change that to "Group nogroup" or something like that ("Group daemon" is
- also very common) PHP will not be able to open files.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Make sure you specify the installed version of apxs when using
- <VAR
- CLASS="option"
- >--with-apxs=/path/to/apxs</VAR
- >.
- You must NOT use the apxs version that is in the apache sources but the one
- that is actually installed on your system.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.apache2"
- >Apache 2.0 on Unix systems</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Apache 2.0 installs
- of PHP on Unix systems.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >We do not recommend using a threaded MPM
- in production with Apache2. Use the prefork MPM instead, or use Apache1. For information
- on why, read the following
- <A
- HREF="#faq.installation.apache2"
- >FAQ entry</A
- ></P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
You are highly encouraged to take a look at the
- <A
- HREF="http://httpd.apache.org/docs-2.0/"
- TARGET="_top"
- >Apache Documentation</A
- > to get
- a basic understanding of the Apache 2.0 Server.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >PHP and Apache 2.0.x compatibility notes: </B
- >
- The following versions of PHP are known to work with the most recent
- version of Apache 2.0.x:
- <P
- ></P
- ><UL
- COMPACT="COMPACT"
- ><LI
- ><SPAN
- >
PHP 4.3.0 or later available at
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >http://www.php.net/downloads.php</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
the latest stable development version.
- Get the source code <A
- HREF="http://snaps.php.net/php4-latest.tar.gz"
- TARGET="_top"
- >
http://snaps.php.net/php4-latest.tar.gz</A
- > or download binaries
- for Windows <A
- HREF="http://snaps.php.net/win32/php4-win32-latest.zip"
- TARGET="_top"
- >
http://snaps.php.net/win32/php4-win32-latest.zip</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
a prerelease version downloadable from
- <A
- HREF="http://qa.php.net/"
- TARGET="_top"
- >http://qa.php.net/</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
you have always the option to obtain PHP through
- <A
- HREF="http://www.php.net/anoncvs.php"
- TARGET="_top"
- >anonymous CVS</A
- >.
- </SPAN
- ></LI
- ></UL
- >
- These versions of PHP are compatible to Apache 2.0.40 and later.
- </P
- ><P
- >
Apache 2.0 <VAR
- CLASS="literal"
- >SAPI</VAR
- >-support started with PHP 4.2.0.
- PHP 4.2.3 works with Apache 2.0.39, don't use any other version of Apache with
- PHP 4.2.3. However, the recommended setup is to use PHP 4.3.0 or later with
- the most recent version of Apache2.
- </P
- ><P
- >
All mentioned versions of PHP will work still with
- Apache 1.3.x.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Download the most recent version of <A
- HREF="http://www.apache.org/"
- TARGET="_top"
- >
Apache 2.0</A
- > and a fitting PHP version from the above mentioned places.
- This quick guide covers only the basics to get started with Apache 2.0
- and PHP. For more information read the
- <A
- HREF="http://httpd.apache.org/docs-2.0/"
- TARGET="_top"
- >Apache Documentation</A
- >.
- The version numbers have been omitted here, to ensure the
- instructions are not incorrect. You will need to replace the
- 'NN' here with the correct values from your files.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN495"
- ></A
- ><P
- ><B
- >Example 4-4.
- Installation Instructions (Apache 2 Shared Module Version)
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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
-
- Now you have Apache 2.0.NN available under /usr/local/apache2,
- configured with loadable module support and the standard MPM prefork.
- To test the installation use your normal procedure for starting
- the Apache server, e.g.:
- /usr/local/apache2/bin/apachectl start
- and stop the server to go on with the configuration for PHP:
- /usr/local/apache2/bin/apachectl stop.
-
- 9. cd ../php-NN
-
- 10. Now, configure your PHP. This is where you customize your PHP
- with various options, like which extensions will be enabled. Do a
- ./configure --help for a list of available options. In our example
- we'll do a simple configure with Apache 2 and MySQL support. Your
- path to apxs may differ, in fact, the binary may even be named apxs2 on
- your system.
-
- ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql
-
- 11. make
- 12. make install
-
- If you decide to change your configure options after installation,
- you only need to repeat the last three steps. You only need to
- restart apache for the new module to take effect. A recompile of
- Apache is not needed.
-
- Note that unless told otherwise, 'make install' will also install PEAR,
- various PHP tools such as phpize, install the PHP CLI, and more.
-
- 13. Setup your php.ini
-
- cp php.ini-dist /usr/local/lib/php.ini
-
- You may edit your .ini file to set PHP options. If you prefer having
- php.ini in another location, use --with-config-file-path=/some/path in
- step 10.
-
- If you instead choose php.ini-recommended, be certain to read the list
- of changes within, as they affect how PHP behaves.
-
- 14. Edit your httpd.conf to load the PHP module. The path on the right hand
- side of the LoadModule statement must point to the path of the PHP
- module on your system. The make install from above may have already
- added this for you, but be sure to check.
-
- For PHP 4:
-
- LoadModule php4_module libexec/libphp4.so
-
- For PHP 5:
-
- LoadModule php5_module libexec/libphp5.so
-
- 15. Tell Apache to parse certain extensions as PHP. For example,
- let's have Apache parse the .php extension as PHP. You could
- have any extension(s) parse as PHP by simply adding more, with
- each separated by a space. We'll add .phtml to demonstrate.
-
- AddType application/x-httpd-php .php .phtml
-
- It's also common to setup the .phps extension to show highlighted PHP
- source, this can be done with:
-
- AddType application/x-httpd-php-source .phps
-
- 16. Use your normal procedure for starting the Apache server, e.g.:
-
- /usr/local/apache2/bin/apachectl start</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Following the steps above you will have a running Apache 2.0 with
- support for PHP as <VAR
- CLASS="literal"
- >SAPI</VAR
- > module.
- Of course there are many more configuration options available for both,
- Apache and PHP. For more information use
- <B
- CLASS="command"
- >./configure --help</B
- > in the corresponding source
- tree. In case you wish to build a multithreaded version of Apache 2.0
- you must overwrite the standard MPM-Module <TT
- CLASS="filename"
- >prefork</TT
- >
- either with <TT
- CLASS="filename"
- >worker</TT
- > or <TT
- CLASS="filename"
- >perchild</TT
- >.
- To do so append to your configure line in step 6 above either the option
- <VAR
- CLASS="option"
- >--with-mpm=worker</VAR
- > or
- <VAR
- CLASS="option"
- >--with-mpm=perchild</VAR
- >. Take care about
- the consequences and understand what you are doing. For more information
- read the Apache documentation about the <A
- HREF="http://httpd.apache.org/docs-2.0/mpm.html"
- TARGET="_top"
- >
MPM-Modules</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you want to use content negotiation, read
- <A
- HREF="#faq.installation.apache.multiviews"
- >related FAQ</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- To build a multithreaded version of Apache your system must support threads.
- This also implies to build PHP with experimental
- Zend Thread Safety (ZTS). Therefore not all extensions might be available.
- The recommended setup is to build Apache with the standard
- <TT
- CLASS="filename"
- >prefork</TT
- > MPM-Module.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.caudium"
- >Caudium</A
- ></H2
- ><P
- >
PHP 4 can be built as a Pike module for the
- <A
- HREF="http://caudium.net/"
- TARGET="_top"
- >Caudium webserver</A
- >.
- Note that this is not supported with PHP 3. Follow the simple
- instructions below to install PHP 4 for Caudium.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.caudium.instructions"
- ></A
- ><P
- ><B
- >Example 4-5. Caudium Installation Instructions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >1. Make sure you have Caudium installed prior to attempting to
- install PHP 4. For PHP 4 to work correctly, you will need Pike
- 7.0.268 or newer. For the sake of this example we assume that
- Caudium is installed in /opt/caudium/server/.
- 2. Change directory to php-x.y.z (where x.y.z is the version number).
- 3. ./configure --with-caudium=/opt/caudium/server
- 4. make
- 5. make install
- 6. Restart Caudium if it's currently running.
- 7. Log into the graphical configuration interface and go to the
- virtual server where you want to add PHP 4 support.
- 8. Click Add Module and locate and then add the PHP 4 Script Support module.
- 9. If the documentation says that the 'PHP 4 interpreter isn't
- available', make sure that you restarted the server. If you did
- check /opt/caudium/logs/debug/default.1 for any errors related to
- <filename>PHP4.so</filename>. Also make sure that
- <filename>caudium/server/lib/[pike-version]/PHP4.so</filename>
- is present.
- 10. Configure the PHP Script Support module if needed.</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
You can of course compile your Caudium module with support for the
- various extensions available in PHP 4. See the reference pages
- for extension specific configure options.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- When compiling PHP 4 with MySQL support you must make sure that
- the normal MySQL client code is used. Otherwise there might be
- conflicts if your Pike already has MySQL support. You do this by
- specifying a MySQL install directory the
- <VAR
- CLASS="option"
- >--with-mysql</VAR
- > option.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.fhttpd"
- >fhttpd related notes</A
- ></H2
- ><P
- >
To build PHP as an fhttpd module, answer "yes" to "Build as an
- fhttpd module?" (the <A
- HREF="#configure.with-fhttpd"
- >
--with-fhttpd</A
- >=<VAR
- CLASS="replaceable"
- >DIR</VAR
- >
- option to configure) and specify the fhttpd source base
- directory. The default directory is <TT
- CLASS="filename"
- >/usr/local/src/fhttpd</TT
- >. If you are
- running fhttpd, building PHP as a module will give better
- performance, more control and remote execution capability.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Support for fhttpd is no longer available as of PHP 4.3.0.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.sun"
- >Sun, iPlanet and Netscape servers on Sun Solaris</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Sun Java System Web Server,
- Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Sun Solaris.
- </P
- ><P
- >
From PHP 4.3.3 on you can use PHP scripts with the
- <A
- HREF="#ref.nsapi"
- >NSAPI module</A
- > to
- <A
- HREF="#install.unix.sun.specialpages"
- >generate custom directory
- listings and error pages</A
- >. Additional functions for Apache
- compatibility are also available. For support in current webservers read
- the <A
- HREF="#install.unix.sun.notes"
- >note about subrequests</A
- >.
- </P
- ><P
- >
You can find more information about setting up PHP for the Netscape
- Enterprise Server (NES) here:
- <A
- HREF="http://benoit.noss.free.fr/php/install-php4.html"
- TARGET="_top"
- >http://benoit.noss.free.fr/php/install-php4.html</A
- >
- </P
- ><P
- >
To build PHP with Sun JSWS/Sun ONE WS/iPlanet/Netscape webservers,
- enter the proper install directory for the
- <A
- HREF="#configure.with-nsapi"
- >--with-nsapi=[DIR]</A
- >
- option. The default directory is usually
- <TT
- CLASS="filename"
- >/opt/netscape/suitespot/</TT
- >.
- Please also read <TT
- CLASS="filename"
- >/php-xxx-version/sapi/nsapi/nsapi-readme.txt</TT
- >.
- </P
- ><P
- >
<P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
Install the following packages from <A
- HREF="http://www.sunfreeware.com/"
- TARGET="_top"
- >
http://www.sunfreeware.com/</A
- > or another download site:
- <P
- ></P
- ><TABLE
- BORDER="0"
- ><TBODY
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >autoconf-2.13</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >automake-1.4</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >bison-1_25-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >flex-2_5_4a-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >gcc-2_95_2-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >gzip-1.2.4-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >m4-1_4-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >make-3_76_1-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- >
<TT
- CLASS="filename"
- >mysql-3.23.24-beta</TT
- > (if you want mysql support)
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >perl-5_005_03-sol26-sparc-local</TT
- ></TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="filename"
- >tar-1.13</TT
- > (GNU tar)</TD
- ></TR
- ></TBODY
- ></TABLE
- ><P
- ></P
- >
- </P
- ></LI
- ><LI
- ><P
- >
Make sure your path includes the proper directories
- <VAR
- CLASS="literal"
- >PATH=.:/usr/local/bin:/usr/sbin:/usr/bin:/usr/ccs/bin</VAR
- >
- and make it available to your system <KBD
- CLASS="userinput"
- >export PATH</KBD
- >.
- </P
- ></LI
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >gunzip php-x.x.x.tar.gz</KBD
- > (if you have a .gz dist,
- otherwise go to 4).
- </P
- ></LI
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >tar xvf php-x.x.x.tar</KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
Change to your extracted PHP directory:
- <KBD
- CLASS="userinput"
- >cd ../php-x.x.x </KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
For the following step, make sure
- <TT
- CLASS="filename"
- >/opt/netscape/suitespot/</TT
- > is
- where your netscape server is installed. Otherwise, change to the
- correct path and run:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --with-mysql=/usr/local/mysql \
- --with-nsapi=/opt/netscape/suitespot/ \
- --enable-libgcc</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Run <B
- CLASS="command"
- >make</B
- > followed by <B
- CLASS="command"
- >make install</B
- >.
- </P
- ></LI
- ></OL
- >
- </P
- ><P
- >
After performing the base install and reading the appropriate readme file,
- you may need to perform some additional configuration steps.
- </P
- ><DIV
- CLASS="formalpara"
- ><P
- ><B
- >Configuration Instructions for Sun/iPlanet/Netscape. </B
- >
- Firstly you may need to add some paths to the <VAR
- CLASS="varname"
- >LD_LIBRARY_PATH</VAR
- >
- environment for the server to find all the shared libs. This can best done
- in the start script for your webserver. The start script is often located
- in: <TT
- CLASS="filename"
- >/path/to/server/https-servername/start</TT
- >.
- You may also need to edit the configuration files that are
- located in: <TT
- CLASS="filename"
- >/path/to/server/https-servername/config/</TT
- >.
- <P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
Add the following line to <TT
- CLASS="filename"
- >mime.types</TT
- > (you can do
- that by the administration server):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >type=magnus-internal/x-httpd-php exts=php</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Edit <TT
- CLASS="filename"
- >magnus.conf</TT
- > (for servers >= 6) or
- <TT
- CLASS="filename"
- >obj.conf</TT
- > (for servers < 6) and add the following,
- shlib will vary depending on your system, it will be something like
- <TT
- CLASS="filename"
- >/opt/netscape/suitespot/bin/libphp4.so</TT
- >. You should
- place the following lines after <VAR
- CLASS="literal"
- >mime types init</VAR
- >.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >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"]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- (PHP >= 4.3.3) The <VAR
- CLASS="literal"
- >php_ini</VAR
- > parameter is
- optional but with it you can place your <TT
- CLASS="filename"
- >php.ini</TT
- > in your
- webserver config directory.
- </P
- ></LI
- ><LI
- ><P
- >
Configure the default object in <TT
- CLASS="filename"
- >obj.conf</TT
- >
- (for virtual server classes [version 6.0+] in
- their <TT
- CLASS="filename"
- >vserver.obj.conf</TT
- >):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- >
- (PHP >= 4.3.3) As additional parameters you can add some special
- <TT
- CLASS="filename"
- >php.ini</TT
- >-values, for example you can set a
- <VAR
- CLASS="literal"
- >docroot="/path/to/docroot"</VAR
- > specific
- to the context <VAR
- CLASS="literal"
- >php4_execute</VAR
- > is called. For boolean
- ini-keys please use 0/1 as value, not
- <VAR
- CLASS="literal"
- >"On","Off",...</VAR
- >
- (this will not work correctly), e.g.
- <VAR
- CLASS="literal"
- >zlib.output_compression=1</VAR
- > instead of
- <VAR
- CLASS="literal"
- >zlib.output_compression="On"</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
This is only needed if you want to configure a directory that only consists of
- PHP scripts (same like a <TT
- CLASS="filename"
- >cgi-bin</TT
- > directory):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><Object name="x-httpd-php">
- ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
- Service fn=php4_execute [inikey=value inikey=value ...]
- </Object></PRE
- ></TD
- ></TR
- ></TABLE
- >
- After that you can configure a directory in the Administration server and assign it
- the style <VAR
- CLASS="literal"
- >x-httpd-php</VAR
- >. All files in it will get executed as PHP.
- This is nice to hide PHP usage by renaming files to <TT
- CLASS="filename"
- >.html</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
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:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><Object name="default">
- AuthTrans fn=php4_auth_trans
- .
- .
- .
- </Object></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
To use PHP Authentication on a single directory, add the following:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><Object ppath="d:\path\to\authenticated\dir\*">
- AuthTrans fn=php4_auth_trans
- </Object></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ></OL
- >
- </P
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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").
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.sun.phpini"
- >CGI environment and recommended modifications in php.ini</A
- ></H3
- ><P
- >
Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE
- WS/iPlanet/Netscape is a multithreaded web server. Because of that all
- requests are running in the same process space (the space of the webserver
- itself) and this space has only one environment. If you want to get CGI
- variables like <VAR
- CLASS="literal"
- >PATH_INFO</VAR
- >, <VAR
- CLASS="literal"
- >HTTP_HOST</VAR
- >
- etc. it is not the correct way to try this in the old PHP 3.x way with
- <A
- HREF="#function.getenv"
- ><B
- CLASS="function"
- >getenv()</B
- ></A
- > or a similar way (register globals to
- environment, <VAR
- CLASS="literal"
- >$_ENV</VAR
- >). You would only get the environment
- of the running webserver without any valid CGI variables!
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Why are there (invalid) CGI variables in the environment?
- </P
- ><P
- >
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 command line as root user and start it manually - you will see
- there are no CGI-like environment variables.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Simply change your scripts to get CGI variables in the correct way for
- PHP 4.x by using the superglobal <VAR
- CLASS="literal"
- >$_SERVER</VAR
- >. If you have
- older scripts which use <VAR
- CLASS="literal"
- >$HTTP_HOST</VAR
- >, etc., you should turn
- on <VAR
- CLASS="literal"
- >register_globals</VAR
- > in <TT
- CLASS="filename"
- >php.ini</TT
- > and change the variable
- order too (important: remove <VAR
- CLASS="literal"
- >"E"</VAR
- > from it,
- because you do not need the environment here):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >variables_order = "GPCS"
- register_globals = On</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.sun.specialpages"
- >Special use for error pages or self-made directory listings (PHP >= 4.3.3)</A
- ></H3
- ><P
- >
You can use PHP to generate the error pages for <VAR
- CLASS="literal"
- >"404 Not Found"</VAR
- >
- or similar. Add the following line to the object in <TT
- CLASS="filename"
- >obj.conf</TT
- > for
- every error page you want to overwrite:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- where <VAR
- CLASS="literal"
- >XXX</VAR
- > is the HTTP error code. Please delete
- any other <VAR
- CLASS="literal"
- >Error</VAR
- > directives which could interfere with yours.
- If you want to place a page for all errors that could exist, leave
- the <VAR
- CLASS="literal"
- >code</VAR
- > parameter out. Your script can get the HTTP status code
- with <VAR
- CLASS="literal"
- >$_SERVER['ERROR_TYPE']</VAR
- >.
- </P
- ><P
- >
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
- <VAR
- CLASS="literal"
- >type="magnus-internal/directory"</VAR
- >
- in <TT
- CLASS="filename"
- >obj.conf</TT
- > with the following:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- For both error and directory listing pages the original URI and
- translated URI are in the variables <VAR
- CLASS="literal"
- >$_SERVER['PATH_INFO']</VAR
- > and
- <VAR
- CLASS="literal"
- >$_SERVER['PATH_TRANSLATED']</VAR
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.sun.notes"
- >Note about <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > and subrequests (PHP >= 4.3.3)</A
- ></H3
- ><P
- >
The NSAPI module now supports the <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > function
- (alias: <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- >)
- to make subrequests on the webserver and insert the result in the webpage.
- This function uses some undocumented features from the NSAPI library.
- On Unix the module automatically looks for the needed functions and uses
- them if available. If not, <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > is disabled.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- But be warned: Support for <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > is EXPERIMENTAL!!!
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.commandline"
- >CGI and commandline setups</A
- ></H2
- ><P
- >
The default is to build PHP as a CGI program. This creates a
- commandline interpreter, which can be used for CGI processing, or
- for non-web-related PHP scripting. If you are running a web
- server PHP has module support for, you should generally go for
- that solution for performance reasons. However, the CGI version
- enables users to run different PHP-enabled pages under
- different user-ids.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
As of PHP 4.3.0, some important additions have happened to PHP. A new
- SAPI named CLI also exists and it has the same name as the CGI binary.
- What is installed at <VAR
- CLASS="literal"
- >{PREFIX}/bin/php</VAR
- > depends on your
- configure line and this is described in detail in the manual section
- named <A
- HREF="#features.commandline"
- >Using PHP from the command
- line</A
- >. For further details please read that section of the manual.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.commandline.testing"
- >Testing</A
- ></H3
- ><P
- >
If you have built PHP as a CGI program, you may test your build
- by typing <B
- CLASS="command"
- >make test</B
- >. It is always a good idea
- to test your build. This way you may catch a problem with PHP on
- your platform early instead of having to struggle with it later.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.commandline.benchmarking"
- >Benchmarking</A
- ></H3
- ><P
- >
If you have built PHP 3 as a CGI program, you may benchmark your
- build by typing <B
- CLASS="command"
- >make bench</B
- >. Note that if
- <A
- HREF="#ini.safe-mode"
- >safe mode</A
- > is on by default, the benchmark may not be able to finish if
- it takes longer then the 30 seconds allowed. This is because the
- <A
- HREF="#function.set-time-limit"
- ><B
- CLASS="function"
- >set_time_limit()</B
- ></A
- > can not be used in
- <A
- HREF="#ini.safe-mode"
- >safe mode</A
- >. Use the <A
- HREF="#ini.max-execution-time"
- >max_execution_time</A
- >
- configuration setting to control this time for your own
- scripts. <B
- CLASS="command"
- >make bench</B
- > ignores the <A
- HREF="#configuration.file"
- >configuration file</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <B
- CLASS="command"
- >make bench</B
- > is only available for PHP 3.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.commandline.using-variables"
- >Using Variables</A
- ></H3
- ><P
- >
Some <A
- HREF="#reserved.variables.server"
- >server supplied
- environment variables</A
- > are not defined in the
- current <A
- HREF="http://hoohoo.ncsa.uiuc.edu/cgi/env.html"
- TARGET="_top"
- >CGI/1.1 specification</A
- >.
- Only the following variables are defined there: <VAR
- CLASS="varname"
- >AUTH_TYPE</VAR
- >,
- <VAR
- CLASS="varname"
- >CONTENT_LENGTH</VAR
- >, <VAR
- CLASS="varname"
- >CONTENT_TYPE</VAR
- >,
- <VAR
- CLASS="varname"
- >GATEWAY_INTERFACE</VAR
- >, <VAR
- CLASS="varname"
- >PATH_INFO</VAR
- >,
- <VAR
- CLASS="varname"
- >PATH_TRANSLATED</VAR
- >, <VAR
- CLASS="varname"
- >QUERY_STRING</VAR
- >,
- <VAR
- CLASS="varname"
- >REMOTE_ADDR</VAR
- >, <VAR
- CLASS="varname"
- >REMOTE_HOST</VAR
- >,
- <VAR
- CLASS="varname"
- >REMOTE_IDENT</VAR
- >, <VAR
- CLASS="varname"
- >REMOTE_USER</VAR
- >,
- <VAR
- CLASS="varname"
- >REQUEST_METHOD</VAR
- >, <VAR
- CLASS="varname"
- >SCRIPT_NAME</VAR
- >,
- <VAR
- CLASS="varname"
- >SERVER_NAME</VAR
- >, <VAR
- CLASS="varname"
- >SERVER_PORT</VAR
- >,
- <VAR
- CLASS="varname"
- >SERVER_PROTOCOL</VAR
- >, and <VAR
- CLASS="varname"
- >SERVER_SOFTWARE</VAR
- >.
- Everything else should be treated as 'vendor extensions'.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.hpux"
- >HP-UX specific installation notes</A
- ></H2
- ><P
- >
This section contains notes and hints specific to installing PHP
- on HP-UX systems. (Contributed by paul_mckay at clearwater-it dot co dot
- uk).
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- These tips were written for PHP 4.0.4 and Apache 1.3.9.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
You need gzip, download a binary distribution from
- <TT
- CLASS="filename"
- >http://hpux.connect.org.uk/ftp/hpux/Gnu/gzip-1.2.4a/gzip-1.2.4a-sd-10.20.depot.Z</TT
- >
- uncompress the file and install using swinstall.
- </P
- ></LI
- ><LI
- ><P
- >
You need gcc, download a binary distribution from
- <TT
- CLASS="filename"
- >http://gatekeep.cs.utah.edu/ftp/hpux/Gnu/gcc-2.95.2/gcc-2.95.2-sd-10.20.depot.gz</TT
- >.
- uncompress this file and install gcc using swinstall.
- </P
- ></LI
- ><LI
- ><P
- >
You need the GNU binutils, you can download a binary distribution from
- <TT
- CLASS="filename"
- >http://hpux.connect.org.uk/ftp/hpux/Gnu/binutils-2.9.1/binutils-2.9.1-sd-10.20.depot.gz</TT
- >.
- uncompress this file and install binutils using swinstall.
- </P
- ></LI
- ><LI
- ><P
- >
You now need bison, you can download a binary distribution from
- <TT
- CLASS="filename"
- >http://hpux.connect.org.uk/ftp/hpux/Gnu/bison-1.28/bison-1.28-sd-10.20.depot.gz</TT
- >,
- install as above.
- </P
- ></LI
- ><LI
- ><P
- >
You now need flex, you need to download the source from one of the
- http://www.gnu.org mirrors. It is in the non-gnu directory of the ftp
- site. Download the file, <B
- CLASS="command"
- >gunzip</B
- >, then
- <B
- CLASS="command"
- >tar -xvf</B
- > it. Go into the newly created flex directory
- and run <B
- CLASS="command"
- >./configure</B
- >, followed by
- <B
- CLASS="command"
- >make</B
- >, and then <B
- CLASS="command"
- >make install</B
- >.
- </P
- ><P
- >
If you have errors here, it's probably because gcc etc. are not in your
- PATH so add them to your PATH.
- </P
- ></LI
- ><LI
- ><P
- >
Download the PHP and apache sources.
- </P
- ></LI
- ><LI
- ><P
- >
<B
- CLASS="command"
- >gunzip</B
- > and <B
- CLASS="command"
- >tar -xvf</B
- > them. We
- need to hack a couple of files so that they can compile OK.
- </P
- ></LI
- ><LI
- ><P
- >
Firstly the configure file needs to be hacked because it seems to lose
- track of the fact that you are a hpux machine, there will be a better
- way of doing this but a cheap and cheerful hack is to put
- <VAR
- CLASS="literal"
- >lt_target=hpux10.20</VAR
- > on line 47286 of the configure
- script.
- </P
- ></LI
- ><LI
- ><P
- >
Next, the Apache GuessOS file needs to be hacked. Under
- <TT
- CLASS="filename"
- >apache_1.3.9/src/helpers</TT
- > change line 89 from <VAR
- CLASS="literal"
- >echo
- "hp${HPUXMACH}-hpux${HPUXVER}"; exit 0</VAR
- > to: <VAR
- CLASS="literal"
- >echo
- "hp${HPUXMACH}-hp-hpux${HPUXVER}"; exit 0</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
You cannot install PHP as a shared object under HP-UX so you must
- compile it as a static, just follow the instructions at the Apache
- page.
- </P
- ></LI
- ><LI
- ><P
- >
PHP and Apache should have compiled OK, but Apache won't start. you
- need to create a new user for Apache, e.g. www, or apache. You then
- change lines 252 and 253 of the <TT
- CLASS="filename"
- >conf/httpd.conf</TT
- > in
- Apache so that instead of
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >User nobody
- Group nogroup</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
you have something like
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >User www
- Group sys</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This is because you can't run Apache as nobody under hp-ux. Apache and
- PHP should then work.
- </P
- ></LI
- ></OL
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.openbsd"
- >OpenBSD installation notes</A
- ></H2
- ><P
- >
This section contains notes and hints specific to installing
- PHP on <A
- HREF="http://www.openbsd.org/"
- TARGET="_top"
- >OpenBSD 3.6</A
- >.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.openbsd.packages"
- >Using Binary Packages</A
- ></H3
- ><P
- >
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.
- </P
- ><P
- >
The main package you need to install is <TT
- CLASS="filename"
- >php4-core-4.3.8.tgz</TT
- >,
- which contains the basic engine (plus gettext and iconv). Next, take a look
- at the module packages, such as <TT
- CLASS="filename"
- >php4-mysql-4.3.8.tgz</TT
- >
- or <TT
- CLASS="filename"
- >php4-imap-4.3.8.tgz</TT
- >. You need to use the <B
- CLASS="command"
- >phpxs</B
- >
- command to activate and deactivate these modules in your <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.openbsd.ports.example"
- ></A
- ><P
- ><B
- >Example 4-6. OpenBSD Package Install Example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- ># pkg_add php4-core-4.3.8.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.8.tgz
- # /usr/local/sbin/phpxs -a mysql
- (add in imap)
- # pkg_add php4-imap-4.3.8.tgz
- # /usr/local/sbin/phpxs -a imap
- (remove mysql as a test)
- # pkg_delete php4-mysql-4.3.8
- # /usr/local/sbin/phpxs -r mysql
- (install the PEAR libraries)
- # pkg_add php4-pear-4.3.8.tgz</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Read the <A
- HREF="http://www.openbsd.org/cgi-bin/man.cgi?query=packages"
- TARGET="_top"
- >packages(7)</A
- >
- manual page for more information about binary packages on OpenBSD.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.openbsd.ports"
- >Using Ports</A
- ></H3
- ><P
- >
You can also compile up PHP from source using the <A
- HREF="http://www.openbsd.org/ports.html"
- TARGET="_top"
- >ports tree</A
- >.
- 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 <B
- CLASS="command"
- >no_*</B
- > FLAVOR. For example, to skip building
- the imap module, set the FLAVOR to <B
- CLASS="command"
- >no_imap</B
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.openbsd.faq"
- >Common Problems</A
- ></H3
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >The default install of Apache runs inside a
- <A
- HREF="http://www.openbsd.org/cgi-bin/man.cgi?query=chroot"
- TARGET="_top"
- >chroot(2) jail</A
- >, which will restrict PHP scripts to
- accessing files under <TT
- CLASS="filename"
- >/var/www</TT
- >. You will therefore need to create a
- <TT
- CLASS="filename"
- >/var/www/tmp</TT
- > 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 <TT
- CLASS="filename"
- >localhost</TT
- > interface. If you use network functions,
- some files from <TT
- CLASS="filename"
- >/etc</TT
- > such as <TT
- CLASS="filename"
- >/etc/resolv.conf</TT
- > and
- <TT
- CLASS="filename"
- >/etc/services</TT
- > will need to be moved into <TT
- CLASS="filename"
- >/var/www/etc</TT
- >.
- 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 <A
- HREF="http://www.openbsd.org/faq/faq10.html#httpdchroot"
- TARGET="_top"
- >OpenBSD FAQ</A
- >.
- </P
- ></LI
- ><LI
- ><P
- >
The OpenBSD 3.6 package for the <A
- HREF="http://www.boutell.com/gd/"
- TARGET="_top"
- >gd</A
- > extension requires
- XFree86 to be installed. If you do not wish to use some of the font features that
- require X11, install the <TT
- CLASS="filename"
- >php4-gd-4.3.8-no_x11.tgz</TT
- > package instead.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.openbsd.older"
- >Older Releases</A
- ></H3
- ><P
- >
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).
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.solaris"
- >Solaris specific installation tips</A
- ></H2
- ><P
- >
This section contains notes and hints specific to installing
- PHP on Solaris systems.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.solaris.required"
- >Required software</A
- ></H3
- ><P
- >
Solaris installs often lack C compilers and their related tools.
- Read <A
- HREF="#faq.installation.needgnu"
- >this FAQ</A
- >
- for information on why using GNU versions for some of these
- tools is necessary. The required software is as follows:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
gcc (recommended, other C compilers may work)
- </P
- ></LI
- ><LI
- ><P
- >
make
- </P
- ></LI
- ><LI
- ><P
- >
flex
- </P
- ></LI
- ><LI
- ><P
- >
bison
- </P
- ></LI
- ><LI
- ><P
- >
m4
- </P
- ></LI
- ><LI
- ><P
- >
autoconf
- </P
- ></LI
- ><LI
- ><P
- >
automake
- </P
- ></LI
- ><LI
- ><P
- >
perl
- </P
- ></LI
- ><LI
- ><P
- >
gzip
- </P
- ></LI
- ><LI
- ><P
- >
tar
- </P
- ></LI
- ><LI
- ><P
- >
GNU sed
- </P
- ></LI
- ></UL
- >
- In addition, you will need to install (and possibly compile) any
- additional software specific to your configuration, such as Oracle
- or MySQL.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.solaris.packages"
- >Using Packages</A
- ></H3
- ><P
- >
You can simplify the Solaris install process by using pkgadd to
- install most of your needed components.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.unix.gentoo"
- >Gentoo installation notes</A
- ></H2
- ><P
- >
This section contains notes and hints specific to installing
- PHP on <A
- HREF="http://www.gentoo.org/"
- TARGET="_top"
- >Gentoo Linux</A
- >.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.gentoo.portage"
- >Using Portage (emerge)</A
- ></H3
- ><P
- >
While you can just download the PHP source and compile it yourself,
- using Gentoo's packaging system is the simplest and cleanest
- method of installing PHP. If you are not familiar with building
- software on Linux, this is the way to go.
- </P
- ><P
- >
If you have built your Gentoo system so far, you are probably used
- to Portage already. Installing Apache and PHP is no different than
- the other system tools.
- </P
- ><P
- >
The first decision you need to make is whether you want to install
- Apache 1.3.x or Apache 2.x. While both can be used with PHP, the
- steps given bellow will use Apache 1.3.x. Another thing to consider
- is whether your local Portage tree is up to date. If you have not
- updated it recently, you need to run <B
- CLASS="command"
- >emerge sync</B
- >
- before anything else. This way, you will be using the most recent
- stable version of Apache and PHP.
- </P
- ><P
- >
Now that everything is in place, you can use the following example
- to install Apache and PHP:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.gentoo.portage.example"
- ></A
- ><P
- ><B
- >Example 4-7. Gentoo Install Example with Apache 1.3</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- ># emerge \<apache-2
- # USE="-*" emerge php mod_php
- # ebuild /var/db/pkg/dev-php/mod_php-<your PHP version>/mod_php-<your PHP version>.ebuild config
- # nano /etc/conf.d/apache
- Add "-D PHP4" to APACHE_OPTS
-
- # rc-update add apache default
- # /etc/init.d/apache start</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
You can read more about emerge in the excellent
- <A
- HREF="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2&chap=1"
- TARGET="_top"
- >Portage Manual</A
- > provided
- on the Gentoo website.
- </P
- ><P
- >
If you need to use Apache 2, you can simply use <B
- CLASS="command"
- >emerge apache</B
- >
- in the last example.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.gentoo.config"
- >Better control on configuration</A
- ></H3
- ><P
- >
In the last section, PHP was emerged without any activated modules.
- As of this writing, the only module activated by default with Portage
- is XML which is needed by <A
- HREF="http://pear.php.net/"
- TARGET="_top"
- >PEAR</A
- >.
- This may not be what you want and you will soon discover that you need
- more activated modules, like MySQL, gettext, GD, etc.
- </P
- ><P
- >
When you compile PHP from source yourself, you need to activate modules
- via the <B
- CLASS="command"
- >configure</B
- > command. With Gentoo, you can simply
- provide USE flags which will be passed to the configure script automatically.
- To see which USE flags to use with emerge, you can try:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.gentoo.config.example"
- ></A
- ><P
- ><B
- >Example 4-8. Getting the list of valid USE flags</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- ># USE="-*" emerge -pv php
-
- [ebuild N ] dev-php/php-4.3.6-r1 -X -berkdb -crypt -curl -debug -doc
- -fdftk -firebird -flash -freetds -gd -gd-external -gdbm -gmp -hardenedphp
- -imap -informix -ipv6 -java -jpeg -kerberos -ldap -mcal -memlimit -mssql
- -mysql -ncurses -nls -oci8 -odbc -pam -pdflib -png -postgres -qt -readline
- -snmp -spell -ssl -tiff -truetype -xml2 -yaz 3,876 kB</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
As you can see from the last output, PHP considers a lot of USE flags.
- Look at them closely and choose what you need. If you choose a flag and
- you do not have the proper libraries, Portage will compile them for you.
- It is a good idea to use <B
- CLASS="command"
- >emerge -pv</B
- > again to see what
- Portage will compile in accordance to your USE flags. As an example,
- if you do not have X installed and you choose to include X in the USE
- flags, Portage will compile X prior to PHP, which can take a couple
- of hours.
- </P
- ><P
- >
If you choose to compile PHP with MySQL, cURL and GD support, the command
- will look something like this:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="install.unix.gentoo.config.example2"
- ></A
- ><P
- ><B
- >Example 4-9. Install PHP with USE flags</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- ># USE="-* curl mysql gd" emerge php mod_php</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
As in the last example, do not forget to emerge php as well as mod_php.
- php is responsible for the command line version of PHP as mod_php is
- for the Apache module version of PHP.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.unix.gentoo.faq"
- >Common Problems</A
- ></H3
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
If you see the PHP source instead of the result the script should
- produce, you have probably forgot to edit <TT
- CLASS="filename"
- >/etc/conf.d/apache</TT
- >.
- Apache needs to be started with the -D PHP4 flag. To see if the flag is
- present, you should be able to see it when using
- <B
- CLASS="command"
- >ps ax | grep apache</B
- > while Apache is running.
- </P
- ></LI
- ><LI
- ><P
- >
Due to slotting problems, you might end up with more than one version
- of PHP installed on your system. If this is the case, you need to unmerge
- the old versions manually by using
- <B
- CLASS="command"
- >emerge unmerge mod_php-<old version></B
- >.
- </P
- ></LI
- ><LI
- ><P
- >
If you cannot emerge PHP because of Java, try putting <B
- CLASS="command"
- >-*</B
- >
- in front of your USE flags like in the above examples.
- </P
- ></LI
- ><LI
- ><P
- >
If you are having problems configuring Apache and PHP, you can always
- search the <A
- HREF="http://forums.gentoo.org/"
- TARGET="_top"
- >Gentoo Forums</A
- >.
- Try searching with the keywords "Apache PHP".
- </P
- ></LI
- ></UL
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.macosx"
- >Chapter 5. Installation on Mac OS X</A
- ></H1
- ><P
- >
This section contains notes and hints specific to installing
- PHP on Mac OS X. There are two slightly different versions of
- Mac OS X, Client and Server, our manual deals with installing
- PHP on both systems. Note that PHP is not available for MacOS
- 9 and earlier versions.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.macosx.packages"
- >Using Packages</A
- ></H2
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.macosx.server"
- >Compiling for OS X Server</A
- ></H2
- ><DIV
- CLASS="formalpara"
- ><P
- ><A
- NAME="install.macosx.server.compile"
- ></A
- ><B
- >Mac OS X Server install. </B
- >
- <P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >Get the latest distributions of Apache and PHP.</P
- ></LI
- ><LI
- ><P
- >
Untar them, and run the <B
- CLASS="command"
- >configure</B
- > program on Apache
- like so.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
If you want the compiler to do some optimization, you may also want to
- add this line:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >setenv OPTIM=-O2</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Next, go to the PHP 4 source directory and configure it.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./configure --prefix=/usr \
- --sysconfdir=/etc \
- --localstatedir=/var \
- --mandir=/usr/share/man \
- --with-xml \
- --with-apache=/src/apache_1.3.12</PRE
- ></TD
- ></TR
- ></TABLE
- >
- If you have any other additions (MySQL, GD, etc.), be sure to add them
- here. For the <VAR
- CLASS="option"
- >--with-apache</VAR
- > string, put
- in the path to your apache source directory, for example
- <TT
- CLASS="filename"
- >/src/apache_1.3.12</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Type <B
- CLASS="command"
- >make</B
- > and <B
- CLASS="command"
- >make install</B
- >. This
- will add a directory to your Apache source directory under
- <TT
- CLASS="filename"
- >src/modules/php4</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Now, reconfigure Apache to build in PHP 4.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >./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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- You may get a message telling you that <TT
- CLASS="filename"
- >libmodphp4.a</TT
- > is
- out of date. If so, go to the <TT
- CLASS="filename"
- >src/modules/php4</TT
- >
- directory inside your Apache source directory and run this command:
- <B
- CLASS="command"
- >ranlib libmodphp4.a</B
- >. Then go back to the root of the
- Apache source directory and run the above <B
- CLASS="command"
- >configure</B
- >
- command again. That'll bring the link table up to date. Run
- <B
- CLASS="command"
- >make</B
- > and <B
- CLASS="command"
- >make install</B
- > again.
- </P
- ></LI
- ><LI
- ><P
- >
Copy and rename the <TT
- CLASS="filename"
- >php.ini-dist</TT
- > file to your
- <TT
- CLASS="filename"
- >bin</TT
- > directory from your PHP 4
- source directory:
- <KBD
- CLASS="userinput"
- >cp php.ini-dist /usr/local/bin/php.ini</KBD
- >
- or (if your don't have a local directory)
- <KBD
- CLASS="userinput"
- >cp php.ini-dist /usr/bin/php.ini</KBD
- >.
- </P
- ></LI
- ></OL
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.macosx.client"
- >Compiling for MacOS X Client</A
- ></H2
- ><P
- >
The following instructions will help you install a PHP module for the Apache
- web server included in MacOS X. This version includes support for the MySQL
- and PostgreSQL databases. These instructions are graciously provided by
- <A
- HREF="http://www.entropy.ch/software/macosx/"
- TARGET="_top"
- >Marc Liyanage</A
- >.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Be careful when you do this, you could screw up your Apache web server!
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
Do this to install:
- <P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
Open a terminal window.
- </P
- ></LI
- ><LI
- ><P
- >
Type
- <KBD
- CLASS="userinput"
- >wget http://www.diax.ch/users/liyanage/software/macosx/libphp4.so.gz</KBD
- >,
- wait for the download to finish.
- </P
- ></LI
- ><LI
- ><P
- >
Type <KBD
- CLASS="userinput"
- >gunzip libphp4.so.gz</KBD
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Type <KBD
- CLASS="userinput"
- >sudo apxs -i -a -n php4 libphp4.so</KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
Now type <KBD
- CLASS="userinput"
- >sudo open -a TextEdit /etc/httpd/httpd.conf</KBD
- >.
- TextEdit will open with the web server configuration file. Locate these
- two lines towards the end of the file: (Use the Find command)
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache"
- >#AddType application/x-httpd-php .php
- #AddType application/x-httpd-php-source .phps</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Remove the two hash marks (<VAR
- CLASS="literal"
- >#</VAR
- >), then save the file and
- quit TextEdit.
- </P
- ></LI
- ><LI
- ><P
- >
Finally, type <KBD
- CLASS="userinput"
- >sudo apachectl graceful</KBD
- > to restart
- the web server.
- </P
- ></LI
- ></OL
- >
- </P
- ><P
- >
PHP should now be up and running. You can test it by dropping a file into
- your <TT
- CLASS="filename"
- >Sites</TT
- > folder which is called
- <TT
- CLASS="filename"
- >test.php</TT
- >. Into that file, write this line:
- <VAR
- CLASS="literal"
- ><?php phpinfo() ?></VAR
- >.
- </P
- ><P
- >
Now open up <VAR
- CLASS="literal"
- >127.0.0.1/~your_username/test.php</VAR
- > in your web
- browser. You should see a status table with information about the PHP module.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.windows"
- >Chapter 6. Installation on Windows systems</A
- ></H1
- ><P
- >
This section applies to Windows 98/Me and Windows NT/2000/XP/2003. 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.
- </P
- ><P
- >
There are two main ways to install PHP for Windows: either
- <A
- HREF="#install.windows.manual"
- >manually</A
- >
- or by using the <A
- HREF="#install.windows.installer"
- >installer</A
- >.
- </P
- ><P
- >
If you have Microsoft Visual Studio, you can also
- <A
- HREF="#install.windows.building"
- >build</A
- >
- PHP from the original source code.
- </P
- ><P
- >
Once you have PHP installed on your Windows system, you may also
- want to <A
- HREF="#install.windows.extensions"
- >load various extensions</A
- >
- for added functionality.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
There are several all-in-one installers over the Internet, but none of
- those are endorsed by PHP.net, as we believe that the manual installation
- is the best choice to have your system secure and optimised.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.installer"
- >Windows Installer</A
- ></H2
- ><P
- >
The Windows PHP installer is available from the downloads page at
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >http://www.php.net/downloads.php</A
- >. This
- installs the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >CGI version</I
- ></SPAN
- > of PHP and for IIS, PWS,
- and Xitami, it configures the web server as well. The installer does not
- include any extra external PHP extensions (php_*.dll) as you'll only find
- those in the Windows Zip Package and <ACRONYM
- CLASS="acronym"
- >PECL</ACRONYM
- > downloads.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- While the Windows installer is an easy way to make PHP work, it is
- restricted in many aspects as, for example, the automatic setup of
- extensions is not supported. Use of the installer isn't the preferred
- method for installing PHP.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
First, install your selected <ACRONYM
- CLASS="acronym"
- >HTTP</ACRONYM
- > (web) server on your
- system, and make sure that it works.
- </P
- ><P
- >
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.
- </P
- ><P
- >
The installation wizard gathers enough information to set up the <TT
- CLASS="filename"
- >php.ini</TT
- >
- file, and configure certain web servers to use PHP. One of the web servers
- the PHP installer does not configure for is Apache, so you'll need to
- configure it manually.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
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.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.manual"
- >Manual Installation Steps</A
- ></H2
- ><P
- >
This install guide will help you manually install and configure PHP with
- a web server on Microsoft Windows. To get started you'll need to download
- the zip binary distribution from the downloads page at
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >http://www.php.net/downloads.php</A
- >.
- </P
- ><P
- >
Although there are many all-in-one installation kits, and we also
- distribute a PHP installer for Microsoft Windows, we recommend you take
- the time to setup PHP yourself as this will provide you with a better
- understanding of the system, and enables you to install PHP extensions
- easily when needed.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><A
- NAME="install.windows.manual.upgrade"
- ></A
- ><P
- ><B
- >Upgrading from a previous PHP version: </B
- >
- Previous editions of the manual suggest moving various ini and
- <ACRONYM
- CLASS="acronym"
- >DLL</ACRONYM
- > files into your SYSTEM (i.e.
- <TT
- CLASS="filename"
- >C:\WINDOWS</TT
- >) folder and while this
- simplifies the installation procedure it makes upgrading difficult. We
- advise you remove all of these files (like <TT
- CLASS="filename"
- >php.ini</TT
- > and PHP related
- DLLs from the Windows SYSTEM folder) before moving on with a new
- PHP installation. Be sure to backup these files as you might break the
- entire system. The old <TT
- CLASS="filename"
- >php.ini</TT
- > might be useful in setting up the new
- PHP as well. And as you'll soon learn, the preferred method for
- installing PHP is to keep all PHP related files in one directory and
- have this directory available to your systems PATH.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >MDAC requirements: </B
- >
- If you use Microsoft <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >Windows 98/NT4</I
- ></SPAN
- > download the
- latest version of the Microsoft Data Access Components (MDAC) for your
- platform. MDAC is available at <A
- HREF="http://msdn.microsoft.com/data/"
- TARGET="_top"
- >http://msdn.microsoft.com/data/</A
- >.
- This requirement exists because <A
- HREF="#ref.uodbc"
- >ODBC</A
- > is
- built into the distributed Windows binaries.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The following steps should be completed on all installations before any
- server specific instructions are performed:
- </P
- ><P
- >
Extract the distribution file into a directory of your choice. If you
- are installing PHP 4, extract to <TT
- CLASS="filename"
- >C:\</TT
- >, as the zip file expands to a
- foldername like <TT
- CLASS="filename"
- >php-4.3.7-Win32</TT
- >. If you are
- installing PHP 5, extract to <TT
- CLASS="filename"
- >C:\php</TT
- > as the zip file doesn't expand as in
- PHP 4. You may choose a different location but do not have spaces in the
- path (like <TT
- CLASS="filename"
- >C:\Program Files\PHP</TT
- >)
- as some web servers will crash if you do.
- </P
- ><P
- >
The directory structure extracted from the zip is different for PHP
- versions 4 and 5 and look like as follows:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1041"
- ></A
- ><P
- ><B
- >Example 6-1. PHP 4 package structure</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >c:\php
- |
- +--cli
- | |
- | |-php.exe -- CLI executable - ONLY for commandline scripting
- |
- +--dlls -- support DLLs required by some extensions
- | |
- | |-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 (server module support) DLLs
- | |
- | |-php4activescript.dll
- | |
- | |-php4apache.dll
- | |
- | |-php4apache2.dll
- | |
- | |-..
- |
- +--PEAR -- initial copy of PEAR
- |
- |
- |-go-pear.bat -- PEAR setup script
- |
- |-..
- |
- |-php.exe -- CGI executable
- |
- |-..
- |
- |-php.ini-dist -- default php.ini settings
- |
- |-php.ini-recommended -- recommended php.ini settings
- |
- |-php4ts.dll -- core PHP DLL
- |
- |-...</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Or:
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1045"
- ></A
- ><P
- ><B
- >Example 6-2. PHP 5 package structure</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >c:\php
- |
- +--dev
- | |
- | |-php5ts.lib
- |
- +--ext -- extension DLLs for PHP
- | |
- | |-php_bz2.dll
- | |
- | |-php_cpdf.dll
- | |
- | |-..
- |
- +--extras
- | |
- | +--mibs -- support files for SNMP
- | |
- | +--openssl -- support files for Openssl
- | |
- | +--pdf-related -- support files for PDF
- | |
- | |-mime.magic
- |
- +--pear -- initial copy of PEAR
- |
- |
- |-go-pear.bat -- PEAR setup script
- |
- |-fdftk.dll
- |
- |-..
- |
- |-php-cgi.exe -- CGI executable
- |
- |-php-win.exe -- executes scripts without an opened command prompt
- |
- |-php.exe -- CLI executable - ONLY for command line scripting
- |
- |-..
- |
- |-php.ini-dist -- default php.ini settings
- |
- |-php.ini-recommended -- recommended php.ini settings
- |
- |-php5activescript.dll
- |
- |-php5apache.dll
- |
- |-php5apache2.dll
- |
- |-..
- |
- |-php5ts.dll -- core PHP DLL
- |
- |-...</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Notice the differences and similarities. Both PHP 4 and PHP 5 have a
- <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > executable, a <ACRONYM
- CLASS="acronym"
- >CLI</ACRONYM
- > executable,
- and server modules, but they are located in different folders and/or have
- different names. While PHP 4 packages have the server modules in the
- <TT
- CLASS="filename"
- >sapi</TT
- > folder, PHP 5
- distributions have no such directory and instead they're in the PHP
- folder root. The supporting DLLs for the PHP 5 extensions are also not
- in a seperate directory.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 4, you should move all files located in the <TT
- CLASS="filename"
- >dll</TT
- > and <TT
- CLASS="filename"
- >sapi</TT
- > folders to the main folder (e.g.
- <TT
- CLASS="filename"
- >C:\php</TT
- >).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Here is a list of server modules shipped with PHP 4 and PHP 5:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4activescript.dll (php5activescript.dll)</TT
- >
- - <A
- HREF="#install.windows.activescript"
- >ActiveScript
- engine</A
- >, allowing you to embed PHP in your Windows
- applications.
- </P
- ></LI
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4apache.dll (php5apache.dll)</TT
- > - Apache 1.3.x module.
- </P
- ></LI
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4apache2.dll (php5apache2.dll)</TT
- > - Apache 2.0.x module.
- </P
- ></LI
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4isapi.dll (php5isapi.dll)</TT
- > - ISAPI Module
- for ISAPI compliant web servers like IIS 4.0/PWS 4.0 or newer.
- </P
- ></LI
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4nsapi.dll (php5nsapi.dll)</TT
- > - Sun/iPlanet/Netscape
- server module.
- </P
- ></LI
- ><LI
- ><P
- >
<TT
- CLASS="filename"
- >sapi/php4pi3web.dll (no equivalent in PHP 5)</TT
- > - Pi3Web server module.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
Server modules provide significantly better performance and additional
- functionality compared to the CGI binary. The CLI version is designed to
- let you use PHP for command line scripting. More information about CLI is
- available in the chapter about <A
- HREF="#features.commandline"
- >using
- PHP from the command line</A
- >.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The SAPI modules have been significantly improved as of the 4.1 release,
- however, in older systems you may encounter server errors or other
- server modules failing, such as ASP.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
The CGI and CLI binaries, and the web server modules all require the
- <TT
- CLASS="filename"
- >php4ts.dll</TT
- > (<TT
- CLASS="filename"
- >php5ts.dll</TT
- >) file to
- be available to them. You have to make sure that this file can be found
- by your PHP installation. The search order for this DLL is as follows:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
The same directory from where <TT
- CLASS="filename"
- >php.exe</TT
- > is called,
- or in case you use a SAPI module, the web server's directory (e.g.
- <TT
- CLASS="filename"
- >C:\Program Files\Apache Group\Apache2\bin</TT
- >).
- </P
- ></LI
- ><LI
- ><P
- >
Any directory in your Windows <VAR
- CLASS="varname"
- >PATH</VAR
- > environment
- variable.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
To make <TT
- CLASS="filename"
- >php4ts.dll</TT
- > / <TT
- CLASS="filename"
- >php5ts.dll</TT
- >
- available you have three options: copy the file to the Windows system
- directory, copy the file to the web server's directory, or add your PHP
- directory, <TT
- CLASS="filename"
- >C:\php</TT
- > to the
- <VAR
- CLASS="varname"
- >PATH</VAR
- >. For better maintenance, we advise you to follow
- the last option, add <TT
- CLASS="filename"
- >C:\php</TT
- > to the
- <VAR
- CLASS="varname"
- >PATH</VAR
- >, because it will be simpler to upgrade PHP in the
- future. Read more about how to add your PHP directory to
- <VAR
- CLASS="varname"
- >PATH</VAR
- > in the <A
- HREF="#faq.installation.addtopath"
- >corresponding FAQ entry</A
- >.
- </P
- ><P
- >
The next step is to set up a valid configuration file for PHP, <TT
- CLASS="filename"
- >php.ini</TT
- >.
- There are two ini files distributed in the zip file,
- <TT
- CLASS="filename"
- >php.ini-dist</TT
- > and
- <TT
- CLASS="filename"
- >php.ini-recommended</TT
- >. We advise you to use
- <TT
- CLASS="filename"
- >php.ini-recommended</TT
- >, because we optimized the
- default settings in this file for performance, and security. Read this
- well documented file carefully because it has changes from
- <TT
- CLASS="filename"
- >php.ini-dist</TT
- > that will drastically affect your
- setup. Some examples are <A
- HREF="#ini.display-errors"
- >
display_errors</A
- > being <VAR
- CLASS="literal"
- >off</VAR
- > and
- <A
- HREF="#ini.magic-quotes-gpc"
- >magic_quotes_gpc</A
- > being
- <VAR
- CLASS="literal"
- >off</VAR
- >. In addition to reading these, study the <A
- HREF="#configuration.file"
- >ini settings</A
- > 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 that PHP is able to find
- and rename it to <TT
- CLASS="filename"
- >php.ini</TT
- >. PHP searches for <TT
- CLASS="filename"
- >php.ini</TT
- > in the following
- locations (in order):
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
PHPIniDir directive (Apache 2 module only)
- </P
- ></LI
- ><LI
- ><P
- >
<VAR
- CLASS="literal"
- >HKEY_LOCAL_MACHINE\SOFTWARE\PHP\IniFilePath</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
The <VAR
- CLASS="varname"
- >PHPRC</VAR
- > environment variable
- </P
- ></LI
- ><LI
- ><P
- >
Directory of PHP (for CLI), or the web server's directory (for
- SAPI modules)
- </P
- ></LI
- ><LI
- ><P
- >
Windows directory (<TT
- CLASS="filename"
- >C:\windows</TT
- >
- or <TT
- CLASS="filename"
- >C:\winnt</TT
- >)
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
If you are running Apache 2, the simpler option is to use the PHPIniDir
- directive (read the <A
- HREF="#install.windows.apache2"
- >installation
- on Apache 2</A
- > page), otherwise your best option is to set the
- <VAR
- CLASS="varname"
- >PHPRC</VAR
- > environment variable. This process is explained
- in the following <A
- HREF="#faq.installation.phprc"
- >FAQ entry</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you're using NTFS on Windows NT, 2000, XP or 2003, make sure that the
- user running the web server has read permissions to your <TT
- CLASS="filename"
- >php.ini</TT
- > (e.g.
- make it readable by Everyone).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The following steps are optional:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Edit your new <TT
- CLASS="filename"
- >php.ini</TT
- > file.
- If you plan to use <A
- HREF="#install.windows.omnihttpd"
- >OmniHTTPd</A
- >,
- do not follow the next step. Set the
- <A
- HREF="#ini.doc-root"
- >doc_root</A
- > to point to your
- web servers document_root. For example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN1144"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- >doc_root = c:\inetpub\wwwroot // for IIS/PWS
-
- doc_root = c:\apache\htdocs // for Apache</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></LI
- ><LI
- ><P
- >
Choose the extensions you would like to load when PHP starts. See
- the section about
- <A
- HREF="#install.windows.extensions"
- >Windows extensions</A
- >,
- 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 <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
On PWS and IIS, you can set the
- <A
- HREF="#ini.browscap"
- >browscap</A
- > configuration setting
- to point to:
- <TT
- CLASS="filename"
- >c:\windows\system\inetsrv\browscap.ini</TT
- > on
- Windows 9x/Me,
- <TT
- CLASS="filename"
- >c:\winnt\system32\inetsrv\browscap.ini</TT
- > on
- NT/2000, and
- <TT
- CLASS="filename"
- >c:\windows\system32\inetsrv\browscap.ini</TT
- >
- on XP. For an up-to-date <TT
- CLASS="filename"
- >browscap.ini</TT
- >, read the
- following <A
- HREF="#faq.obtaining.browscap"
- >FAQ</A
- >.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
PHP is now setup on your system. The next step is to choose a web
- server, and enable it to run PHP. Choose a webserver from the table of
- contents.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.activescript"
- >ActiveScript</A
- ></H2
- ><P
- >
This section contains notes specific to the ActiveScript installation.
- </P
- ><P
- >
ActiveScript is a windows only SAPI that enables you to use PHP script in
- any ActiveScript compliant host, like Windows Script Host, ASP/ASP.NET,
- Windows Script Components or Microsoft Scriptlet control.
- </P
- ><P
- >
As of PHP 5.0.1, ActiveScript has been moved to the <A
- HREF="http://pecl.php.net"
- TARGET="_top"
- >PECL</A
- > repository. You may download this <ACRONYM
- CLASS="acronym"
- >PECL</ACRONYM
- >
- extension <ACRONYM
- CLASS="acronym"
- >DLL</ACRONYM
- > from the <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >
PHP Downloads</A
- > page or at <A
- HREF="http://snaps.php.net/"
- TARGET="_top"
- >
http://snaps.php.net/</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You should read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
After installing PHP, you should download the ActiveScript DLL
- (<TT
- CLASS="filename"
- >php5activescript.dll</TT
- >) and place it in the main PHP
- folder (e.g. <TT
- CLASS="filename"
- >C:\php</TT
- >).
- </P
- ><P
- >
After having all the files needed, you must register the DLL on your
- system. To achieve this, open a Command Prompt window (located in the
- Start Menu). Then go to your PHP directory by typing something like
- <VAR
- CLASS="literal"
- >cd C:\php</VAR
- >. To register the DLL just type
- <VAR
- CLASS="literal"
- >regsvr32 php5activescript.dll</VAR
- >.
- </P
- ><P
- >
To test if ActiveScript is working, create a new file, named
- <VAR
- CLASS="literal"
- >test.wsf</VAR
- > (the extension is very important) and type:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><job id="test">
-
- <script language="PHPScript">
- $WScript->Echo("Hello World!");
- </script>
-
- </job></PRE
- ></TD
- ></TR
- ></TABLE
- >
- Save and double-click on the file. If you receive a little window saying
- "Hello World!" you're done.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- ActiveScript doesn't use the default <TT
- CLASS="filename"
- >php.ini</TT
- > file. Instead, it will
- look only in the same directory as the .exe that caused it to load. You
- should create <TT
- CLASS="filename"
- >php-activescript.ini</TT
- > and place it in
- that folder, if you wish to load extensions, etc.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.iis"
- >Microsoft IIS / PWS</A
- ></H2
- ><P
- >
This section contains notes and hints specific to IIS (Microsoft
- Internet Information Server). We have included installation
- instructions for <A
- HREF="#install.windows.iis.iis3"
- >PWS/IIS 3</A
- >,
- <A
- HREF="#install.windows.iis.pws4"
- >PWS 4 or newer</A
- > and
- <A
- HREF="#install.windows.iis.iis4"
- >IIS 4 or newer</A
- > versions.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Important for CGI users: </B
- >
- Read the <A
- HREF="#faq.installation.forceredirect"
- >faq
- on cgi.force_redirect</A
- > for important details. This
- directive needs to be set to <VAR
- CLASS="literal"
- >0</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.iis.iis3"
- >Windows and PWS/IIS 3</A
- ></H3
- ><P
- >
The recommended method for configuring these servers is to use
- the REG file included with the distribution
- (<TT
- CLASS="filename"
- >pws-php4cgi.reg</TT
- > in the SAPI folder for PHP 4, or
- <TT
- CLASS="filename"
- >pws-php5cgi.reg</TT
- > in the main folder for PHP 5).
- You may want to edit this file and make sure
- the extensions and PHP install directories match your
- configuration. Or you can follow the steps below to do it
- manually.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
These steps involve working directly with the Windows
- registry. One error here can leave your system in an unstable
- state. We highly recommend that you back up your registry
- first. The PHP Development team will not be held responsible if
- you damage your registry.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
<P
- ></P
- ><UL
- ><LI
- ><P
- >
Run Regedit.
- </P
- ></LI
- ><LI
- ><P
- >
Navigate to: <VAR
- CLASS="literal"
- >HKEY_LOCAL_MACHINE /System
- /CurrentControlSet /Services /W3Svc /Parameters
- /ScriptMap</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
On the edit menu select: <VAR
- CLASS="literal"
- >New->String Value</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Type in the extension you wish to use for your php
- scripts. For example <VAR
- CLASS="literal"
- >.php</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
Double click on the new string value and enter the path to
- <TT
- CLASS="filename"
- >php.exe</TT
- > in the value data field. ex:
- <TT
- CLASS="filename"
- >C:\php\php.exe</TT
- > for PHP 4, or
- <TT
- CLASS="filename"
- >C:\php\php-cgi.exe</TT
- > for PHP 5.
- </P
- ></LI
- ><LI
- ><P
- >
Repeat these steps for each extension you wish to associate
- with PHP scripts.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
The following steps do not affect the web server installation
- and only apply if you want your PHP scripts to be executed when
- they are run from the command line (ex. run
- <TT
- CLASS="filename"
- >C:\myscripts\test.php</TT
- >) or by double clicking
- on them in a directory viewer window. You may wish to skip these
- steps as you might prefer the PHP files to load into a text
- editor when you double click on them.
- </P
- ><P
- >
<P
- ></P
- ><UL
- ><LI
- ><P
- >
Navigate to: <VAR
- CLASS="literal"
- >HKEY_CLASSES_ROOT</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
On the edit menu select: <VAR
- CLASS="literal"
- >New->Key</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Name the key to the extension you setup in the previous
- section. ex: <VAR
- CLASS="literal"
- >.php</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
Highlight the new key and in the right side pane, double click
- the "default value" and enter <VAR
- CLASS="literal"
- >phpfile</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Repeat the last step for each extension you set up in the
- previous section.
- </P
- ></LI
- ><LI
- ><P
- >
Now create another <VAR
- CLASS="literal"
- >New->Key</VAR
- > under
- <VAR
- CLASS="literal"
- >HKEY_CLASSES_ROOT</VAR
- > and name it
- <VAR
- CLASS="literal"
- >phpfile</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Highlight the new key <VAR
- CLASS="literal"
- >phpfile</VAR
- > and in the
- right side pane, double click the "default value" and enter
- <VAR
- CLASS="literal"
- >PHP Script</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Right click on the <VAR
- CLASS="literal"
- >phpfile</VAR
- > key and select
- <VAR
- CLASS="literal"
- >New->Key</VAR
- >, name it <VAR
- CLASS="literal"
- >Shell</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Right click on the <VAR
- CLASS="literal"
- >Shell</VAR
- > key and select
- <VAR
- CLASS="literal"
- >New->Key</VAR
- >, name it <VAR
- CLASS="literal"
- >open</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Right click on the <VAR
- CLASS="literal"
- >open</VAR
- > key and select
- <VAR
- CLASS="literal"
- >New->Key</VAR
- >, name it
- <VAR
- CLASS="literal"
- >command</VAR
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Highlight the new key <VAR
- CLASS="literal"
- >command</VAR
- > and in the
- right side pane, double click the "default value" and enter
- the path to <TT
- CLASS="filename"
- >php.exe</TT
- >. ex:
- <VAR
- CLASS="literal"
- >c:\php\php.exe -q %1</VAR
- >. (don't forget the
- <VAR
- CLASS="literal"
- >%1</VAR
- >).
- </P
- ></LI
- ><LI
- ><P
- >
Exit Regedit.
- </P
- ></LI
- ><LI
- ><P
- >
If using PWS on Windows, reboot to reload the registry.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
PWS and IIS 3 users now have a fully operational system. IIS 3
- users can use a nifty <A
- HREF="http://www.genusa.com/iis/iiscfg.html"
- TARGET="_top"
- >tool</A
- >
- from Steven Genusa to configure their script maps.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.iis.pws4"
- >Windows and PWS 4 or newer</A
- ></H3
- ><P
- >
When installing PHP on Windows with PWS 4 or newer version,
- you have two options. One to set up the PHP CGI binary,
- the other is to use the ISAPI module DLL.
- </P
- ><P
- >
If you choose the CGI binary, do the following:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Edit the enclosed <TT
- CLASS="filename"
- >pws-php4cgi.reg</TT
- > /
- <TT
- CLASS="filename"
- >pws-php5cgi.reg</TT
- > file (look into the SAPI folder
- for PHP 4, or in the main folder for PHP 5) to reflect the location of
- your <TT
- CLASS="filename"
- >php.exe</TT
- > / <TT
- CLASS="filename"
- >php-cgi.exe</TT
- >.
- Backslashes should be escaped, for example:
- <VAR
- CLASS="literal"
- >[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script
- Map] ".php"="C:\\php\\php.exe"</VAR
- > (change to
- <VAR
- CLASS="literal"
- >C:\\php\\php-cgi.exe</VAR
- > if you are using PHP 5)
- Now merge this registery file into your system; you may do
- this by double-clicking it.
- </P
- ></LI
- ><LI
- ><P
- >
In the PWS Manager, right click on a given directory you want
- to add PHP support to, and select Properties. Check the 'Execute'
- checkbox, and confirm.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
If you choose the ISAPI module, do the following:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Edit the enclosed <TT
- CLASS="filename"
- >pws-php4isapi.reg</TT
- > /
- <TT
- CLASS="filename"
- >pws-php5isapi.reg</TT
- > file (look into the SAPI folder
- for PHP 4, or in the main folder for PHP 5) to reflect the location of
- your <TT
- CLASS="filename"
- >php4isapi.dll</TT
- > /
- <TT
- CLASS="filename"
- >php5isapi.dll</TT
- >. Backslashes should be escaped, for example:
- <VAR
- CLASS="literal"
- >[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script
- Map] ".php"="C:\\php\\sapi\\php4isapi.dll"</VAR
- > (or
- <VAR
- CLASS="literal"
- >C:\\php\\php5isapi.dll</VAR
- > for PHP 5)
- Now merge this registery file into your system; you may do
- this by double-clicking it.
- </P
- ></LI
- ><LI
- ><P
- >
In the PWS Manager, right click on a given directory you want to
- add PHP support to, and select Properties. Check the 'Execute'
- checkbox, and confirm.
- </P
- ></LI
- ></UL
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.iis.iis4"
- >Windows NT/2000/XP and IIS 4 or newer</A
- ></H3
- ><P
- >
To install PHP on an NT/2000/XP Server running IIS 4 or newer,
- follow these instructions. You have two options to set up
- PHP, using the CGI binary (<TT
- CLASS="filename"
- >php.exe</TT
- > in PHP 4, or
- <TT
- CLASS="filename"
- >php-cgi.exe</TT
- > in PHP 5) or with the ISAPI module.
- </P
- ><P
- >
In either case, you need to start the Microsoft Management
- Console (may appear as 'Internet Services Manager', either
- in your Windows NT 4.0 Option Pack branch or the Control
- Panel=>Administrative Tools under Windows 2000/XP). Then
- right click on your Web server node (this will most probably
- appear as 'Default Web Server'), and select 'Properties'.
- </P
- ><P
- >
If you want to use the CGI binary, do the following:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Under 'Home Directory', 'Virtual Directory', or
- 'Directory', click on the 'Configuration' button,
- and then enter the App Mappings tab.
- </P
- ></LI
- ><LI
- ><P
- >
Click Add, and in the Executable box, type:
- <VAR
- CLASS="literal"
- >C:\php\php.exe</VAR
- > for PHP 4 or
- <VAR
- CLASS="literal"
- >C:\php\php-cgi.exe</VAR
- > for PHP 5 (assuming
- that you have unziped PHP in <TT
- CLASS="filename"
- >c:\php\</TT
- >).
- </P
- ></LI
- ><LI
- ><P
- >
In the Extension box, type the file name extension you want
- associated with PHP scripts. Leave 'Method exclusions'
- blank, and check the 'Script engine' checkbox. You may also
- like to check the 'check that file exists' box - for a small
- performance penalty, IIS (or PWS) will check that the script
- file exists and sort out authentication before firing up PHP.
- This means that you will get sensible 404 style error messages
- instead of CGI errors complaining that PHP did not output any data.
- </P
- ><P
- >
You must start over from the previous step for each
- extension you want associated with PHP scripts.
- <VAR
- CLASS="literal"
- >.php</VAR
- > and <VAR
- CLASS="literal"
- >.phtml</VAR
- >
- are common, although <VAR
- CLASS="literal"
- >.php3</VAR
- > may be
- required for legacy applications.
- </P
- ></LI
- ><LI
- ><P
- >
Set up the appropriate security. (This is done in Internet
- Service Manager), and if your NT Server uses NTFS file system,
- add execute rights for I_USR_ to the directory that contains
- <TT
- CLASS="filename"
- >php.exe</TT
- > / <TT
- CLASS="filename"
- >php-cgi.exe</TT
- >.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
To use the ISAPI module, do the following:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
If you don't want to perform HTTP Authentication using PHP,
- you can (and should) skip this step. Under ISAPI Filters,
- add a new ISAPI filter. Use PHP as the filter name, and
- supply a path to the <TT
- CLASS="filename"
- >php4isapi.dll</TT
- > /
- <TT
- CLASS="filename"
- >php5isapi.dll</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Under 'Home Directory', click on the 'Configuration' button.
- Add a new entry to the Application Mappings. Use the path
- to the <TT
- CLASS="filename"
- >php4isapi.dll</TT
- > /
- <TT
- CLASS="filename"
- >php5isapi.dll</TT
- > as the Executable, supply
- <VAR
- CLASS="literal"
- >.php</VAR
- > as the extension, leave 'Method exclusions'
- blank, and check the 'Script engine' checkbox.
- </P
- ></LI
- ><LI
- ><P
- >
Stop IIS completely (NET STOP iisadmin)
- </P
- ></LI
- ><LI
- ><P
- >
Start IIS again (NET START w3svc)
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
If you experience 100% CPU usage after some time, turn off the IIS
- setting <VAR
- CLASS="literal"
- >Cache ISAPI Application</VAR
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.apache1"
- >Apache 1.3.x on Microsoft Windows</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Apache 1.3.x installs
- of PHP on Microsoft Windows systems. There are also
- <A
- HREF="#install.windows.apache2"
- >instructions and notes
- for Apache 2</A
- > on a separate page.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Please read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
There are two ways to set up PHP to work with Apache 1.3.x
- on Windows. One is to use the CGI binary (<TT
- CLASS="filename"
- >php.exe</TT
- >
- for PHP 4 and <TT
- CLASS="filename"
- >php-cgi.exe</TT
- > for PHP 5),
- the other is to use the Apache Module DLL. In either case
- you need to edit your <TT
- CLASS="filename"
- >httpd.conf</TT
- > to configure Apache to
- work with PHP, and then restart the server.
- </P
- ><P
- >
It is worth noting here that now the SAPI module has been
- made more stable under Windows, we recommend it's use above
- the CGI binary, since it is more transparent and secure.
- </P
- ><P
- >
Although there can be a few variations of configuring PHP
- under Apache, these are simple enough to be used by the
- newcomer. Please consult the Apache Documentation for further
- configuration directives.
- </P
- ><P
- >
After changing the configuration file, remember to restart the server, for
- example, <B
- CLASS="command"
- >NET STOP APACHE</B
- > followed by
- <B
- CLASS="command"
- >NET START APACHE</B
- >, if you run Apache as a Windows
- Service, or use your regular shortcuts.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >Remember that when adding
- path values in the Apache configuration files on Windows, all backslashes
- such as <TT
- CLASS="filename"
- >c:\directory\file.ext</TT
- > must be converted to
- forward slashes, as <TT
- CLASS="filename"
- >c:/directory/file.ext</TT
- >.</P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.apache1.module"
- >Installing as an Apache module</A
- ></H3
- ><P
- >
You should add the following lines to your Apache <TT
- CLASS="filename"
- >httpd.conf</TT
- > file:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1374"
- ></A
- ><P
- ><B
- >Example 6-3. PHP as an Apache 1.3.x module</B
- ></P
- ><P
- >
This assumes PHP is installed to <TT
- CLASS="filename"
- >c:\php</TT
- >. Adjust the
- path if this is not the case.
- </P
- ><P
- >
For PHP 4:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Add to the end of the LoadModule section
- LoadModule php4_module "c:/php/php4apache.dll"
-
- # Add to the end of the AddModule section
- AddModule mod_php4.c</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
For PHP 5:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Add to the end of the LoadModule section
- LoadModule php5_module "c:/php/php5apache.dll"
-
- # Add to the end of the AddModule section
- AddModule mod_php5.c</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
For both:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Add this line inside the <IfModule mod_mime.c> conditional brace
- AddType application/x-httpd-php .php
-
- # For syntax highlighted .phps files, also add
- AddType application/x-httpd-php-source .phps</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.apache1.cgi"
- >Installing as a CGI binary</A
- ></H3
- ><P
- >
If you unzipped the PHP package to <TT
- CLASS="filename"
- >C:\php\</TT
- > as described
- in the <A
- HREF="#install.windows.manual"
- >Manual
- Installation Steps</A
- > section, you need to insert
- these lines to your Apache configuration file to set
- up the CGI binary:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1389"
- ></A
- ><P
- ><B
- >Example 6-4. PHP and Apache 1.3.x as CGI</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- >ScriptAlias /php/ "c:/php/"
- AddType application/x-httpd-php .php
-
- # For PHP 4
- Action application/x-httpd-php "/php/php.exe"
-
- # For PHP 5
- Action application/x-httpd-php "/php/php-cgi.exe"
-
- # specify the directory where php.ini is
- SetEnv PHPRC C:/php</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Note that the second line in the list above can be found
- in the actual versions of <TT
- CLASS="filename"
- >httpd.conf</TT
- >, but it is commented out. Remember
- also to substitute the <TT
- CLASS="filename"
- >c:/php/</TT
- > for your actual path to
- PHP.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
If you would like to present PHP source files syntax highlighted, there
- is no such convenient option as with the module version of PHP.
- If you chose to configure Apache to use PHP as a CGI binary, you
- will need to use the <A
- HREF="#function.highlight-file"
- ><B
- CLASS="function"
- >highlight_file()</B
- ></A
- > function. To
- do this simply create a PHP script file and add this code:
- <VAR
- CLASS="literal"
- ><?php highlight_file('some_php_script.php'); ?></VAR
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.apache2"
- >Apache 2.0.x on Microsoft Windows</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Apache 2.0.x installs
- of PHP on Microsoft Windows systems. We also
- have <A
- HREF="#install.windows.apache1"
- >instructions and notes
- for Apache 1.3.x users on a separate page</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You should read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >We do not recommend using a threaded MPM
- in production with Apache2. Use the prefork MPM instead, or use Apache1. For information
- on why, read the following
- <A
- HREF="#faq.installation.apache2"
- >FAQ entry</A
- ></P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
You are highly encouraged to take a look at the
- <A
- HREF="http://httpd.apache.org/docs-2.0/"
- TARGET="_top"
- >Apache Documentation</A
- > to get
- a basic understanding of the Apache 2.0.x Server. Also consider to
- read the <A
- HREF="http://httpd.apache.org/docs-2.0/platform/windows.html"
- TARGET="_top"
- >Windows specific
- notes</A
- > for Apache 2.0.x before reading on here.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >PHP and Apache 2.0.x compatibility notes: </B
- >
- The following versions of PHP are known to work with the most recent
- version of Apache 2.0.x:
- <P
- ></P
- ><UL
- COMPACT="COMPACT"
- ><LI
- ><SPAN
- >
PHP 4.3.0 or later available at
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >http://www.php.net/downloads.php</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
the latest stable development version.
- Get the source code <A
- HREF="http://snaps.php.net/php4-latest.tar.gz"
- TARGET="_top"
- >
http://snaps.php.net/php4-latest.tar.gz</A
- > or download binaries
- for Windows <A
- HREF="http://snaps.php.net/win32/php4-win32-latest.zip"
- TARGET="_top"
- >
http://snaps.php.net/win32/php4-win32-latest.zip</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
a prerelease version downloadable from
- <A
- HREF="http://qa.php.net/"
- TARGET="_top"
- >http://qa.php.net/</A
- >.
- </SPAN
- ></LI
- ><LI
- ><SPAN
- >
you have always the option to obtain PHP through
- <A
- HREF="http://www.php.net/anoncvs.php"
- TARGET="_top"
- >anonymous CVS</A
- >.
- </SPAN
- ></LI
- ></UL
- >
- These versions of PHP are compatible to Apache 2.0.40 and later.
- </P
- ><P
- >
Apache 2.0 <VAR
- CLASS="literal"
- >SAPI</VAR
- >-support started with PHP 4.2.0.
- PHP 4.2.3 works with Apache 2.0.39, don't use any other version of Apache with
- PHP 4.2.3. However, the recommended setup is to use PHP 4.3.0 or later with
- the most recent version of Apache2.
- </P
- ><P
- >
All mentioned versions of PHP will work still with
- Apache 1.3.x.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Apache 2.0.x is designed to run on Windows NT 4.0, Windows 2000 or
- Windows XP. At this time, support for Windows 9x is incomplete.
- Apache 2.0.x is not expected to work on those platforms at this time.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
Download the most recent version of <A
- HREF="http://www.apache.org/"
- TARGET="_top"
- >
Apache 2.0.x</A
- > and a fitting PHP version.
- Follow the <A
- HREF="#install.windows.manual"
- >Manual Installation
- Steps</A
- > and come back to go on with the integration of PHP and Apache.
- </P
- ><P
- >
There are two ways to set up PHP to work with Apache 2.0.x on Windows.
- One is to use the CGI binary the other is to use the Apache module DLL.
- In either case you need to edit your <TT
- CLASS="filename"
- >httpd.conf</TT
- > to configure Apache
- to work with PHP and then restart the server.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >Remember that when adding
- path values in the Apache configuration files on Windows, all backslashes
- such as <TT
- CLASS="filename"
- >c:\directory\file.ext</TT
- > must be converted to
- forward slashes, as <TT
- CLASS="filename"
- >c:/directory/file.ext</TT
- >.</P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.apache2.cgi"
- >Installing as a CGI binary</A
- ></H3
- ><P
- >
You need to insert these three lines to your Apache <TT
- CLASS="filename"
- >httpd.conf</TT
- >
- configuration file to set up the CGI binary:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1448"
- ></A
- ><P
- ><B
- >Example 6-5. PHP and Apache 2.0 as CGI</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- >ScriptAlias /php/ "c:/php/"
- AddType application/x-httpd-php .php
-
- # For PHP 4
- Action application/x-httpd-php "/php/php.exe"
-
- # For PHP 5
- Action application/x-httpd-php "/php/php-cgi.exe"</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.apache2.module"
- >Installing as an Apache module</A
- ></H3
- ><P
- >
You need to insert these two lines to your
- Apache <TT
- CLASS="filename"
- >httpd.conf</TT
- > configuration file to set up the
- PHP module for Apache 2.0:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1458"
- ></A
- ><P
- ><B
- >Example 6-6. PHP and Apache 2.0 as Module</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># For PHP 4 do something like this:
- LoadModule php4_module "c:/php/php4apache2.dll"
- AddType application/x-httpd-php .php
-
- # For PHP 5 do something like this:
- LoadModule php5_module "c:/php/php5apache2.dll"
- AddType application/x-httpd-php .php
-
- # configure the path to php.ini
- PHPIniDir "C:/php"</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Remember to substitute the <TT
- CLASS="filename"
- >c:/php/</TT
- > for your actual
- path to PHP in the above examples. Take care to use
- either <TT
- CLASS="filename"
- >php4apache2.dll</TT
- > or
- <TT
- CLASS="filename"
- >php5apache2.dll</TT
- > in your LoadModule directive and
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > <TT
- CLASS="filename"
- >php4apache.dll</TT
- > or
- <TT
- CLASS="filename"
- >php5apache.dll</TT
- > as the latter ones are designed to
- run with <A
- HREF="#install.windows.apache1"
- >Apache 1.3.x</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you want to use content negotiation, read
- <A
- HREF="#faq.installation.apache.multiviews"
- >related FAQ</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Don't mix up your installation with DLL files from
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >different PHP versions</I
- ></SPAN
- >. You have the only choice
- to use the DLL's and extensions that ship with your downloaded PHP version.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.sun"
- >Sun, iPlanet and Netscape servers on Microsoft Windows</A
- ></H2
- ><P
- >
This section contains notes and hints specific to Sun Java System Web Server,
- Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Windows.
- </P
- ><P
- >
From PHP 4.3.3 on you can use PHP scripts with the
- <A
- HREF="#ref.nsapi"
- >NSAPI module</A
- > to
- <A
- HREF="#install.windows.sun.specialpages"
- >generate custom
- directory listings and error pages</A
- >. Additional functions for
- Apache compatibility are also available. For support in current webservers
- read the <A
- HREF="#install.windows.sun.notes"
- >note about
- subrequests</A
- >.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.sun.cgi"
- >CGI setup on Sun, iPlanet and Netscape servers</A
- ></H3
- ><P
- >
To install PHP as a CGI handler, do the following:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Copy <TT
- CLASS="filename"
- >php4ts.dll</TT
- > to your systemroot
- (the directory where you installed Windows)
- </P
- ></LI
- ><LI
- ><P
- >
Make a file association from the command line.
- Type the following two lines:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >assoc .php=PHPScript
- ftype PHPScript=c:\php\php.exe %1 %*</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
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).
- </P
- ></LI
- ><LI
- ><P
- >
In the Netscape Enterprise Administration Server create
- a new mime type (Category: type,
- Content-Type: magnus-internal/shellcgi, File Suffix:php).
- </P
- ></LI
- ><LI
- ><P
- >
Do it for each web server instance you want PHP to run
- </P
- ></LI
- ></UL
- ><P
- >
More details about setting up
- PHP as a CGI executable can be found here:
- <A
- HREF="http://benoit.noss.free.fr/php/install-php.html"
- TARGET="_top"
- >http://benoit.noss.free.fr/php/install-php.html</A
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.sun.nsapi"
- >NSAPI setup on Sun, iPlanet and Netscape servers</A
- ></H3
- ><P
- >
To install PHP with NSAPI, do the following:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Copy <TT
- CLASS="filename"
- >php4ts.dll</TT
- > to your systemroot
- (the directory where you installed Windows)
- </P
- ></LI
- ><LI
- ><P
- >
Make a file association from the command line.
- Type the following two lines:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >assoc .php=PHPScript
- ftype PHPScript=c:\php\php.exe %1 %*</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
In the Netscape Enterprise Administration Server create
- a new mime type (Category: type,
- Content-Type: magnus-internal/x-httpd-php, File Suffix: php).
- </P
- ></LI
- ><LI
- ><P
- >
Edit <TT
- CLASS="filename"
- >magnus.conf</TT
- > (for servers >= 6) or
- <TT
- CLASS="filename"
- >obj.conf</TT
- > (for servers < 6) and add the following:
- You should
- place the lines after <VAR
- CLASS="literal"
- >mime types init</VAR
- >.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >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"]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- (PHP >= 4.3.3) The <VAR
- CLASS="literal"
- >php_ini</VAR
- > parameter is
- optional but with it you can place your
- <TT
- CLASS="filename"
- >php.ini</TT
- > in your webserver config directory.
- </P
- ></LI
- ><LI
- ><P
- >
Configure the default object in <TT
- CLASS="filename"
- >obj.conf</TT
- >
- (for virtual server classes [Sun Web Server 6.0+] in
- their <TT
- CLASS="filename"
- >vserver.obj.conf</TT
- >):
- In the <VAR
- CLASS="literal"
- ><Object name="default"></VAR
- >
- section, place this line necessarily after all 'ObjectType'
- and before all 'AddLog' lines:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- (PHP >= 4.3.3) As additional parameters you can add some special
- <TT
- CLASS="filename"
- >php.ini</TT
- >-values, for example you
- can set a <VAR
- CLASS="literal"
- >docroot="/path/to/docroot"</VAR
- >
- specific to the context <VAR
- CLASS="literal"
- >php4_execute</VAR
- >
- is called. For boolean ini-keys please use 0/1 as value,
- not <VAR
- CLASS="literal"
- >"On","Off",...</VAR
- >
- (this will not work correctly), e.g.
- <VAR
- CLASS="literal"
- >zlib.output_compression=1</VAR
- > instead of
- <VAR
- CLASS="literal"
- >zlib.output_compression="On"</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
This is only needed if you want to configure a directory that only consists of
- PHP scripts (same like a cgi-bin directory):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><Object name="x-httpd-php">
- ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
- Service fn=php4_execute [inikey=value inikey=value ...]
- </Object></PRE
- ></TD
- ></TR
- ></TABLE
- >
- After that you can configure a directory in the Administration server and assign it
- the style <VAR
- CLASS="literal"
- >x-httpd-php</VAR
- >. All files in it will get executed as PHP.
- This is nice to hide PHP usage by renaming files to <TT
- CLASS="filename"
- >.html</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Restart your web service and apply changes
- </P
- ></LI
- ><LI
- ><P
- >
Do it for each web server instance you want PHP to run
- </P
- ></LI
- ></UL
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- More details about setting up
- PHP as an NSAPI filter can be found here:
- <A
- HREF="http://benoit.noss.free.fr/php/install-php4.html"
- TARGET="_top"
- >http://benoit.noss.free.fr/php/install-php4.html</A
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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").
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.sun.phpini"
- >CGI environment and recommended modifications in php.ini</A
- ></H3
- ><P
- >
Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE
- WS/iPlanet/Netscape is a multithreaded web server. Because of that all
- requests are running in the same process space (the space of the webserver
- itself) and this space has only one environment. If you want to get CGI
- variables like <VAR
- CLASS="literal"
- >PATH_INFO</VAR
- >, <VAR
- CLASS="literal"
- >HTTP_HOST</VAR
- >
- etc. it is not the correct way to try this in the old PHP 3.x way with
- <A
- HREF="#function.getenv"
- ><B
- CLASS="function"
- >getenv()</B
- ></A
- > or a similar way (register globals to
- environment, <VAR
- CLASS="literal"
- >$_ENV</VAR
- >). You would only get the environment
- of the running webserver without any valid CGI variables!
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Why are there (invalid) CGI variables in the environment?
- </P
- ><P
- >
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 command line as root user and start it manually - you will see
- there are no CGI-like environment variables.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Simply change your scripts to get CGI variables in the correct way for
- PHP 4.x by using the superglobal <VAR
- CLASS="literal"
- >$_SERVER</VAR
- >. If you have
- older scripts which use <VAR
- CLASS="literal"
- >$HTTP_HOST</VAR
- >, etc., you should turn
- on <VAR
- CLASS="literal"
- >register_globals</VAR
- > in <TT
- CLASS="filename"
- >php.ini</TT
- > and change the variable
- order too (important: remove <VAR
- CLASS="literal"
- >"E"</VAR
- > from it,
- because you do not need the environment here):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >variables_order = "GPCS"
- register_globals = On</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.sun.specialpages"
- >Special use for error pages or self-made directory listings (PHP >= 4.3.3)</A
- ></H3
- ><P
- >
You can use PHP to generate the error pages for <VAR
- CLASS="literal"
- >"404 Not Found"</VAR
- >
- or similar. Add the following line to the object in <TT
- CLASS="filename"
- >obj.conf</TT
- > for
- every error page you want to overwrite:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- where <VAR
- CLASS="literal"
- >XXX</VAR
- > is the HTTP error code. Please delete
- any other <VAR
- CLASS="literal"
- >Error</VAR
- > directives which could interfere with yours.
- If you want to place a page for all errors that could exist, leave
- the <VAR
- CLASS="literal"
- >code</VAR
- > parameter out. Your script can get the HTTP status code
- with <VAR
- CLASS="literal"
- >$_SERVER['ERROR_TYPE']</VAR
- >.
- </P
- ><P
- >
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
- <VAR
- CLASS="literal"
- >type="magnus-internal/directory"</VAR
- >
- in <TT
- CLASS="filename"
- >obj.conf</TT
- > with the following:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- For both error and directory listing pages the original URI and
- translated URI are in the variables <VAR
- CLASS="literal"
- >$_SERVER['PATH_INFO']</VAR
- > and
- <VAR
- CLASS="literal"
- >$_SERVER['PATH_TRANSLATED']</VAR
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.sun.notes"
- >Note about <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > and subrequests (PHP >= 4.3.3)</A
- ></H3
- ><P
- >
The NSAPI module now supports the <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > function
- (alias: <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- >)
- 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.
- </P
- ><P
- >
Under Unix this is not a problem, because the module automatically looks
- for the needed functions and uses them if available.
- If not, <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > is disabled.
- </P
- ><P
- >
Under Windows limitations in the DLL handling need the use of a automatic
- detection of the most recent <TT
- CLASS="filename"
- >ns-httpdXX.dll</TT
- > file.
- This is tested for servers till version 6.1. If a newer version of the
- Sun server is used, the detection fails and <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- >
- is disabled.
- </P
- ><P
- >
If this is the case, try the following:
- Add the following parameter to <VAR
- CLASS="literal"
- >php4_init</VAR
- > in
- <TT
- CLASS="filename"
- >magnus.conf</TT
- >/<TT
- CLASS="filename"
- >obj.conf</TT
- >:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Init fn=php4_init ... server_lib="ns-httpdXX.dll"</PRE
- ></TD
- ></TR
- ></TABLE
- >
- where <VAR
- CLASS="literal"
- >XX</VAR
- > 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.
- </P
- ><P
- >
You can check the status by using the <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > function.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- But be warned: Support for <A
- HREF="#function.nsapi-virtual"
- ><B
- CLASS="function"
- >nsapi_virtual()</B
- ></A
- > is EXPERIMENTAL!!!
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.omnihttpd"
- >OmniHTTPd Server</A
- ></H2
- ><P
- >
This section contains notes and hints specific to
- <A
- HREF="http://www.omnicron.ca/"
- TARGET="_top"
- >OmniHTTPd</A
- > on Windows.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You should read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
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.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Important for CGI users: </B
- >
- Read the <A
- HREF="#faq.installation.forceredirect"
- >faq
- on cgi.force_redirect</A
- > for important details. This
- directive needs to be set to <VAR
- CLASS="literal"
- >0</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
Install OmniHTTPd server.
- </P
- ></LI
- ><LI
- ><P
- >
Right click on the blue OmniHTTPd icon in the system
- tray and select <VAR
- CLASS="literal"
- >Properties</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
Click on <VAR
- CLASS="literal"
- >Web Server Global Settings</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
On the 'External' tab, enter: <VAR
- CLASS="literal"
- >virtual = .php
- | actual = c:\php\php.exe</VAR
- > (use
- <TT
- CLASS="filename"
- >php-cgi.exe</TT
- > if installing PHP 5), and use the Add
- button.
- </P
- ></LI
- ><LI
- ><P
- >
On the <VAR
- CLASS="literal"
- >Mime</VAR
- > tab, enter:
- <VAR
- CLASS="literal"
- >virtual = wwwserver/stdcgi | actual = .php</VAR
- >,
- and use the Add button.
- </P
- ></LI
- ><LI
- ><P
- >
Click <VAR
- CLASS="literal"
- >OK</VAR
- >
- </P
- ></LI
- ></OL
- >
- </P
- ><P
- >
Repeat steps 2 - 6 for each extension you want to associate with PHP.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.sambar"
- >Sambar Server on Microsoft Windows</A
- ></H2
- ><P
- >
This section contains notes and hints specific to the
- <A
- HREF="http://www.sambar.com/"
- TARGET="_top"
- >Sambar Server</A
- > for Windows.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You should read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
This list describes how to set up the ISAPI module to
- work with the Sambar server on Windows.
- </P
- ><P
- >
<P
- ></P
- ><UL
- ><LI
- ><P
- >
Find the file called <TT
- CLASS="filename"
- >mappings.ini</TT
- > (in the config
- directory) in the Sambar install directory.
- </P
- ></LI
- ><LI
- ><P
- >
Open <TT
- CLASS="filename"
- >mappings.ini</TT
- > and add the following line
- under <VAR
- CLASS="literal"
- >[ISAPI]</VAR
- >:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1659"
- ></A
- ><P
- ><B
- >Example 6-7. ISAPI configuration of Sambar</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >#for PHP 4
- *.php = c:\php\php4isapi.dll
-
- #for PHP 5
- *.php = c:\php\php5isapi.dll</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- (This line assumes that PHP was installed in
- <TT
- CLASS="filename"
- >c:\php</TT
- >.)
- </P
- ></LI
- ><LI
- ><P
- >
Now restart the Sambar server for the changes to take effect.
- </P
- ></LI
- ></UL
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.xitami"
- >Xitami on Microsoft Windows</A
- ></H2
- ><P
- >
This section contains notes and hints specific to
- <A
- HREF="http://www.xitami.com/"
- TARGET="_top"
- >Xitami</A
- > on Windows.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You should read the <A
- HREF="#install.windows.manual"
- >manual
- installation steps</A
- > first!
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
This list describes how to set up the PHP CGI binary
- to work with Xitami on Windows.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Important for CGI users: </B
- >
- Read the <A
- HREF="#faq.installation.forceredirect"
- >faq
- on cgi.force_redirect</A
- > for important details. This
- directive needs to be set to <VAR
- CLASS="literal"
- >0</VAR
- >.
- If you want to use <VAR
- CLASS="literal"
- >$_SERVER['PHP_SELF']</VAR
- > you have to
- enable the <A
- HREF="#ini.cgi.fix-pathinfo"
- >cgi.fix_pathinfo</A
- >
- directive.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >By using the CGI setup, your server
- is open to several possible attacks. Please read our
- <A
- HREF="#security.cgi-bin"
- >CGI security section</A
- > to learn how to
- defend yourself from those attacks.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
<P
- ></P
- ><UL
- ><LI
- ><P
- >
Make sure the webserver is running, and point
- your browser to xitamis admin console
- (usually <VAR
- CLASS="literal"
- >http://127.0.0.1/admin</VAR
- >),
- and click on Configuration.
- </P
- ></LI
- ><LI
- ><P
- >
Navigate to the Filters, and put the
- extension which PHP should parse (i.e. .php)
- into the field File extensions (.xxx).
- </P
- ></LI
- ><LI
- ><P
- >
In Filter command or script put the path and name
- of your PHP CGI executable i.e. <TT
- CLASS="filename"
- >C:\php\php.exe</TT
- >
- for PHP 4, or <TT
- CLASS="filename"
- >C:\php\php-cgi.exe</TT
- > for PHP 5.
- </P
- ></LI
- ><LI
- ><P
- >
Press the 'Save' icon.
- </P
- ></LI
- ><LI
- ><P
- >
Restart the server to reflect changes.
- </P
- ></LI
- ></UL
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.building"
- >Building from source</A
- ></H2
- ><P
- >
Before getting started, it is worthwhile answering the question:
- "Why is building on Windows so hard?" Two reasons come to mind:
- </P
- ><P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
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.
- </P
- ></LI
- ><LI
- ><P
- >
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.
- </P
- ></LI
- ></OL
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.building.requirement"
- >Requirements</A
- ></H3
- ><P
- >
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 <A
- HREF="http://www.info-zip.org/pub/infozip/"
- TARGET="_top"
- >InfoZip</A
- >.
- </P
- ><P
- >
Before you get started, you have to download...
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
..the win32 buildtools from the PHP site
- at <A
- HREF="http://www.php.net/extra/win32build.zip"
- TARGET="_top"
- >http://www.php.net/extra/win32build.zip</A
- >.
- </P
- ></LI
- ><LI
- ><P
- >
..the source code for the DNS name resolver used by PHP from
- <A
- HREF="http://www.php.net/extra/bindlib_w32.zip"
- TARGET="_top"
- >
http://www.php.net/extra/bindlib_w32.zip</A
- >. This is a replacement for the
- <TT
- CLASS="filename"
- >resolv.lib</TT
- > library included in <TT
- CLASS="filename"
- >
win32build.zip</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
If you plan to compile PHP as a Apache
- module you will also need the <A
- HREF="http://www.apache.org/dist/httpd/"
- TARGET="_top"
- >Apache
- sources</A
- >.
- </P
- ></LI
- ></UL
- ><P
- >
Finally, you are going to need the source to PHP itself. You can get
- the latest development version using <A
- HREF="http://www.php.net/anoncvs.php"
- TARGET="_top"
- >
anonymous CVS</A
- >, a <A
- HREF="http://snaps.php.net/"
- TARGET="_top"
- >
snapshot</A
- > or the most recent released <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >
source</A
- > tarball.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.building.install"
- >Putting it all together</A
- ></H3
- ><P
- >
After downloading the required packages you have to extract them in a
- proper place.
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Create a working directory where all files end up after extracting, e.g:
- <TT
- CLASS="filename"
- >C:\work</TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
Create the directory <TT
- CLASS="filename"
- >win32build</TT
- > under your
- working directory (<TT
- CLASS="filename"
- >C:\work</TT
- >) and unzip <TT
- CLASS="filename"
- >
win32build.zip</TT
- > into it.
- </P
- ></LI
- ><LI
- ><P
- >
Create the directory <TT
- CLASS="filename"
- >bindlib_w32</TT
- > under your
- working directory (<TT
- CLASS="filename"
- >C:\work</TT
- >) and unzip <TT
- CLASS="filename"
- >
bindlib_w32.zip</TT
- > into it.
- </P
- ></LI
- ><LI
- ><P
- >
Extract the downloaded PHP source code into your working directory
- (<TT
- CLASS="filename"
- >C:\work</TT
- >).
- </P
- ></LI
- ></UL
- >
- Following this steps your directory structure looks like this:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN1747"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >+--c:\work
- | |
- | +--bindlib_w32
- | | |
- | | +--arpa
- | | |
- | | +--conf
- | | |
- | | +--...
- | |
- | +--php-4.x.x
- | | |
- | | +--build
- | | |
- | | +--...
- | | |
- | | +--win32
- | | |
- | | +--...
- | |
- | +--win32build
- | | |
- | | +--bin
- | | |
- | | +--include
- | | |
- | | +--lib</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- Create the directories <TT
- CLASS="filename"
- >c:\usr\local\lib</TT
- >. Copy
- <TT
- CLASS="filename"
- >bison.simple</TT
- > from <TT
- CLASS="filename"
- >c:\work\win32build\bin
- </TT
- > to <TT
- CLASS="filename"
- >c:\usr\local\lib</TT
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="http://www.cygwin.com/"
- TARGET="_top"
- >Cygwin</A
- > users may omit the last
- step. A properly installed Cygwin environment provides the mandatory
- files <TT
- CLASS="filename"
- >bison.simple</TT
- > and
- <TT
- CLASS="filename"
- >bison.exe</TT
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.building.configure"
- >Configure MVC ++</A
- ></H3
- ><P
- >
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:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Executable files: <TT
- CLASS="filename"
- >c:\work\win32build\bin</TT
- >,
- Cygwin users: <TT
- CLASS="filename"
- >cygwin\bin</TT
- >
- </P
- ></LI
- ><LI
- ><P
- >
Include files: <TT
- CLASS="filename"
- >c:\work\win32build\include</TT
- >
- </P
- ></LI
- ><LI
- ><P
- >
Library files: <TT
- CLASS="filename"
- >c:\work\win32build\lib</TT
- >
- </P
- ></LI
- ></UL
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.building.resolvlib"
- >Build resolv.lib</A
- ></H3
- ><P
- >
You must build the <TT
- CLASS="filename"
- >resolv.lib</TT
- > library.
- Decide whether you want to have debug symbols available
- (bindlib - Win32 Debug) or not (bindlib - Win32 Release).
- Build the appropriate configuration:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
For GUI users, launch VC++, and then select File => Open
- Workspace, navigate to <TT
- CLASS="filename"
- >c:\work\bindlib_w32</TT
- > and
- select <TT
- CLASS="filename"
- >bindlib.dsw</TT
- >. Then select Build=>Set
- Active Configuration and select the desired configuration.
- Finally select Build=>Rebuild All.
- </P
- ></LI
- ><LI
- ><P
- >
For command line users, make sure that you either have the C++
- environment variables registered, or have run
- <B
- CLASS="command"
- >vcvars.bat</B
- >, and then execute one of the following
- commands:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >msdev bindlib.dsp /MAKE "bindlib - Win32 Debug"</KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >msdev bindlib.dsp /MAKE "bindlib - Win32 Release"</KBD
- >
- </P
- ></LI
- ></UL
- ></LI
- ></UL
- >
- At this point, you should have a usable <TT
- CLASS="filename"
- >resolv.lib</TT
- >
- in either your <TT
- CLASS="filename"
- >c:\work\bindlib_w32\Debug</TT
- > or
- <TT
- CLASS="filename"
- >Release</TT
- > subdirectories. Copy this file into your
- <TT
- CLASS="filename"
- >c:\work\win32build\lib</TT
- > directory over the file
- by the same name found in there.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="install.windows.building.compile"
- >Compiling</A
- ></H3
- ><P
- >
The best way to get started is to build the CGI version.
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
For GUI users, launch VC++, and then select File => Open
- Workspace and select <TT
- CLASS="filename"
- >c:\work\php-4.x.x\win32\php4ts.dsw
- </TT
- >. Then select Build=>Set Active
- Configuration and select the desired configuration, either
- <VAR
- CLASS="literal"
- >php4ts - Win32 Debug_TS</VAR
- > or
- <VAR
- CLASS="literal"
- >php4ts - Win32 Release_TS</VAR
- >. Finally select
- Build=>Rebuild All.
- </P
- ></LI
- ><LI
- ><P
- >
For command line users, make sure that you either have
- the C++ environment variables registered, or have run
- <B
- CLASS="command"
- >vcvars.bat</B
- >, and then execute one of the
- following commands from the <TT
- CLASS="filename"
- >c:\work\php-4.x.x\win32
- </TT
- > directory:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >msdev php4ts.dsp /MAKE "php4ts - Win32 Debug_TS"</KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
<KBD
- CLASS="userinput"
- >msdev php4ts.dsp /MAKE "php4ts - Win32 Release_TS"</KBD
- >
- </P
- ></LI
- ><LI
- ><P
- >
At this point, you should have a usable <TT
- CLASS="filename"
- >php.exe</TT
- >
- in either your <TT
- CLASS="filename"
- >c:\work\php-4.x.x.\Debug_TS</TT
- > or
- <TT
- CLASS="filename"
- >Release_TS</TT
- > subdirectories.
- </P
- ></LI
- ></UL
- ></LI
- ></UL
- ><P
- >
It is possible to do minor customization to the build process by editing
- the <TT
- CLASS="filename"
- >main/config.win32.h</TT
- > file. For example you can
- change the default location of <TT
- CLASS="filename"
- >php.ini</TT
- >, the built-in extensions, and the
- default location for your extensions.
- </P
- ><P
- >
Next you may want to build the CLI version which is designed to use
- <A
- HREF="#features.commandline"
- >PHP from the command line</A
- >.
- The steps are the same as for building the CGI version, except you have
- to select the <VAR
- CLASS="literal"
- >php4ts_cli - Win32 Debug_TS</VAR
- > or
- <VAR
- CLASS="literal"
- >php4ts_cli - Win32 Release_TS</VAR
- > project file. After a
- successful compiling run you will find the <TT
- CLASS="filename"
- >php.exe</TT
- >
- in either the directory <TT
- CLASS="filename"
- >Release_TS\cli\</TT
- > or
- <TT
- CLASS="filename"
- >Debug_TS\cli\</TT
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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 <A
- HREF="http://pear.php.net/manual/"
- TARGET="_top"
- >
PEAR</A
- > website.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
In order to build the SAPI module (<TT
- CLASS="filename"
- >php4isapi.dll</TT
- >)
- for integrating PHP with Microsoft IIS, set your active configuration to
- <TT
- CLASS="filename"
- >php4isapi-whatever-config</TT
- > and build the desired dll.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.windows.extensions"
- >Installation of extensions on Windows</A
- ></H2
- ><P
- >
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
- <TT
- CLASS="filename"
- >php.ini</TT
- >. You can also load a module dynamically in your script using
- <A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- >.
- </P
- ><P
- >
The DLLs for PHP extensions are prefixed with <VAR
- CLASS="literal"
- >php_</VAR
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 4.3.1 BCMath, Calendar, COM, Ctype, FTP, MySQL, ODBC, Overload,
- PCRE, Session, Tokenizer, WDDX, XML and Zlib support is
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >built in</I
- ></SPAN
- >. You don't need to load any additional
- extensions in order to use these functions. See your distributions
- <TT
- CLASS="filename"
- >README.txt</TT
- > or <TT
- CLASS="filename"
- >install.txt</TT
- >
- or <A
- HREF="#install.windows.extensions.overview"
- >this table</A
- >
- for a list of built in modules.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The default location PHP searches for extensions is
- <TT
- CLASS="filename"
- >c:\php4\extensions</TT
- > in PHP 4 and
- <TT
- CLASS="filename"
- >c:\php5</TT
- > in PHP 5. To change this
- setting to reflect your setup of PHP edit your <TT
- CLASS="filename"
- >php.ini</TT
- > file:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
You will need to change the
- <A
- HREF="#ini.extension-dir"
- >extension_dir</A
- > setting to
- point to the directory where your extensions lives, or where you have
- placed your <TT
- CLASS="filename"
- >php_*.dll</TT
- > files. Please do not
- forget the last backslash. For example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN1858"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- >extension_dir = c:/php/extensions/</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></LI
- ><LI
- ><P
- >
Enable the extension(s) in <TT
- CLASS="filename"
- >php.ini</TT
- > you want to use by uncommenting the
- <VAR
- CLASS="literal"
- >extension=php_*.dll</VAR
- > lines in <TT
- CLASS="filename"
- >php.ini</TT
- >. This is done
- by deleting the leading ; form the extension you want to load.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN1865"
- ></A
- ><P
- ><B
- >Example 6-8. Enable <A
- HREF="#ref.bzip2"
- >Bzip2</A
- > extension for PHP-Windows</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- >// change the following line from ...
- ;extension=php_bz2.dll
-
- // ... to
- extension=php_bz2.dll</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Some of the extensions need extra DLLs to work. Couple of them can be
- found in the distribution package, in the
- <TT
- CLASS="filename"
- >C:\php\dlls\</TT
- > folder in PHP 4 or
- in the main folder in PHP 5, but some, for example Oracle
- (<TT
- CLASS="filename"
- >php_oci8.dll</TT
- >) require DLLs which are not bundled
- with the distribution package. If you are installing PHP 4, copy the
- bundled DLLs from <TT
- CLASS="filename"
- >C:\php\dlls</TT
- >
- folder to the main <TT
- CLASS="filename"
- >C:\php</TT
- >
- folder. Don't forget to include <TT
- CLASS="filename"
- >C:\php</TT
- > in the system
- <VAR
- CLASS="varname"
- >PATH</VAR
- > (this process is explained in a separate <A
- HREF="#faq.installation.addtopath"
- >FAQ entry</A
- >).
- </P
- ></LI
- ></UL
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you are running a server module version of PHP
- remember to restart your webserver to reflect your changes to <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
The following table describes some of the extensions available and required
- additional dlls.
- <DIV
- CLASS="table"
- ><A
- NAME="install.windows.extensions.overview"
- ></A
- ><P
- ><B
- >Table 6-1. PHP Extensions</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Extension</TH
- ><TH
- >Description</TH
- ><TH
- >Notes</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >php_bz2.dll</TD
- ><TD
- ><A
- HREF="#ref.bzip2"
- >bzip2</A
- > compression functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_calendar.dll</TD
- ><TD
- ><A
- HREF="#ref.calendar"
- >Calendar</A
- > conversion functions</TD
- ><TD
- >Built in since PHP 4.0.3</TD
- ></TR
- ><TR
- ><TD
- >php_cpdf.dll</TD
- ><TD
- ><A
- HREF="#ref.cpdf"
- >ClibPDF</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_crack.dll</TD
- ><TD
- ><A
- HREF="#ref.crack"
- >Crack</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_ctype.dll</TD
- ><TD
- ><A
- HREF="#ref.ctype"
- >ctype</A
- > family functions</TD
- ><TD
- >Built in since PHP 4.3.0</TD
- ></TR
- ><TR
- ><TD
- >php_curl.dll</TD
- ><TD
- ><A
- HREF="#ref.curl"
- >CURL</A
- >, Client URL library functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >libeay32.dll</TT
- >,
- <TT
- CLASS="filename"
- >ssleay32.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_cybercash.dll</TD
- ><TD
- ><A
- HREF="#ref.cybercash"
- >Cybercash</A
- > payment functions</TD
- ><TD
- >PHP <= 4.2.0</TD
- ></TR
- ><TR
- ><TD
- >php_db.dll</TD
- ><TD
- ><A
- HREF="#ref.dbm"
- >DBM</A
- > functions</TD
- ><TD
- >Deprecated. Use DBA instead (<TT
- CLASS="filename"
- >php_dba.dll</TT
- >)</TD
- ></TR
- ><TR
- ><TD
- >php_dba.dll</TD
- ><TD
- ><A
- HREF="#ref.dba"
- >DBA</A
- >: DataBase (dbm-style)
- Abstraction layer functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_dbase.dll</TD
- ><TD
- ><A
- HREF="#ref.dbase"
- >dBase</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_dbx.dll</TD
- ><TD
- ><A
- HREF="#ref.dbx"
- >dbx</A
- > functions</TD
- ><TD
- > </TD
- ></TR
- ><TR
- ><TD
- >php_domxml.dll</TD
- ><TD
- ><A
- HREF="#ref.domxml"
- >DOM XML</A
- > functions</TD
- ><TD
- >
PHP <= 4.2.0 requires: <TT
- CLASS="filename"
- >libxml2.dll</TT
- > (bundled)
- PHP >= 4.3.0 requires: <TT
- CLASS="filename"
- >iconv.dll</TT
- > (bundled)
- </TD
- ></TR
- ><TR
- ><TD
- >php_dotnet.dll</TD
- ><TD
- ><A
- HREF="#ref.dotnet"
- >.NET</A
- > functions</TD
- ><TD
- >PHP <= 4.1.1</TD
- ></TR
- ><TR
- ><TD
- >php_exif.dll</TD
- ><TD
- ><A
- HREF="#ref.exif"
- >EXIF</A
- > functions</TD
- ><TD
- >
<A
- HREF="#ref.mbstring"
- >php_mbstring.dll</A
- >. And,
- <TT
- CLASS="filename"
- >php_exif.dll</TT
- > must be loaded <VAR
- CLASS="literal"
- >after</VAR
- >
- <TT
- CLASS="filename"
- >php_mbstring.dll</TT
- > in <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </TD
- ></TR
- ><TR
- ><TD
- >php_fbsql.dll</TD
- ><TD
- ><A
- HREF="#ref.fbsql"
- >FrontBase</A
- > functions</TD
- ><TD
- >PHP <= 4.2.0</TD
- ></TR
- ><TR
- ><TD
- >php_fdf.dll</TD
- ><TD
- ><A
- HREF="#ref.fdf"
- >FDF</A
- >: Forms Data Format functions.</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >fdftk.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_filepro.dll</TD
- ><TD
- ><A
- HREF="#ref.filepro"
- >filePro</A
- > functions</TD
- ><TD
- >Read-only access</TD
- ></TR
- ><TR
- ><TD
- >php_ftp.dll</TD
- ><TD
- ><A
- HREF="#ref.ftp"
- >FTP</A
- > functions</TD
- ><TD
- >Built-in since PHP 4.0.3</TD
- ></TR
- ><TR
- ><TD
- >php_gd.dll</TD
- ><TD
- ><A
- HREF="#ref.image"
- >GD</A
- > library image functions</TD
- ><TD
- >
Removed in PHP 4.3.2. Also note that truecolor functions are not
- available in GD1, instead, use <TT
- CLASS="filename"
- >php_gd2.dll</TT
- >.
- </TD
- ></TR
- ><TR
- ><TD
- >php_gd2.dll</TD
- ><TD
- ><A
- HREF="#ref.image"
- >GD</A
- > library image functions</TD
- ><TD
- >GD2</TD
- ></TR
- ><TR
- ><TD
- >php_gettext.dll</TD
- ><TD
- ><A
- HREF="#ref.gettext"
- >Gettext</A
- > functions</TD
- ><TD
- >
PHP <= 4.2.0 requires <TT
- CLASS="filename"
- >gnu_gettext.dll</TT
- > (bundled),
- PHP >= 4.2.3 requires <TT
- CLASS="filename"
- >libintl-1.dll</TT
- >,
- <TT
- CLASS="filename"
- >iconv.dll</TT
- > (bundled).
- </TD
- ></TR
- ><TR
- ><TD
- >php_hyperwave.dll</TD
- ><TD
- ><A
- HREF="#ref.hw"
- >HyperWave</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_iconv.dll</TD
- ><TD
- ><A
- HREF="#ref.iconv"
- >ICONV</A
- > characterset conversion</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >iconv-1.3.dll</TT
- > (bundled),
- PHP >=4.2.1 <TT
- CLASS="filename"
- >iconv.dll</TT
- ></TD
- ></TR
- ><TR
- ><TD
- >php_ifx.dll</TD
- ><TD
- ><A
- HREF="#ref.ifx"
- >Informix</A
- > functions</TD
- ><TD
- >Requires: Informix libraries</TD
- ></TR
- ><TR
- ><TD
- >php_iisfunc.dll</TD
- ><TD
- >IIS management functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_imap.dll</TD
- ><TD
- ><A
- HREF="#ref.imap"
- >IMAP</A
- > POP3 and NNTP functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_ingres.dll</TD
- ><TD
- ><A
- HREF="#ref.ingres"
- >Ingres II</A
- > functions</TD
- ><TD
- >Requires: Ingres II libraries</TD
- ></TR
- ><TR
- ><TD
- >php_interbase.dll</TD
- ><TD
- ><A
- HREF="#ref.ibase"
- >InterBase</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >gds32.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_java.dll</TD
- ><TD
- ><A
- HREF="#ref.java"
- >Java</A
- > functions</TD
- ><TD
- >PHP <= 4.0.6 requires: <TT
- CLASS="filename"
- >jvm.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_ldap.dll</TD
- ><TD
- ><A
- HREF="#ref.ldap"
- >LDAP</A
- > functions</TD
- ><TD
- >
PHP <= 4.2.0 requires <TT
- CLASS="filename"
- >libsasl.dll</TT
- > (bundled),
- PHP >= 4.3.0 requires <TT
- CLASS="filename"
- >libeay32.dll</TT
- >,
- <TT
- CLASS="filename"
- >ssleay32.dll</TT
- > (bundled)
- </TD
- ></TR
- ><TR
- ><TD
- >php_mbstring.dll</TD
- ><TD
- ><A
- HREF="#ref.mbstring"
- >Multi-Byte String</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_mcrypt.dll</TD
- ><TD
- ><A
- HREF="#ref.mcrypt"
- >Mcrypt Encryption</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >libmcrypt.dll</TT
- ></TD
- ></TR
- ><TR
- ><TD
- >php_mhash.dll</TD
- ><TD
- ><A
- HREF="#ref.mhash"
- >Mhash</A
- > functions</TD
- ><TD
- >PHP >= 4.3.0 requires: <TT
- CLASS="filename"
- >libmhash.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_mime_magic.dll</TD
- ><TD
- ><A
- HREF="#ref.mime-magic"
- >Mimetype</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >magic.mime</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_ming.dll</TD
- ><TD
- ><A
- HREF="#ref.ming"
- >Ming</A
- > functions for Flash</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_msql.dll</TD
- ><TD
- ><A
- HREF="#ref.msql"
- >mSQL</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >msql.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_mssql.dll</TD
- ><TD
- ><A
- HREF="#ref.mssql"
- >MSSQL</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >ntwdblib.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_mysql.dll</TD
- ><TD
- ><A
- HREF="#ref.mysql"
- >MySQL</A
- > functions</TD
- ><TD
- >PHP >= 5.0.0, requires <TT
- CLASS="filename"
- >libmysql.dll</TT
- >
- (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_mysqli.dll</TD
- ><TD
- ><A
- HREF="#ref.mysqli"
- >MySQLi</A
- > functions</TD
- ><TD
- >PHP >= 5.0.0, requires <TT
- CLASS="filename"
- >libmysql.dll</TT
- >
- (<TT
- CLASS="filename"
- >libmysqli.dll</TT
- > in PHP <= 5.0.2) (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_oci8.dll</TD
- ><TD
- ><A
- HREF="#ref.oci8"
- >Oracle 8</A
- > functions</TD
- ><TD
- >Requires: Oracle 8.1+ client libraries</TD
- ></TR
- ><TR
- ><TD
- >php_openssl.dll</TD
- ><TD
- ><A
- HREF="#ref.openssl"
- >OpenSSL</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >libeay32.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_oracle.dll</TD
- ><TD
- ><A
- HREF="#ref.oracle"
- >Oracle</A
- > functions</TD
- ><TD
- >Requires: Oracle 7 client libraries</TD
- ></TR
- ><TR
- ><TD
- >php_overload.dll</TD
- ><TD
- ><A
- HREF="#ref.overload"
- >Object overloading</A
- > functions</TD
- ><TD
- >Built in since PHP 4.3.0</TD
- ></TR
- ><TR
- ><TD
- >php_pdf.dll</TD
- ><TD
- ><A
- HREF="#ref.pdf"
- >PDF</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_pgsql.dll</TD
- ><TD
- ><A
- HREF="#ref.pgsql"
- >PostgreSQL</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_printer.dll</TD
- ><TD
- ><A
- HREF="#ref.printer"
- >Printer</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_shmop.dll</TD
- ><TD
- ><A
- HREF="#ref.shmop"
- >Shared Memory</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_snmp.dll</TD
- ><TD
- ><A
- HREF="#ref.snmp"
- >SNMP</A
- > get and walk functions</TD
- ><TD
- >NT only!</TD
- ></TR
- ><TR
- ><TD
- >php_soap.dll</TD
- ><TD
- ><A
- HREF="#ref.soap"
- >SOAP</A
- > functions</TD
- ><TD
- >PHP >= 5.0.0</TD
- ></TR
- ><TR
- ><TD
- >php_sockets.dll</TD
- ><TD
- ><A
- HREF="#ref.sockets"
- >Socket</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_sybase_ct.dll</TD
- ><TD
- ><A
- HREF="#ref.sybase"
- >Sybase</A
- > functions</TD
- ><TD
- >Requires: Sybase client libraries</TD
- ></TR
- ><TR
- ><TD
- >php_tidy.dll</TD
- ><TD
- ><A
- HREF="#ref.tidy"
- >Tidy</A
- > functions</TD
- ><TD
- >PHP >= 5.0.0</TD
- ></TR
- ><TR
- ><TD
- >php_tokenizer.dll</TD
- ><TD
- ><A
- HREF="#ref.tokenizer"
- >Tokenizer</A
- > functions</TD
- ><TD
- >Built in since PHP 4.3.0</TD
- ></TR
- ><TR
- ><TD
- >php_w32api.dll</TD
- ><TD
- ><A
- HREF="#ref.w32api"
- >W32api</A
- > functions</TD
- ><TD
- >None</TD
- ></TR
- ><TR
- ><TD
- >php_xmlrpc.dll</TD
- ><TD
- ><A
- HREF="#ref.xmlrpc"
- >XML-RPC</A
- > functions</TD
- ><TD
- >PHP >= 4.2.1 requires: <TT
- CLASS="filename"
- >iconv.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_xslt.dll</TD
- ><TD
- ><A
- HREF="#ref.xslt"
- >XSLT</A
- > functions</TD
- ><TD
- >
PHP <= 4.2.0 requires <TT
- CLASS="filename"
- >sablot.dll</TT
- >,
- <TT
- CLASS="filename"
- >expat.dll</TT
- > (bundled). PHP >= 4.2.1 requires
- <TT
- CLASS="filename"
- >sablot.dll</TT
- >, <TT
- CLASS="filename"
- >expat.dll</TT
- >,
- <TT
- CLASS="filename"
- >iconv.dll</TT
- > (bundled).
- </TD
- ></TR
- ><TR
- ><TD
- >php_yaz.dll</TD
- ><TD
- ><A
- HREF="#ref.yaz"
- >YAZ</A
- > functions</TD
- ><TD
- >Requires: <TT
- CLASS="filename"
- >yaz.dll</TT
- > (bundled)</TD
- ></TR
- ><TR
- ><TD
- >php_zip.dll</TD
- ><TD
- ><A
- HREF="#ref.zip"
- >Zip File</A
- > functions</TD
- ><TD
- >Read only access</TD
- ></TR
- ><TR
- ><TD
- >php_zlib.dll</TD
- ><TD
- ><A
- HREF="#ref.zlib"
- >ZLib</A
- > compression functions</TD
- ><TD
- >Built in since PHP 4.3.0</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.pecl"
- >Chapter 7. Installation of PECL extensions</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.intro"
- >Introduction to PECL Installations</A
- ></H2
- ><P
- >
PHP extensions may be installed in a variety of ways.
- <A
- HREF="http://pecl.php.net"
- TARGET="_top"
- >PECL</A
- > is a repository of PHP extensions
- living within the <A
- HREF="http://pear.php.net/"
- TARGET="_top"
- >PEAR</A
- > structure, and
- the following demonstrates how to install these extensions.
- </P
- ><P
- >
These instructions assume <VAR
- CLASS="literal"
- >/your/phpsrcdir/</VAR
- > is the path
- to the PHP source, and <VAR
- CLASS="literal"
- >extname</VAR
- > is the name of the
- PECL extension. Adjust accordingly. These instructions also assume a
- familiarity with the <A
- HREF="http://pear.php.net/manual/en/installation.cli.php"
- TARGET="_top"
- >pear command</A
- >.
- </P
- ><P
- >
Shared extensions may be installed by including them inside of <TT
- CLASS="filename"
- >php.ini</TT
- >
- using the <A
- HREF="#ini.extension"
- >extension</A
- > PHP directive. See
- also the <A
- HREF="#ini.extension-dir"
- >extensions_dir</A
- >
- directive, and <A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- >. The installation methods described
- below do not automatically configure PHP to include these extensions, this
- step must be done manually.
- </P
- ><P
- >
When building PHP modules, it's important to have the appropriate versions
- of the required tools (autoconf, automake, libtool, etc.) See the
- <A
- HREF="http://www.php.net/anoncvs.php"
- TARGET="_top"
- >Anonymous CVS Instructions</A
- > for
- details on the required tools, and required versions.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.downloads"
- >Downloading PECL extensions</A
- ></H2
- ><P
- >
There are several options for downloading PECL extensions, such as:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="http://pecl.php.net"
- TARGET="_top"
- >http://pecl.php.net</A
- >
- </P
- ><P
- >
Listed here is information like the ChangeLog, release information,
- requirements, revisions, etc. Although not every PECL extension has a
- webpage, most do.
- </P
- ></LI
- ><LI
- ><P
- >
<VAR
- CLASS="literal"
- >pear download extname</VAR
- >
- </P
- ><P
- >
The <A
- HREF="http://pear.php.net/manual/en/installation.cli.php"
- TARGET="_top"
- >pear command</A
- > may also be used
- to download source files. Specific revisions may also be specified.
- </P
- ></LI
- ><LI
- ><P
- >
<ACRONYM
- CLASS="acronym"
- >CVS</ACRONYM
- >
- </P
- ><P
- >
All PECL files reside in <ACRONYM
- CLASS="acronym"
- >CVS</ACRONYM
- >. A web-based view may
- be seen at <A
- HREF="http://cvs.php.net/pecl/"
- TARGET="_top"
- >http://cvs.php.net/pecl/</A
- >.
- To download straight from <ACRONYM
- CLASS="acronym"
- >CVS</ACRONYM
- >, consider the following
- where <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >phpfi</I
- ></SPAN
- > is the password for user
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >cvsread</I
- ></SPAN
- >:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ cvs -d:pserver:cvsread@cvs.php.net:/repository login
- $ cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/extname</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Windows downloads
- </P
- ><P
- >
Windows users may find compiled PECL binaries by downloading the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >Collection of PECL modules</I
- ></SPAN
- > from the
- <A
- HREF="http://www.php.net/downloads.php"
- TARGET="_top"
- >PHP Downloads</A
- > page, and by
- retrieving a <A
- HREF="http://snaps.php.net/"
- TARGET="_top"
- >PECL Snapshot</A
- >. To
- compile PHP under Windows, read the
- <A
- HREF="http://cvs.php.net/co.php/php-src/README.WIN32-BUILD-SYSTEM"
- TARGET="_top"
- >Win32 Build README</A
- >.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.windows"
- >PECL for Windows users</A
- ></H2
- ><P
- >
Like with any other PHP extension <ACRONYM
- CLASS="acronym"
- >DLL</ACRONYM
- >, to install move
- the PECL extension DLLs into the <A
- HREF="#ini.extension-dir"
- >
extension_dir</A
- > folder and include them within <TT
- CLASS="filename"
- >php.ini</TT
- >. For
- example:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >extension=php_extname.dll</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
After doing this, restart the web server.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.pear"
- >Compiling shared PECL extensions with PEAR</A
- ></H2
- ><P
- >
PEAR makes it easy to create shared PHP extensions. Using the
- <A
- HREF="http://pear.php.net/manual/en/installation.cli.php"
- TARGET="_top"
- >pear command</A
- >, do the following:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ pear install extname</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
That will download the source for <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >extname</I
- ></SPAN
- >, and
- compile it on the system. This results in an
- <TT
- CLASS="filename"
- >extname.so</TT
- > file that may then be included in <TT
- CLASS="filename"
- >php.ini</TT
- >
- </P
- ><P
- >
In case the systems <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >preferred_state</I
- ></SPAN
- > is set higher than
- an available <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >extname</I
- ></SPAN
- > version, like it's set to stable
- and the extension is still in beta, either alter the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >preferred_state</I
- ></SPAN
- > via <VAR
- CLASS="literal"
- >pear config-set</VAR
- >
- or specify a specific version of the PECL extension. For example:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ pear install extname-0.1.1</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Regardless, pear will copy this <TT
- CLASS="filename"
- >extname.so</TT
- > into the
- <A
- HREF="#ini.extension-dir"
- >extensions directory</A
- >. Adjust
- <TT
- CLASS="filename"
- >php.ini</TT
- > accordingly.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.phpize"
- >Compiling shared PECL extensions with phpize</A
- ></H2
- ><P
- >
If using pear is not an option, like for building shared PECL extensions
- from <ACRONYM
- CLASS="acronym"
- >CVS</ACRONYM
- >, or for unreleased PECL packages, then creating
- a shared extension may also be done by manually using the
- <VAR
- CLASS="literal"
- >phpize</VAR
- > command. The pear command essentially does this
- but it may also be done manually. Assuming the source file is named
- <TT
- CLASS="filename"
- >extname.tgz</TT
- >, and that it was downloaded into the
- current directory, consider the following:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ pear download extname
- $ gzip -d < extname.tgz | tar -xvf -
- $ cd extname
- $ phpize
- $ ./configure && make</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Upon success, this will create <TT
- CLASS="filename"
- >extname.so</TT
- > and put it
- into the <TT
- CLASS="filename"
- >modules/</TT
- > and/or <TT
- CLASS="filename"
- >.libs/</TT
- >
- directory within the <TT
- CLASS="filename"
- >extname/</TT
- > source. Move this
- shared extension (<TT
- CLASS="filename"
- >extname.so</TT
- >) into the PHP
- <A
- HREF="#ini.extension-dir"
- >extensions directory</A
- >, and adjust
- <TT
- CLASS="filename"
- >php.ini</TT
- > accordingly.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.pecl.static"
- >Compiling PECL extensions statically into PHP</A
- ></H2
- ><P
- >
To statically include the extension within the PHP build, put the
- extensions source into the <TT
- CLASS="filename"
- >ext/</TT
- > directory found in
- the PHP source. For example:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ cd /your/phpsrcdir/ext
- $ pear download extname
- $ gzip -d < extname.tgz | tar -xvf -
- $ mv extname-x.x.x extname
- $ rm package.xml</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This will result in the following directory:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >/your/phpsrcdir/ext/extname</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
From here, build PHP as normal:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ cd /your/phpsrcdir
- $ ./buildconf
- $ ./configure --help
- $ ./configure --with-extname --enable-someotherext --with-foobar
- $ make
- $ make install</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Whether <VAR
- CLASS="literal"
- >--enable-extname</VAR
- > or <VAR
- CLASS="literal"
- >--with-extname
- </VAR
- > is used depends on the extension. Typically an extension that
- does not require external libraries uses <VAR
- CLASS="literal"
- >--enable</VAR
- >. To be
- sure, run the following after buildconf:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ ./configure --help | grep extname</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="install.problems"
- >Chapter 8. Problems?</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="install.problems.faq"
- >Read the FAQ</A
- ></H2
- ><P
- >
Some problems are more common than others. The most
- common ones are listed in the <A
- HREF="#faq"
- >PHP
- FAQ</A
- >, part of this manual.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.problems.support"
- >Other problems</A
- ></H2
- ><P
- >
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 <A
- HREF="http://www.php.net/support.php"
- TARGET="_top"
- >http://www.php.net/support.php</A
- >. To subscribe to the PHP installation
- mailing list, send an empty mail to <A
- HREF="mailto:php-install-subscribe@lists.php.net"
- TARGET="_top"
- >php-install-subscribe@lists.php.net</A
- >.
- The mailing list address is <A
- HREF="mailto:php-install@lists.php.net"
- TARGET="_top"
- >php-install@lists.php.net</A
- >.
- </P
- ><P
- >
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, <A
- HREF="#ini.safe-mode"
- >safe mode</A
- >, etc...), and
- preferably enough code to make others able to reproduce and test
- your problem.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="install.problems.bugs"
- >Bug reports</A
- ></H2
- ><P
- >
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 <A
- HREF="http://bugs.php.net/"
- TARGET="_top"
- >http://bugs.php.net/</A
- >. Please do not
- send bug reports in mailing list or personal letters. The
- bug system is also suitable to submit feature requests.
- </P
- ><P
- >
Read the <A
- HREF="http://bugs.php.net/how-to-report.php"
- TARGET="_top"
- >How to report a bug</A
- >
- document before submitting any bug reports!
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="configuration"
- >Chapter 9. Runtime Configuration</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="configuration.file"
- >The configuration file</A
- ></H2
- ><P
- >
The configuration file (called <TT
- CLASS="filename"
- >php3.ini</TT
- > in
- PHP 3, and simply <TT
- CLASS="filename"
- >php.ini</TT
- > 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
- <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > and <ACRONYM
- CLASS="acronym"
- >CLI</ACRONYM
- > version, it happens on
- every invocation.
- </P
- ><P
- >
The default location of <TT
- CLASS="filename"
- >php.ini</TT
- > is a compile time option (see the <A
- HREF="#faq.installation.phpini"
- >FAQ</A
- > entry), but can be changed
- for the <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > and <ACRONYM
- CLASS="acronym"
- >CLI</ACRONYM
- > version with the
- <VAR
- CLASS="literal"
- >-c</VAR
- > command line switch, see the chapter about using
- PHP from the <A
- HREF="#features.commandline"
- >command line</A
- >. You can also use the
- environment variable <VAR
- CLASS="varname"
- >PHPRC</VAR
- > for an additional path to
- search for a <TT
- CLASS="filename"
- >php.ini</TT
- > file.
- </P
- ><P
- >
If <TT
- CLASS="filename"
- >php-SAPI.ini</TT
- > exists (where SAPI is used SAPI, so the
- filename is e.g. <TT
- CLASS="filename"
- >php-cli.ini</TT
- > or
- <TT
- CLASS="filename"
- >php-apache.ini</TT
- >), it's used instead of <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The Apache web server changes the directory to root at startup causing
- PHP to attempt to read <TT
- CLASS="filename"
- >php.ini</TT
- > from the root filesystem if it exists.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The <TT
- CLASS="filename"
- >php.ini</TT
- > directives handled by extensions are documented respectively
- on the pages of the extensions themselves. The <A
- HREF="#ini"
- >list of
- the core directives</A
- > 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
- <TT
- CLASS="filename"
- >php.ini</TT
- > file. Alternatively, you may find the
- <A
- HREF="http://cvs.php.net/co.php/php-src/php.ini-dist"
- TARGET="_top"
- >the latest <TT
- CLASS="filename"
- >php.ini</TT
- ></A
- > from CVS
- helpful too.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2389"
- ></A
- ><P
- ><B
- >Example 9-1. <TT
- CLASS="filename"
- >php.ini</TT
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- >; 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"</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="configuration.changes"
- >How to change configuration settings</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="configuration.changes.apache"
- >Running PHP as an Apache module</A
- ></H3
- ><P
- >
When using PHP as an Apache module, you can also change the
- configuration settings using directives in Apache configuration
- files (e.g. <TT
- CLASS="filename"
- >httpd.conf</TT
- >) and <TT
- CLASS="filename"
- >.htaccess</TT
- > files. You will need
- "AllowOverride Options" or "AllowOverride All" privileges to do so.
- </P
- ><P
- >
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
- <TT
- CLASS="constant"
- ><B
- >PHP_INI_ALL</B
- ></TT
- >, <TT
- CLASS="constant"
- ><B
- >PHP_INI_PERDIR</B
- ></TT
- >,
- or <TT
- CLASS="constant"
- ><B
- >PHP_INI_SYSTEM</B
- ></TT
- >, have a look at the table
- found within the <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- > documentation.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- With PHP 3, there are Apache directives that correspond to each
- configuration setting in the <TT
- CLASS="filename"
- >php3.ini</TT
- > name,
- except the name is prefixed by "php3_".
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><SPAN
- CLASS="systemitem"
- >php_value</SPAN
- >
- <VAR
- CLASS="parameter"
- >name</VAR
- >
- <VAR
- CLASS="parameter"
- >value</VAR
- ></DT
- ><DD
- ><P
- >
Sets the value of the specified directive.
- Can be used only with <TT
- CLASS="constant"
- ><B
- >PHP_INI_ALL</B
- ></TT
- > and <TT
- CLASS="constant"
- ><B
- >PHP_INI_PERDIR</B
- ></TT
- > type directives.
- To clear a previously set value use <VAR
- CLASS="literal"
- >none</VAR
- > as the value.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Don't use <SPAN
- CLASS="systemitem"
- >php_value</SPAN
- > to set boolean values.
- <SPAN
- CLASS="systemitem"
- >php_flag</SPAN
- > (see below) should be used instead.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DD
- ><DT
- ><SPAN
- CLASS="systemitem"
- >php_flag</SPAN
- >
- <VAR
- CLASS="parameter"
- >name</VAR
- >
- <VAR
- CLASS="parameter"
- >on|off</VAR
- ></DT
- ><DD
- ><P
- >
Used to set a boolean configuration directive.
- Can be used only with <TT
- CLASS="constant"
- ><B
- >PHP_INI_ALL</B
- ></TT
- > and
- <TT
- CLASS="constant"
- ><B
- >PHP_INI_PERDIR</B
- ></TT
- > type directives.
- </P
- ></DD
- ><DT
- ><SPAN
- CLASS="systemitem"
- >php_admin_value</SPAN
- >
- <VAR
- CLASS="parameter"
- >name</VAR
- >
- <VAR
- CLASS="parameter"
- >value</VAR
- ></DT
- ><DD
- ><P
- >
Sets the value of the specified directive.
- This <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >can not be used</I
- ></SPAN
- > in <TT
- CLASS="filename"
- >.htaccess</TT
- > files.
- Any directive type set with <SPAN
- CLASS="systemitem"
- >php_admin_value</SPAN
- >
- can not be overridden by <TT
- CLASS="filename"
- >.htaccess</TT
- > or virtualhost directives.
- To clear a previously set value use <VAR
- CLASS="literal"
- >none</VAR
- > as the value.
- </P
- ></DD
- ><DT
- ><SPAN
- CLASS="systemitem"
- >php_admin_flag</SPAN
- >
- <VAR
- CLASS="parameter"
- >name</VAR
- >
- <VAR
- CLASS="parameter"
- >on|off</VAR
- ></DT
- ><DD
- ><P
- >
Used to set a boolean configuration directive.
- This <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >can not be used</I
- ></SPAN
- > in <TT
- CLASS="filename"
- >.htaccess</TT
- > files.
- Any directive type set with <SPAN
- CLASS="systemitem"
- >php_admin_flag</SPAN
- >
- can not be overridden by <TT
- CLASS="filename"
- >.htaccess</TT
- > or virtualhost directives.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2457"
- ></A
- ><P
- ><B
- >Example 9-2. Apache configuration example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
PHP constants do not exist outside of PHP. For example, in
- <TT
- CLASS="filename"
- >httpd.conf</TT
- > you can not use PHP constants
- such as <TT
- CLASS="constant"
- ><B
- >E_ALL</B
- ></TT
- > or <TT
- CLASS="constant"
- ><B
- >E_NOTICE</B
- ></TT
- >
- to set the <A
- HREF="#ini.error-reporting"
- >error_reporting</A
- >
- directive as they will have no meaning and will evaluate to
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >0</I
- ></SPAN
- >. Use the associated bitmask values instead.
- These constants can be used in <TT
- CLASS="filename"
- >php.ini</TT
- >
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="configuration.changes.windows"
- >Changing PHP configuration via the Windows registry</A
- ></H3
- ><P
- >
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
- <VAR
- CLASS="literal"
- >HKLM\SOFTWARE\PHP\Per Directory Values</VAR
- >,
- in the sub-keys corresponding to the path names. For example, configuration
- values for the directory <VAR
- CLASS="literal"
- >c:\inetpub\wwwroot</VAR
- > would
- be stored in the key <VAR
- CLASS="literal"
- >HKLM\SOFTWARE\PHP\Per Directory
- Values\c\inetpub\wwwroot</VAR
- >. 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.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="configuration.changes.other"
- >Other interfaces to PHP</A
- ></H3
- ><P
- >
Regardless of how you run PHP, you can change certain values at runtime
- of your scripts through <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- >. See the documentation
- on the <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- > page for more information.
- </P
- ><P
- >
If you are interested in a complete list of configuration settings
- on your system with their current values, you can execute the
- <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > function, and review the resulting
- page. You can also access the values of individual configuration
- directives at runtime using <A
- HREF="#function.ini-get"
- ><B
- CLASS="function"
- >ini_get()</B
- ></A
- > or
- <A
- HREF="#function.get-cfg-var"
- ><B
- CLASS="function"
- >get_cfg_var()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="langref"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >III. Language Reference</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >10. <A
- HREF="#language.basic-syntax"
- >Basic syntax</A
- ></DT
- ><DT
- >11. <A
- HREF="#language.types"
- >Types</A
- ></DT
- ><DT
- >12. <A
- HREF="#language.variables"
- >Variables</A
- ></DT
- ><DT
- >13. <A
- HREF="#language.constants"
- >Constants</A
- ></DT
- ><DT
- >14. <A
- HREF="#language.expressions"
- >Expressions</A
- ></DT
- ><DT
- >15. <A
- HREF="#language.operators"
- >Operators</A
- ></DT
- ><DT
- >16. <A
- HREF="#language.control-structures"
- >Control Structures</A
- ></DT
- ><DT
- >17. <A
- HREF="#language.functions"
- >Functions</A
- ></DT
- ><DT
- >18. <A
- HREF="#language.oop"
- >Classes and Objects (PHP 4)</A
- ></DT
- ><DT
- >19. <A
- HREF="#language.oop5"
- >Classes and Objects (PHP 5)</A
- ></DT
- ><DT
- >20. <A
- HREF="#language.exceptions"
- >Exceptions</A
- ></DT
- ><DT
- >21. <A
- HREF="#language.references"
- >References Explained</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.basic-syntax"
- >Chapter 10. Basic syntax</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="language.basic-syntax.phpmode"
- >Escaping from HTML</A
- ></H2
- ><P
- >
When PHP parses a file, it simply passes the text of the file
- through until it encounters one of the special tags which tell it
- to start interpreting the text as PHP code. The parser then
- executes all the code it finds, up until it runs into a PHP
- closing tag, which tells the parser to just start passing the text
- through again. This is the mechanism which allows you to embed PHP
- code inside HTML: everything outside the PHP tags is left utterly
- alone, while everything inside is parsed as code.
- </P
- ><P
- >
There are four sets of tags which can be used to denote blocks of
- PHP code. Of these, only two (<?php. . .?> and <script
- language="php">. . .</script>) are always available; the
- others can be turned on or off from the
- <TT
- CLASS="filename"
- >php.ini</TT
- > configuration file. While the
- short-form tags and ASP-style tags may be convenient, they are not
- as portable as the longer versions. Also, if you intend to embed
- PHP code in XML or XHTML, you will need to use the
- <?php. . .?> form to conform to the XML.
- </P
- ><P
- >
The tags supported by PHP are:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2494"
- ></A
- ><P
- ><B
- >Example 10-1. Ways of escaping from HTML</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >1. <?php echo("if you want to serve XHTML or XML documents, do like this\n"); ?>
-
- 2. <? echo ("this is the simplest, an SGML processing instruction\n"); ?>
- <?= expression ?> This is a shortcut for "<? echo expression ?>"
-
- 3. <script language="php">
- echo ("some editors (like FrontPage) don't
- like processing instructions");
- </script>
-
- 4. <% echo ("You may optionally use ASP-style tags"); %>
- <%= $variable; # This is a shortcut for "<% echo . . ." %></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The first way, <?php. . .?>, is the preferred method, as it
- allows the use of PHP in XML-conformant code such as XHTML.
- </P
- ><P
- >
The second way is not available always. Short tags are available
- only when they have been enabled. This can be done via the
- <B
- CLASS="function"
- >short_tags()</B
- > function (PHP 3 only), by enabling
- the <A
- HREF="#ini.short-open-tag"
- >short_open_tag</A
- >
- configuration setting in the PHP config file, or by compiling PHP
- with the <VAR
- CLASS="option"
- >--enable-short-tags</VAR
- > option to
- <B
- CLASS="command"
- >configure</B
- >. Even if it is enabled by default in
- <TT
- CLASS="filename"
- >php.ini-dist</TT
- >, use of short tags are discouraged.
- </P
- ><P
- >
The third way is always available and safe like the first one. However,
- the first is the preferred and most used one.
- </P
- ><P
- >
The fourth way is only available if <SPAN
- CLASS="productname"
- >ASP</SPAN
- >
- tags have been enabled using the <A
- HREF="#ini.asp-tags"
- >asp_tags</A
- >
- configuration setting.
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >Support for <SPAN
- CLASS="productname"
- >ASP</SPAN
- > tags was added in 3.0.4.</P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Using short tags should be avoided when developing applications
- or libraries that are meant for redistribution, or deployment on
- PHP servers which are not under your control, because short tags
- may not be supported on the target server. For portable,
- redistributable code, be sure not to use short tags.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
The closing tag for the block will include the immediately
- trailing newline if one is present. Also, the closing tag
- automatically implies a semicolon; you do not need to have a
- semicolon terminating the last line of a PHP block.
- Closing tag of a PHP block at the end of a file is optional.
- </P
- ><P
- >
PHP allows you to use structures like this:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2516"
- ></A
- ><P
- ><B
- >Example 10-2. Advanced escaping</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($expression) {
- ?>
- <strong>This is true.</strong>
- <?php
- } else {
- ?>
- <strong>This is false.</strong>
- <?php
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- This works as expected, because when PHP hits the ?> closing
- tags, it simply starts outputting whatever it finds until it hits
- another opening tag. The example given here is contrived, of
- course, but for outputting large blocks of text, dropping out of
- PHP parsing mode is generally more efficient than sending all of
- the text through <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- > or
- <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- > or somesuch.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.basic-syntax.instruction-separation"
- >Instruction separation</A
- ></H2
- ><P
- >
Instructions are separated the same as in C or Perl - terminate
- each statement with a semicolon.
- </P
- ><P
- >
The closing tag (?>) also implies the end of the statement, so
- the following are equivalent:
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2525"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "This is a test";
- ?>
-
- <?php echo "This is a test" ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.basic-syntax.comments"
- >Comments</A
- ></H2
- ><P
- >
PHP supports 'C', 'C++' and Unix shell-style comments. For example:
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2530"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "This is a test"; // This is a one-line c++ style comment
- /* This is a multi line comment
- yet another line of comment */
- echo "This is yet another test";
- echo "One Final Test"; # This is shell-style style comment
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The "one-line" comment styles actually only comment to the end of
- the line or the current block of PHP code, whichever comes
- first.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2534"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><h1>This is an <?php # echo "simple";?> example.</h1>
- <p>The header above will say 'This is an example'.</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
You should be careful not to nest 'C' style comments, which can
- happen when commenting out large blocks.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2538"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /*
- echo "This is a test"; /* This comment will cause a problem */
- */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The one-line comment styles actually only comment to the end
- of the line or the current block of PHP code, whichever comes first.
- This means that HTML code after <VAR
- CLASS="literal"
- >// ?></VAR
- > WILL be printed:
- ?> skips out of the PHP mode and returns to HTML mode, and
- <VAR
- CLASS="literal"
- >//</VAR
- > cannot influence that.
- If <A
- HREF="#ini.asp-tags"
- >asp_tags</A
- > configuration directive
- is enabled, it behaves the same with <VAR
- CLASS="literal"
- >// %></VAR
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.types"
- >Chapter 11. Types</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="language.types.intro"
- >Introduction</A
- ></H2
- ><P
- >
PHP supports eight primitive types.
- </P
- ><P
- >
Four scalar types:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- > (floating-point number, aka '<A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >double</B
- ></A
- >')
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >
- </P
- ></LI
- ></UL
- >
-
- Two compound types:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.object"
- ><B
- CLASS="type"
- >object</B
- ></A
- >
- </P
- ></LI
- ></UL
- >
-
- And finally two special types:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#language.types.resource"
- ><B
- CLASS="type"
- >resource</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.null"
- ><B
- CLASS="type"
- >NULL</B
- ></A
- >
- </P
- ></LI
- ></UL
- >
-
- This manual also introduces some
- <A
- HREF="#language.pseudo-types"
- >pseudo-types</A
- >
- for readability reasons:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#language.types.mixed"
- ><B
- CLASS="type"
- >mixed</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.number"
- ><B
- CLASS="type"
- >number</B
- ></A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.callback"
- ><B
- CLASS="type"
- >callback</B
- ></A
- >
- </P
- ></LI
- ></UL
- >
- You may also find some references to the type "double". Consider
- double the same as float, the two names exist only for historic
- reasons.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you want to check out the type and value of a certain <A
- HREF="#language.expressions"
- >expression</A
- >, use
- <A
- HREF="#function.var-dump"
- ><B
- CLASS="function"
- >var_dump()</B
- ></A
- >.
- </P
- ><P
- ><B
- >Note: </B
- >
- If you simply want a human-readable representation of the type for
- debugging, use <A
- HREF="#function.gettype"
- ><B
- CLASS="function"
- >gettype()</B
- ></A
- >. To check for a certain type,
- do <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > use <A
- HREF="#function.gettype"
- ><B
- CLASS="function"
- >gettype()</B
- ></A
- >, but use the
- <VAR
- CLASS="literal"
- >is_<VAR
- CLASS="replaceable"
- >type</VAR
- ></VAR
- > functions. Some
- examples:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2601"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
If you would like to force a variable to be converted to a certain
- type, you may either <A
- HREF="#language.types.typecasting"
- >cast</A
- > the variable or
- use the <A
- HREF="#function.settype"
- ><B
- CLASS="function"
- >settype()</B
- ></A
- > function on it.
- </P
- ><P
- >
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 <A
- HREF="#language.types.type-juggling"
- >Type Juggling</A
- >. Also, you
- may be interested in viewing
- <A
- HREF="#types.comparisons"
- >the type comparison tables</A
- >,
- as they show examples of various type related comparisons.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.boolean"
- >Booleans</A
- ></H2
- ><P
- >
This is the easiest type. A <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > expresses a
- truth value. It can be either <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The boolean type was introduced in PHP 4.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.boolean.syntax"
- >Syntax</A
- ></H3
- ><P
- >
To specify a boolean literal, use either the keyword <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >
- or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >. Both are case-insensitive.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2622"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $foo = True; // assign the value TRUE to $foo
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Usually you
- use some kind of <A
- HREF="#language.operators"
- >operator</A
- >
- which returns a <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > value, and then pass it
- on to a <A
- HREF="#language.control-structures"
- >control
- structure</A
- >.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2628"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.boolean.casting"
- >Converting to boolean</A
- ></H3
- ><P
- >
To explicitly convert a value to <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- >, use either
- the <VAR
- CLASS="literal"
- >(bool)</VAR
- > or the <VAR
- CLASS="literal"
- >(boolean)</VAR
- > 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 <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > argument.
- </P
- ><P
- >
See also <A
- HREF="#language.types.type-juggling"
- >Type Juggling</A
- >.
- </P
- ><P
- >
When converting to <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- >, the following values
- are considered <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- >the <A
- HREF="#language.types.boolean"
- >boolean</A
- >
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > itself</P
- ></LI
- ><LI
- ><P
- >the <A
- HREF="#language.types.integer"
- >integer</A
- > 0 (zero) </P
- ></LI
- ><LI
- ><P
- >the <A
- HREF="#language.types.float"
- >float</A
- >
- 0.0 (zero) </P
- ></LI
- ><LI
- ><P
- >the empty <A
- HREF="#language.types.string"
- >string</A
- >, and the <A
- HREF="#language.types.string"
- >string</A
- >
- "0"</P
- ></LI
- ><LI
- ><P
- >an <A
- HREF="#language.types.array"
- >array</A
- >
- with zero elements</P
- ></LI
- ><LI
- ><P
- >an <A
- HREF="#language.types.object"
- >object</A
- >
- with zero member variables (PHP 4 only)</P
- ></LI
- ><LI
- ><P
- >the special type <A
- HREF="#language.types.null"
- >NULL</A
- > (including unset variables)
- </P
- ></LI
- ></UL
- >
-
- Every other value is considered <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > (including any
- <A
- HREF="#language.types.resource"
- >resource</A
- >).
- <DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
<VAR
- CLASS="literal"
- >-1</VAR
- > is considered
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, like any other non-zero (whether negative
- or positive) number!
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- >
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2672"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.integer"
- >Integers</A
- ></H2
- ><P
- >
An <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > is a number of the set
- Z = {..., -2, -1, 0, 1, 2, ...}.
- </P
- ><P
- >
See also:
- <A
- HREF="#ref.gmp"
- >Arbitrary length integer / GMP</A
- >,
- <A
- HREF="#language.types.float"
- >Floating point numbers</A
- >, and
- <A
- HREF="#ref.bc"
- >Arbitrary precision / BCMath</A
- >
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.integer.syntax"
- >Syntax</A
- ></H3
- ><P
- >
Integers can be specified in decimal (10-based), hexadecimal (16-based)
- or octal (8-based) notation, optionally preceded by a sign (- or +).
- </P
- ><P
- >
If you use the octal notation, you must precede the number with a
- <VAR
- CLASS="literal"
- >0</VAR
- > (zero), to use hexadecimal notation precede
- the number with <VAR
- CLASS="literal"
- >0x</VAR
- >.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2688"
- ></A
- ><P
- ><B
- >Example 11-1. Integer literals</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Formally the possible structure for integer literals is:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2691"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >decimal : [1-9][0-9]*
- | 0
-
- hexadecimal : 0[xX][0-9a-fA-F]+
-
- octal : 0[0-7]+
-
- integer : [+-]?decimal
- | [+-]?hexadecimal
- | [+-]?octal</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
If invalid digit is passed to octal integer (i.e. 8 or 9), the rest of
- the number is ignored.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2695"
- ></A
- ><P
- ><B
- >Example 11-2. Octal weirdness</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- var_dump(01090); // 010 octal = 8 decimal
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.integer.overflow"
- >Integer overflow</A
- ></H3
- ><P
- >
If you specify a number beyond the bounds of the <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >
- type, it will be interpreted as a <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- > instead. Also, if
- you perform an operation that results in a number beyond the bounds of
- the <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > type, a <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- > will be returned
- instead.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2705"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- <DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
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 <VAR
- CLASS="literal"
- >-50000 *
- $million</VAR
- >, the result will be
- <VAR
- CLASS="literal"
- >-429496728</VAR
- >. However, when both operands are
- positive there is no problem.
- </P
- ><P
- >
This is solved in PHP 4.1.0.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
There is no integer division operator in PHP.
- <VAR
- CLASS="literal"
- >1/2</VAR
- > yields the <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- >
- <VAR
- CLASS="literal"
- >0.5</VAR
- >. You can cast the value to
- an integer to always round it downwards, or you can
- use the <A
- HREF="#function.round"
- ><B
- CLASS="function"
- >round()</B
- ></A
- > function.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2717"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- var_dump(25/7); // float(3.5714285714286)
- var_dump((int) (25/7)); // int(3)
- var_dump(round(25/7)); // float(4)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.integer.casting"
- >Converting to integer</A
- ></H3
- ><P
- >
To explicitly convert a value to <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >, use either
- the <VAR
- CLASS="literal"
- >(int)</VAR
- > or the <VAR
- CLASS="literal"
- >(integer)</VAR
- > 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 <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > argument.
- You can also convert a value to integer with the function
- <A
- HREF="#function.intval"
- ><B
- CLASS="function"
- >intval()</B
- ></A
- >.
- </P
- ><P
- >
See also <A
- HREF="#language.types.type-juggling"
- >type-juggling</A
- >.
- </P
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.integer.casting.from-boolean"
- >From <A
- HREF="#language.types.boolean"
- >booleans</A
- ></A
- ></H4
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > will yield
- <VAR
- CLASS="literal"
- >0</VAR
- > (zero), and <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >
- will yield <VAR
- CLASS="literal"
- >1</VAR
- > (one).
- </P
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.integer.casting.from-float"
- >From <A
- HREF="#language.types.float"
- >floating point numbers</A
- ></A
- ></H4
- ><P
- >
When converting from float to integer, the number will
- be rounded <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >towards zero</I
- ></SPAN
- >.
- </P
- ><P
- >
If the float is beyond the boundaries of integer
- (usually <VAR
- CLASS="literal"
- >+/- 2.15e+9 = 2^31</VAR
- >),
- 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!
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Never cast an unknown fraction to <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >, as this can
- sometimes lead to unexpected results.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2747"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
-
- See for more information the <A
- HREF="#warn.float-precision"
- >warning
- about float-precision</A
- >.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.integer.casting.from-string"
- >From strings</A
- ></H4
- ><P
- >
See <A
- HREF="#language.types.string.conversion"
- >String
- conversion to numbers</A
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.integer.casting.from-other"
- >From other types</A
- ></H4
- ><P
- >
<DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Behaviour of converting to integer is undefined for other
- types. Currently, the behaviour is the same as if the value
- was first <A
- HREF="#language.types.boolean.casting"
- >converted to boolean</A
- >. However, do
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > rely on this behaviour, as it can
- change without notice.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.float"
- >Floating point numbers</A
- ></H2
- ><P
- >
Floating point numbers (AKA "floats", "doubles" or "real numbers") can be
- specified using any of the following syntaxes:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2764"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1.234;
- $b = 1.2e3;
- $c = 7E-10;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- Formally:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2766"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >LNUM [0-9]+
- DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
- EXPONENT_DNUM ( ({LNUM} | {DNUM}) [eE][+-]? {LNUM})</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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).
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- ><A
- NAME="warn.float-precision"
- ></A
- >Floating point precision</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
It is quite usual that simple decimal fractions like
- <VAR
- CLASS="literal"
- >0.1</VAR
- > or <VAR
- CLASS="literal"
- >0.7</VAR
- > cannot be
- converted into their internal binary counterparts without a
- little loss of precision. This can lead to confusing results: for
- example, <VAR
- CLASS="literal"
- >floor((0.1+0.7)*10)</VAR
- > will usually
- return <VAR
- CLASS="literal"
- >7</VAR
- > instead of the expected
- <VAR
- CLASS="literal"
- >8</VAR
- > as the result of the internal representation
- really being something like <VAR
- CLASS="literal"
- >7.9999999999...</VAR
- >.
- </P
- ><P
- >
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, <VAR
- CLASS="literal"
- >1/3</VAR
- > in decimal form
- becomes <VAR
- CLASS="literal"
- >0.3333333. . .</VAR
- >.
- </P
- ><P
- >
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 <A
- HREF="#ref.bc"
- >arbitrary precision math functions</A
- >
- or <A
- HREF="#ref.gmp"
- >gmp</A
- > functions instead.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.float.casting"
- >Converting to float</A
- ></H3
- ><P
- >
For information on when and how strings are converted to floats,
- see the section titled <A
- HREF="#language.types.string.conversion"
- >String
- conversion to numbers</A
- >. 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 <A
- HREF="#language.types.integer.casting"
- >Converting
- to integer</A
- > section for more information.
- As of PHP 5, notice is thrown if you try to convert object to float.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.string"
- >Strings</A
- ></H2
- ><P
- >
A <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- > 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 <A
- HREF="#function.utf8-encode"
- ><B
- CLASS="function"
- >utf8_encode()</B
- ></A
- >
- and <A
- HREF="#function.utf8-decode"
- ><B
- CLASS="function"
- >utf8_decode()</B
- ></A
- > for some Unicode support.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.string.syntax"
- >Syntax</A
- ></H3
- ><P
- >
A string literal can be specified in three different
- ways.
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#language.types.string.syntax.single"
- >single quoted</A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.string.syntax.double"
- >double quoted</A
- >
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#language.types.string.syntax.heredoc"
- >heredoc syntax</A
- >
- </P
- ></LI
- ></UL
- >
- </P
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.string.syntax.single"
- >Single quoted</A
- ></H4
- ><P
- >
The easiest way to specify a simple string is to
- enclose it in single quotes (the character <VAR
- CLASS="literal"
- >'</VAR
- >).
- </P
- ><P
- >
To specify a literal single
- quote, you will need to escape it with a backslash
- (<VAR
- CLASS="literal"
- >\</VAR
- >), 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.
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 3, a warning will
- be issued at the <VAR
- CLASS="literal"
- >E_NOTICE</VAR
- > level when this
- happens.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Unlike the two other syntaxes, <A
- HREF="#language.variables"
- >variables</A
- > and escape sequences
- for special characters will <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > be expanded
- when they occur in single quoted strings.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2822"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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';
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.string.syntax.double"
- >Double quoted</A
- ></H4
- ><P
- >
If the string is enclosed in double-quotes ("),
- PHP understands more escape sequences for special
- characters:
- </P
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN2827"
- ></A
- ><P
- ><B
- >Table 11-1. Escaped characters</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >sequence</TH
- ><TH
- >meaning</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\n</VAR
- ></TD
- ><TD
- >linefeed (LF or 0x0A (10) in ASCII)</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\r</VAR
- ></TD
- ><TD
- >carriage return (CR or 0x0D (13) in ASCII)</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\t</VAR
- ></TD
- ><TD
- >horizontal tab (HT or 0x09 (9) in ASCII)</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\\</VAR
- ></TD
- ><TD
- >backslash</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\$</VAR
- ></TD
- ><TD
- >dollar sign</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\"</VAR
- ></TD
- ><TD
- >double-quote</TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\[0-7]{1,3}</VAR
- ></TD
- ><TD
- >
the sequence of characters matching the regular
- expression is a character in octal notation
- </TD
- ></TR
- ><TR
- ><TD
- ><VAR
- CLASS="literal"
- >\x[0-9A-Fa-f]{1,2}</VAR
- ></TD
- ><TD
- >
the sequence of characters matching the regular
- expression is a character in hexadecimal notation
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
Again, if you try to escape any other character, the
- backslash will be printed too!
- </P
- ><P
- >
But the most important feature of double-quoted strings
- is the fact that variable names will be expanded.
- See <A
- HREF="#language.types.string.parsing"
- >string
- parsing</A
- > for details.
- </P
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.string.syntax.heredoc"
- >Heredoc</A
- ></H4
- ><P
- >
Another way to delimit strings is by using heredoc syntax
- ("<<<"). One should provide an identifier after
- <VAR
- CLASS="literal"
- ><<<</VAR
- >, then the string, and then the
- same identifier to close the quotation.
- </P
- ><P
- >
The closing identifier <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >must</I
- ></SPAN
- > 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.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
It is very important to note that the line with the closing
- identifier contains no other characters, except
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >possibly</I
- ></SPAN
- > a semicolon (<VAR
- CLASS="literal"
- >;</VAR
- >).
- That means especially that the identifier
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >may not be indented</I
- ></SPAN
- >, 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 <VAR
- CLASS="literal"
- >\r</VAR
- > on Macintosh
- for example.
- </P
- ><P
- >
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.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2884"
- ></A
- ><P
- ><B
- >Example 11-3. Heredoc string quoting example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Heredoc support was added in PHP 4.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.string.parsing"
- >Variable parsing</A
- ></H4
- ><P
- >
When a string is specified in double quotes or with
- heredoc, <A
- HREF="#language.variables"
- >variables</A
- > are
- parsed within it.
- </P
- ><P
- >
There are two types of syntax: a
- <A
- HREF="#language.types.string.parsing.simple"
- >simple</A
- >
- one and a
- <A
- HREF="#language.types.string.parsing.complex"
- >complex</A
- >
- one.
- The simple syntax is the most common and convenient. It provides a way
- to parse a variable, an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > value, or an
- object property.
- </P
- ><P
- >
The complex syntax was introduced in PHP 4, and can be recognised
- by the curly braces surrounding the expression.
- </P
- ><DIV
- CLASS="sect4"
- ><HR><H5
- CLASS="sect4"
- ><A
- NAME="language.types.string.parsing.simple"
- >Simple syntax</A
- ></H5
- ><P
- >
If a dollar sign (<VAR
- CLASS="literal"
- >$</VAR
- >) 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.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2903"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Similarly, you can also have an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > index or an
- object property parsed. With array indices, the closing square
- bracket (<VAR
- CLASS="literal"
- >]</VAR
- >) 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.
-
-
-
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2909"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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.";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
For anything more complex, you should use the complex syntax.
- </P
- ></DIV
- ><DIV
- CLASS="sect4"
- ><HR><H5
- CLASS="sect4"
- ><A
- NAME="language.types.string.parsing.complex"
- >Complex (curly) syntax</A
- ></H5
- ><P
- >
This isn't called complex because the syntax is complex,
- but because you can include complex expressions this way.
- </P
- ><P
- >
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:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2916"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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}}";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.string.substr"
- >String access and modification by character</A
- ></H4
- ><P
- >
Characters within strings may be accessed and modified by specifying the
- zero-based offset of the desired character after the string
- in curly braces.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For backwards compatibility, you can still use array-brackets
- for the same purpose. However, this syntax is deprecated as
- of PHP 4.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN2924"
- ></A
- ><P
- ><B
- >Example 11-4. Some string examples</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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';
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.string.useful-funcs"
- >Useful functions and operators</A
- ></H3
- ><P
- >
Strings may be concatenated using the '.' (dot) operator. Note
- that the '+' (addition) operator will not work for this. Please
- see <A
- HREF="#language.operators.string"
- >String
- operators</A
- > for more information.
- </P
- ><P
- >
There are a lot of useful functions for string modification.
- </P
- ><P
- >
See the <A
- HREF="#ref.strings"
- >string functions section</A
- >
- for general functions, the regular expression functions for
- advanced find&replacing (in two tastes:
- <A
- HREF="#ref.pcre"
- >Perl</A
- > and
- <A
- HREF="#ref.regex"
- >POSIX extended</A
- >).
- </P
- ><P
- >
There are also <A
- HREF="#ref.url"
- >functions for URL-strings</A
- >,
- and functions to encrypt/decrypt strings
- (<A
- HREF="#ref.mcrypt"
- >mcrypt</A
- > and
- <A
- HREF="#ref.mhash"
- >mhash</A
- >).
- </P
- ><P
- >
Finally, if you still didn't find what you're looking for,
- see also the <A
- HREF="#ref.ctype"
- >character type functions</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.string.casting"
- >Converting to string</A
- ></H3
- ><P
- >
You can convert a value to a string using the <VAR
- CLASS="literal"
- >(string)</VAR
- >
- cast, or the <A
- HREF="#function.strval"
- ><B
- CLASS="function"
- >strval()</B
- ></A
- > 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 <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- >
- or <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- > functions, or when you compare a variable
- value to a string. Reading the manual sections on <A
- HREF="#language.types"
- >Types</A
- > and <A
- HREF="#language.types.type-juggling"
- >Type Juggling</A
- > will make
- the following clearer. See also <A
- HREF="#function.settype"
- ><B
- CLASS="function"
- >settype()</B
- ></A
- >.
- </P
- ><P
- >
A <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > value is converted to the string <VAR
- CLASS="literal"
- >"1"</VAR
- >,
- the <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > value is represented as <VAR
- CLASS="literal"
- >""</VAR
- > (empty string).
- This way you can convert back and forth between boolean and string values.
- </P
- ><P
- >
- An <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > or a floating point number (<A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- >)
- is converted to a string representing the number with its digits
- (including the exponent part for floating point numbers).
- </P
- ><P
- >
Arrays are always converted to the string <VAR
- CLASS="literal"
- >"Array"</VAR
- >,
- so you cannot dump out the contents of an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > with
- <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- > or <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- > to see what is inside
- them. To view one element, you'd do something like <VAR
- CLASS="literal"
- >
echo $arr['foo']</VAR
- >. See below for tips on dumping/viewing the
- entire contents.
- </P
- ><P
- >
Objects are always converted to the string <VAR
- CLASS="literal"
- >"Object"</VAR
- >.
- If you would like to print out the member variable values of an
- <A
- HREF="#language.types.object"
- ><B
- CLASS="type"
- >object</B
- ></A
- > 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 <A
- HREF="#function.get-class"
- ><B
- CLASS="function"
- >get_class()</B
- ></A
- >.
- As of PHP 5, __toString() method is used if applicable.
- </P
- ><P
- >
Resources are always converted to strings with the structure
- <VAR
- CLASS="literal"
- >"Resource id #1"</VAR
- > where <VAR
- CLASS="literal"
- >1</VAR
- > is
- the unique number of the <A
- HREF="#language.types.resource"
- ><B
- CLASS="type"
- >resource</B
- ></A
- > assigned by PHP during runtime.
- If you would like to get the type of the resource, use
- <A
- HREF="#function.get-resource-type"
- ><B
- CLASS="function"
- >get_resource_type()</B
- ></A
- >.
- </P
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > is always converted to an empty string.
- </P
- ><P
- >
As you can see above, printing out the arrays, objects or resources does not
- provide you any useful information about the values themselves. Look at the
- functions <A
- HREF="#function.print-r"
- ><B
- CLASS="function"
- >print_r()</B
- ></A
- > and <A
- HREF="#function.var-dump"
- ><B
- CLASS="function"
- >var_dump()</B
- ></A
- >
- for better ways to print out values for debugging.
- </P
- ><P
- >
You can also convert PHP values to strings to store them permanently. This
- method is called serialization, and can be done with the function
- <A
- HREF="#function.serialize"
- ><B
- CLASS="function"
- >serialize()</B
- ></A
- >. You can also serialize PHP values to
- XML structures, if you have <A
- HREF="#ref.wddx"
- >WDDX</A
- > support
- in your PHP setup.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.string.conversion"
- >String conversion to numbers</A
- ></H3
- ><P
- >
When a string is evaluated as a numeric value, the resulting
- value and type are determined as follows.
- </P
- ><P
- >
The string will evaluate as a <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- > if it contains any of the
- characters '.', 'e', or 'E'. Otherwise, it will evaluate as an
- integer.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2990"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
For more information on this conversion, see the Unix manual page
- for strtod(3).
- </P
- ><P
- >
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:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN2994"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
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
- <A
- HREF="#function.ord"
- ><B
- CLASS="function"
- >ord()</B
- ></A
- > and <A
- HREF="#function.chr"
- ><B
- CLASS="function"
- >chr()</B
- ></A
- > to convert
- between charcodes and characters.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.array"
- >Arrays</A
- ></H2
- ><P
- >
An array in PHP is actually an ordered map. A map is a type that
- maps <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >values</I
- ></SPAN
- > to <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >keys</I
- ></SPAN
- >.
- 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.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.syntax"
- >Syntax</A
- ></H3
- ><DIV
- CLASS="sect3"
- ><H4
- CLASS="sect3"
- ><A
- NAME="language.types.array.syntax.array-func"
- >Specifying with <A
- HREF="#function.array"
- ><B
- CLASS="function"
- >array()</B
- ></A
- ></A
- ></H4
- ><P
- >
An <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > can be created by the <A
- HREF="#function.array"
- ><B
- CLASS="function"
- >array()</B
- ></A
- >
- language-construct. It takes a certain number of comma-separated
- <VAR
- CLASS="literal"
- ><VAR
- CLASS="replaceable"
- >key</VAR
- > => <VAR
- CLASS="replaceable"
- >value</VAR
- ></VAR
- >
- pairs.
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="synopsis"
- >array( [<VAR
- CLASS="replaceable"
- >key</VAR
- > =>] <VAR
- CLASS="replaceable"
- >value</VAR
- >
- , ...
- )
- // <VAR
- CLASS="replaceable"
- >key</VAR
- > may be an <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > or <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >
- // <VAR
- CLASS="replaceable"
- >value</VAR
- > may be any value</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3026"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $arr = array("foo" => "bar", 12 => true);
-
- echo $arr["foo"]; // bar
- echo $arr[12]; // 1
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
A <VAR
- CLASS="varname"
- >key</VAR
- > may be either an
- <VAR
- CLASS="literal"
- >integer</VAR
- > or a <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >. If a key is
- the standard representation of an <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >, it will
- be interpreted as such (i.e. <VAR
- CLASS="literal"
- >"8"</VAR
- > will be
- interpreted as <VAR
- CLASS="literal"
- >8</VAR
- >, while
- <VAR
- CLASS="literal"
- >"08"</VAR
- > will be interpreted as
- <VAR
- CLASS="literal"
- >"08"</VAR
- >). 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.
- </P
- ><P
- >
A value can be of any PHP type.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3038"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
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.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3041"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
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 (<VAR
- CLASS="literal"
- >0</VAR
- >). Before, the new
- index would have been set to the largest existing key + 1,
- the same as positive indices are.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
Using <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > as a key will evaluate to <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >
- <VAR
- CLASS="literal"
- >1</VAR
- > as key. Using <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > as a key will evaluate
- to <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > <VAR
- CLASS="literal"
- >0</VAR
- > as key. Using
- <VAR
- CLASS="literal"
- >NULL</VAR
- > 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.
- </P
- ><P
- >
You cannot use arrays or objects as keys. Doing so will result in a
- warning: <VAR
- CLASS="literal"
- >Illegal offset type</VAR
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.types.array.syntax.modifying"
- >Creating/modifying with square-bracket syntax</A
- ></H4
- ><P
- >
You can also modify an existing array by explicitly setting
- values in it.
- </P
- ><P
- >
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 ("<VAR
- CLASS="literal"
- >[]</VAR
- >") to the variable name in that case.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="synopsis"
- >$arr[<VAR
- CLASS="replaceable"
- >key</VAR
- >] = <VAR
- CLASS="replaceable"
- >value</VAR
- >;
- $arr[] = <VAR
- CLASS="replaceable"
- >value</VAR
- >;
- // <VAR
- CLASS="replaceable"
- >key</VAR
- > may be an <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > or <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >
- // <VAR
- CLASS="replaceable"
- >value</VAR
- > may be any value</PRE
- ></TD
- ></TR
- ></TABLE
- >
- If <VAR
- CLASS="varname"
- >$arr</VAR
- > 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 <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- > it.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3071"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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 <VAR
- CLASS="literal"
- >0</VAR
- >
- (zero). If you specify a key that already has a value assigned
- to it, that value will be overwritten.
- </P
- ><P
- >
<DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
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 (<VAR
- CLASS="literal"
- >0</VAR
- >). Before, the new
- index would have been set to the largest existing key + 1,
- the same as positive indices are.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
Note that the maximum integer key used for this <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >need
- not currently exist in the array</I
- ></SPAN
- >. It simply must
- have existed in the array at some time since the last time the
- array was re-indexed. The following example illustrates:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3082"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The above example would produce the following output:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => 1
- [1] => 2
- [2] => 3
- [3] => 4
- [4] => 5
- )
- Array
- (
- )
- Array
- (
- [5] => 6
- )
- Array
- (
- [0] => 6
- [1] => 7
- )</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- ></P
- ></DIV
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.useful-funcs"
- >Useful functions</A
- ></H3
- ><P
- >
There are quite a few useful functions for working with arrays.
- See the <A
- HREF="#ref.array"
- >array functions</A
- > section.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- > 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 <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- >.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3094"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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')
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
-
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The <A
- HREF="#control-structures.foreach"
- >foreach</A
- >
- control structure exists specifically for arrays. It
- provides an easy way to traverse an array.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.donts"
- >Array do's and don'ts</A
- ></H3
- ><DIV
- CLASS="sect3"
- ><H4
- CLASS="sect3"
- ><A
- NAME="language.types.array.foo-bar"
- >Why is <VAR
- CLASS="literal"
- >$foo[bar]</VAR
- > wrong?</A
- ></H4
- ><P
- >
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:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3104"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $foo[bar] = 'enemy';
- echo $foo[bar];
- // etc
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >bare string</I
- ></SPAN
- > (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 <TT
- CLASS="constant"
- ><B
- >bar</B
- ></TT
- >, then PHP will substitute in the
- string <VAR
- CLASS="literal"
- >'bar'</VAR
- > and use that.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This does not mean to <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >always</I
- ></SPAN
- > quote the
- key. You do not want to quote keys which are <A
- HREF="#language.constants"
- >constants</A
- > or <A
- HREF="#language.variables"
- >variables</A
- >, as this will
- prevent PHP from interpreting them.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3114"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- ><B
- >Note: </B
- >
- The output from the above is:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
More examples to demonstrate this fact:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3119"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
When you turn <A
- HREF="#function.error-reporting"
- ><B
- CLASS="function"
- >error_reporting()</B
- ></A
- > up to show
- <TT
- CLASS="constant"
- ><B
- >E_NOTICE</B
- ></TT
- > level errors (such as setting
- it to <TT
- CLASS="constant"
- ><B
- >E_ALL</B
- ></TT
- >) then you will see these
- errors. By default, <A
- HREF="#ini.error-reporting"
- >
error_reporting</A
- > is turned down to not show them.
- </P
- ><P
- >
As stated in the <A
- HREF="#language.types.array.syntax"
- >syntax</A
- > section,
- there must be an expression between the square brackets
- ('<VAR
- CLASS="literal"
- >[</VAR
- >' and '<VAR
- CLASS="literal"
- >]</VAR
- >'). That means
- that you can write things like this:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3130"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo $arr[somefunc($bar)];
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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 <VAR
- CLASS="literal"
- >E_*</VAR
- > ones
- before.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3133"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- Note that <VAR
- CLASS="literal"
- >E_ERROR</VAR
- > is also a valid identifier,
- just like <VAR
- CLASS="literal"
- >bar</VAR
- > in the first example. But the last
- example is in fact the same as writing:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3137"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- because <VAR
- CLASS="literal"
- >E_ERROR</VAR
- > equals <VAR
- CLASS="literal"
- >1</VAR
- >, etc.
- </P
- ><P
- >
As we already explained in the above examples,
- <VAR
- CLASS="literal"
- >$foo[bar]</VAR
- > still works but is wrong.
- It works, because <VAR
- CLASS="literal"
- >bar</VAR
- > is due to its syntax
- expected to be a constant expression. However, in this case no
- constant with the name <VAR
- CLASS="literal"
- >bar</VAR
- > exists. PHP now
- assumes that you meant <VAR
- CLASS="literal"
- >bar</VAR
- > literally,
- as the string <VAR
- CLASS="literal"
- >"bar"</VAR
- >, but that you forgot
- to write the quotes.
- </P
- ><DIV
- CLASS="sect4"
- ><HR><H5
- CLASS="sect4"
- ><A
- NAME="AEN3147"
- >So why is it bad then?</A
- ></H5
- ><P
- >
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 <VAR
- CLASS="literal"
- >empty</VAR
- > and
- <VAR
- CLASS="literal"
- >default</VAR
- > this way, since they are special
- <A
- HREF="#reserved"
- >reserved keywords</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- To reiterate, inside a double-quoted <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >, it's
- valid to not surround array indexes with quotes so
- <VAR
- CLASS="literal"
- >"$foo[bar]"</VAR
- > is valid. See the above
- examples for details on why as well as the section on
- <A
- HREF="#language.types.string.parsing"
- >variable parsing
- in strings</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.casting"
- >Converting to array</A
- ></H3
- ><P
- >
For any of the types: <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >, <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- >,
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >, <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > and <A
- HREF="#language.types.resource"
- ><B
- CLASS="type"
- >resource</B
- ></A
- >,
- if you convert a value to an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >, you get an array
- with one element (with index 0), which is the scalar value you
- started with.
- </P
- ><P
- >
If you convert an <A
- HREF="#language.types.object"
- ><B
- CLASS="type"
- >object</B
- ></A
- > to an array, you get the
- properties (member variables) of that object as the array's elements.
- The keys are the member variable names.
- </P
- ><P
- >
If you convert a <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > value to an array, you get an empty array.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.comparing"
- >Comparing</A
- ></H3
- ><P
- >
It is possible to compare arrays by <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > and
- by <A
- HREF="#language.operators.array"
- >Array operators</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.array.examples"
- >Examples</A
- ></H3
- ><P
- >
The array type in PHP is very versatile, so here will be some
- examples to show you the full power of arrays.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3180"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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')
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3182"
- ></A
- ><P
- ><B
- >Example 11-5. Using array()</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="language.types.array.examples.loop"
- ></A
- ><P
- ><B
- >Example 11-6. Collection</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $colors = array('red', 'blue', 'green', 'yellow');
-
- foreach ($colors as $color) {
- echo "Do you like $color?\n";
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Do you like red?
- Do you like blue?
- Do you like green?
- Do you like yellow?</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Note that it is currently not possible to change the values of the array
- directly in such a loop.
-
- A workaround is the following:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="language.types.array.examples.changeloop"
- ></A
- ><P
- ><B
- >Example 11-7. Collection</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- foreach ($colors as $key => $color) {
- // won't work:
- //$color = strtoupper($color);
-
- // works:
- $colors[$key] = strtoupper($color);
- }
- print_r($colors);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => RED
- [1] => BLUE
- [2] => GREEN
- [3] => YELLOW
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This example creates a one-based array.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3197"
- ></A
- ><P
- ><B
- >Example 11-8. One-based index</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $firstquarter = array(1 => 'January', 'February', 'March');
- print_r($firstquarter);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [1] => 'January'
- [2] => 'February'
- [3] => 'March'
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3202"
- ></A
- ><P
- ><B
- >Example 11-9. Filling an array</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // fill an array with all items from a directory
- $handle = opendir('.');
- while (false !== ($file = readdir($handle))) {
- $files[] = $file;
- }
- closedir($handle);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Arrays are ordered. You can also change the order using various
- sorting functions. See the <A
- HREF="#ref.array"
- >array
- functions</A
- > section for more information. You can count
- the number of items in an array using the
- <A
- HREF="#function.count"
- ><B
- CLASS="function"
- >count()</B
- ></A
- > function.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3208"
- ></A
- ><P
- ><B
- >Example 11-10. Sorting an array</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- sort($files);
- print_r($files);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
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.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3212"
- ></A
- ><P
- ><B
- >Example 11-11. Recursive and multi-dimensional arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
You should be aware that array assignment always involves
- value copying. You need to use the reference operator to copy
- an array by reference.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3216"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.object"
- >Objects</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.types.object.init"
- >Object Initialization</A
- ></H3
- ><P
- >
To initialize an object, you use the <VAR
- CLASS="literal"
- >new</VAR
- >
- statement to instantiate the object to a variable.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3224"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class foo
- {
- function do_foo()
- {
- echo "Doing foo.";
- }
- }
-
- $bar = new foo;
- $bar->do_foo();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
For a full discussion, please read the section <A
- HREF="#language.oop"
- >Classes and Objects</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.object.casting"
- >Converting to object</A
- ></H3
- ><P
- >
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
- <VAR
- CLASS="literal"
- >stdClass</VAR
- > built in class is created. If the value
- was null, the new instance will be empty. For any other value, a
- member variable named <VAR
- CLASS="literal"
- >scalar</VAR
- > will contain the
- value.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3233"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $obj = (object) 'ciao';
- echo $obj->scalar; // outputs 'ciao'
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.resource"
- >Resource</A
- ></H2
- ><P
- >
A resource is a special variable, holding
- a reference to an external resource. Resources
- are created and used by special functions.
- See the <A
- HREF="#resource"
- >appendix</A
- >
- for a listing of all these
- functions and the corresponding resource types.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The resource type was introduced in PHP 4
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.resource.casting"
- >Converting to resource</A
- ></H3
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.resource.self-destruct"
- >Freeing resources</A
- ></H3
- ><P
- >
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.
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Persistent database links are special, they
- are <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > destroyed by the
- garbage collector. See also the section about <A
- HREF="#features.persistent-connections"
- >persistent
- connections</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.null"
- >NULL</A
- ></H2
- ><P
- >
The special <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > value represents
- that a variable has no value. <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > is the only possible value of type
- <A
- HREF="#language.types.null"
- ><B
- CLASS="type"
- >NULL</B
- ></A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The null type was introduced in PHP 4
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
A variable is considered to be <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > if
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
it has been assigned the constant <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- >.
- </P
- ></LI
- ><LI
- ><P
- >
it has not been set to any value yet.
- </P
- ></LI
- ><LI
- ><P
- >
it has been <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >.
- </P
- ></LI
- ></UL
- >
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.null.syntax"
- >Syntax</A
- ></H3
- ><P
- >
There is only one value of type <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- >, and that is
- the case-insensitive keyword <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- >.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3275"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $var = NULL;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
See also <A
- HREF="#function.is-null"
- ><B
- CLASS="function"
- >is_null()</B
- ></A
- > and <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.pseudo-types"
- >Pseudo-types used in this documentation</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.types.mixed"
- >mixed</A
- ></H3
- ><P
- >
<VAR
- CLASS="literal"
- >mixed</VAR
- > indicates that a parameter may accept multiple (but not
- necessarily all) types.
- </P
- ><P
- >
<A
- HREF="#function.gettype"
- ><B
- CLASS="function"
- >gettype()</B
- ></A
- > for example will accept all PHP types,
- while <A
- HREF="#function.str-replace"
- ><B
- CLASS="function"
- >str_replace()</B
- ></A
- > will accept strings and arrays.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.number"
- >number</A
- ></H3
- ><P
- >
<VAR
- CLASS="literal"
- >number</VAR
- > indicates that a parameter can be either
- <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > or <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.callback"
- >callback</A
- ></H3
- ><P
- >
Some functions like <A
- HREF="#function.call-user-func"
- ><B
- CLASS="function"
- >call_user_func()</B
- ></A
- >
- or <A
- HREF="#function.usort"
- ><B
- CLASS="function"
- >usort()</B
- ></A
- > accept user defined
- callback functions as a parameter. Callback functions can not only
- be simple functions but also object methods including static class
- methods.
- </P
- ><P
- >
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
- <A
- HREF="#function.array"
- ><B
- CLASS="function"
- >array()</B
- ></A
- >,
- <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- >,
- <A
- HREF="#function.empty"
- ><B
- CLASS="function"
- >empty()</B
- ></A
- >,
- <A
- HREF="#function.eval"
- ><B
- CLASS="function"
- >eval()</B
- ></A
- >,
- <A
- HREF="#function.exit"
- ><B
- CLASS="function"
- >exit()</B
- ></A
- >,
- <A
- HREF="#function.isset"
- ><B
- CLASS="function"
- >isset()</B
- ></A
- >,
- <A
- HREF="#function.list"
- ><B
- CLASS="function"
- >list()</B
- ></A
- >,
- <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- > and
- <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3313"
- ></A
- ><P
- ><B
- >Example 11-12.
- Callback function examples
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // An example callback function
- function my_callback_function() {
- echo 'hello world!';
- }
-
- // An example callback method
- class MyClass {
- function myCallbackMethod() {
- echo 'Hello World!';
- }
- }
-
- // Type 1: Simple callback
- call_user_func('my_callback_function');
-
- // Type 2: Static class method call
- call_user_func(array('MyClass', 'myCallbackMethod'));
-
- // Type 3: Object method call
- $obj = new MyClass();
- call_user_func(array(&$obj, 'myCallbackMethod'));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.types.type-juggling"
- >Type Juggling</A
- ></H2
- ><P
- >
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
- CLASS="parameter"
- >$var</VAR
- >,
- <VAR
- CLASS="parameter"
- >$var</VAR
- > becomes a string. If you then assign an
- integer value to <VAR
- CLASS="parameter"
- >$var</VAR
- >, it becomes an
- integer.
- </P
- ><P
- >
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.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3323"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
If the last two examples above seem odd, see <A
- HREF="#language.types.string.conversion"
- >String
- conversion to numbers</A
- >.
- </P
- ><P
- >
If you wish to force a variable to be evaluated as a certain type,
- see the section on <A
- HREF="#language.types.typecasting"
- >Type
- casting</A
- >. If you wish to change the type of a variable, see
- <A
- HREF="#function.settype"
- ><B
- CLASS="function"
- >settype()</B
- ></A
- >.
- </P
- ><P
- >
If you would like to test any of the examples in this section, you
- can use the <A
- HREF="#function.var-dump"
- ><B
- CLASS="function"
- >var_dump()</B
- ></A
- > function.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The behaviour of an automatic conversion to array is currently
- undefined.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3335"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = "1"; // $a is a string
- $a[0] = "f"; // What about string offsets? What happens?
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
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?
- </P
- ><P
- >
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:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3339"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = "abc"; // $a is a string
- $a{1} = "f"; // $a is now "afc"
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- See the section titled <A
- HREF="#language.types.string.substr"
- >String
- access by character</A
- > for more information.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.types.typecasting"
- >Type Casting</A
- ></H3
- ><P
- >
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.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3345"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $foo = 10; // $foo is an integer
- $bar = (boolean) $foo; // $bar is a boolean
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The casts allowed are:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >(int), (integer) - cast to integer</P
- ></LI
- ><LI
- ><P
- >(bool), (boolean) - cast to boolean</P
- ></LI
- ><LI
- ><P
- >(float), (double), (real) - cast to float</P
- ></LI
- ><LI
- ><P
- >(string) - cast to string</P
- ></LI
- ><LI
- ><P
- >(array) - cast to array</P
- ></LI
- ><LI
- ><P
- >(object) - cast to object</P
- ></LI
- ></UL
- >
- </P
- ><P
- >
Note that tabs and spaces are allowed inside the parentheses, so
- the following are functionally equivalent:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3362"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $foo = (int) $bar;
- $foo = ( int ) $bar;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Instead of casting a variable to string, you can also enclose
- the variable in double quotes.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3366"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
It may not be obvious exactly what will happen when casting
- between certain types. For more info, see these sections:
-
- <P
- ></P
- ><UL
- ><LI
- ><P
- ><A
- HREF="#language.types.boolean.casting"
- >Converting to
- boolean</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.integer.casting"
- >Converting to
- integer</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.float.casting"
- >Converting to
- float</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.string.casting"
- >Converting to
- string</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.array.casting"
- >Converting to
- array</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.object.casting"
- >Converting to
- object</A
- ></P
- ></LI
- ><LI
- ><P
- ><A
- HREF="#language.types.resource.casting"
- >Converting to
- resource</A
- ></P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#types.comparisons"
- >The type comparison tables</A
- >
- </P
- ></LI
- ></UL
- >
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.variables"
- >Chapter 12. Variables</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="language.variables.basics"
- >Basics</A
- ></H2
- ><P
- >
Variables in PHP are represented by a dollar sign followed by the
- name of the variable. The variable name is case-sensitive.
- </P
- ><P
- >
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]*'
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For our purposes here, a letter is a-z, A-Z, and the ASCII
- characters from 127 through 255 (0x7f-0xff).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
For information on variable related functions, see the
- <A
- HREF="#ref.var"
- >Variable Functions Reference</A
- >.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3405"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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.
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
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 <A
- HREF="#language.expressions"
- >Expressions</A
- >.
- </P
- ><P
- >
As of PHP 4, PHP offers another way to assign values to variables:
- <A
- HREF="#language.references"
- >assign by reference</A
- >.
- 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
- <A
- HREF="#language.types.array"
- >arrays</A
- > or
- <A
- HREF="#language.types.object"
- >objects</A
- >.
- </P
- ><P
- >
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:
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3414"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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.
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
One important thing to note is that only named variables may be
- assigned by reference.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3417"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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.
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.variables.predefined"
- >Predefined variables</A
- ></H2
- ><P
- >
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
- <A
- HREF="#features.commandline"
- >command line</A
- >.
- For a listing of these variables, please see the section on
- <A
- HREF="#reserved.variables"
- >Reserved Predefined Variables</A
- >.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
In PHP 4.2.0 and later, the default value for the PHP directive <A
- HREF="#ini.register-globals"
- >register_globals</A
- > is
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >off</I
- ></SPAN
- >. This is a major change in PHP. Having
- register_globals <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >off</I
- ></SPAN
- > affects the set of predefined
- variables available in the global scope. For example, to get
- <VAR
- CLASS="varname"
- >DOCUMENT_ROOT</VAR
- > you'll use
- <VAR
- CLASS="varname"
- >$_SERVER['DOCUMENT_ROOT']</VAR
- > instead of
- <VAR
- CLASS="varname"
- >$DOCUMENT_ROOT</VAR
- >, or <VAR
- CLASS="varname"
- >$_GET['id']</VAR
- > from
- the URL <VAR
- CLASS="literal"
- >http://www.example.com/test.php?id=3</VAR
- > instead
- of <VAR
- CLASS="varname"
- >$id</VAR
- >, or <VAR
- CLASS="varname"
- >$_ENV['HOME']</VAR
- > instead of
- <VAR
- CLASS="varname"
- >$HOME</VAR
- >.
- </P
- ><P
- >
For related information on this change, read the configuration entry for
- <A
- HREF="#ini.register-globals"
- >register_globals</A
- >, the security
- chapter on <A
- HREF="#security.globals"
- >Using Register Globals
- </A
- >, as well as the PHP <A
- HREF="http://www.php.net/release_4_1_0.php"
- TARGET="_top"
- >4.1.0
- </A
- > and <A
- HREF="http://www.php.net/release_4_2_0.php"
- TARGET="_top"
- >4.2.0</A
- > Release
- Announcements.
- </P
- ><P
- >
Using the available PHP Reserved Predefined Variables, like the
- <A
- HREF="#language.variables.superglobals"
- >superglobal arrays</A
- >,
- is preferred.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
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
- <A
- HREF="#reserved.variables"
- >Reserved Predefined Variables</A
- >.
- Also, you'll notice how the older predefined variables
- (<VAR
- CLASS="varname"
- >$HTTP_*_VARS</VAR
- >) still exist.
-
- As of PHP 5.0.0, the long PHP
- <A
- HREF="#language.variables.predefined"
- >predefined variable</A
- >
- arrays may be disabled with the
- <A
- HREF="#ini.register-long-arrays"
- >register_long_arrays</A
- >
- directive.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Variable variables: </B
- >
- Superglobals cannot be used as
- <A
- HREF="#language.variables.variable"
- >variable variables</A
- >
- inside functions or class methods.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Even though both the superglobal and HTTP_*_VARS can exist at the same
- time; they are not identical, so modifying one will not change the other.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
If certain variables in <A
- HREF="#ini.variables-order"
- >variables_order</A
- > are not set, their
- appropriate PHP predefined arrays are also left empty.
- </P
- ><P
- ></P
- ><DIV
- CLASS="variablelist"
- ><P
- ><B
- >PHP Superglobals</B
- ></P
- ><DL
- ><DT
- ><A
- HREF="#reserved.variables.globals"
- >$GLOBALS</A
- ></DT
- ><DD
- ><P
- >
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.
- <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > has existed since PHP 3.
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.server"
- >$_SERVER</A
- ></DT
- ><DD
- ><P
- >
Variables set by the web server or otherwise directly related
- to the execution environment of the current script. Analogous
- to the old <VAR
- CLASS="varname"
- >$HTTP_SERVER_VARS</VAR
- > array (which is
- still available, but deprecated).
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.get"
- >$_GET</A
- ></DT
- ><DD
- ><P
- >
Variables provided to the script via HTTP GET. Analogous to the
- old <VAR
- CLASS="varname"
- >$HTTP_GET_VARS</VAR
- > array (which is still
- available, but deprecated).
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.post"
- >$_POST</A
- ></DT
- ><DD
- ><P
- >
Variables provided to the script via HTTP POST. Analogous to the
- old <VAR
- CLASS="varname"
- >$HTTP_POST_VARS</VAR
- > array (which is still
- available, but deprecated).
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.cookies"
- >$_COOKIE</A
- ></DT
- ><DD
- ><P
- >
Variables provided to the script via HTTP cookies. Analogous to
- the old <VAR
- CLASS="varname"
- >$HTTP_COOKIE_VARS</VAR
- > array (which is
- still available, but deprecated).
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.files"
- >$_FILES</A
- ></DT
- ><DD
- ><P
- >
Variables provided to the script via HTTP post file
- uploads. Analogous to the old
- <VAR
- CLASS="varname"
- >$HTTP_POST_FILES</VAR
- > array (which is still
- available, but deprecated). See <A
- HREF="#features.file-upload.post-method"
- >POST method
- uploads</A
- > for more information.
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.environment"
- >$_ENV</A
- ></DT
- ><DD
- ><P
- >
Variables provided to the script via the environment. Analogous
- to the old <VAR
- CLASS="varname"
- >$HTTP_ENV_VARS</VAR
- > array (which is
- still available, but deprecated).
- </P
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.request"
- >$_REQUEST</A
- ></DT
- ><DD
- ><P
- >
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 <A
- HREF="#ini.variables-order"
- >variables_order</A
- >
- configuration directive. This array has no direct analogue in versions
- of PHP prior to 4.1.0. See also
- <A
- HREF="#function.import-request-variables"
- ><B
- CLASS="function"
- >import_request_variables()</B
- ></A
- >.
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Since PHP 4.3.0, FILE information from <VAR
- CLASS="varname"
- >$_FILES</VAR
- > does
- not exist in <VAR
- CLASS="varname"
- >$_REQUEST</VAR
- >.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- When running on the <A
- HREF="#features.commandline"
- >command line
- </A
- >, this will <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > include the
- <VAR
- CLASS="varname"
- >argv</VAR
- > and <VAR
- CLASS="varname"
- >argc</VAR
- > entries; these are
- present in the <VAR
- CLASS="varname"
- >$_SERVER</VAR
- > array.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DD
- ><DT
- ><A
- HREF="#reserved.variables.session"
- >$_SESSION</A
- ></DT
- ><DD
- ><P
- >
Variables which are currently registered to a script's
- session. Analogous to the old
- <VAR
- CLASS="varname"
- >$HTTP_SESSION_VARS</VAR
- > array (which is still
- available, but deprecated). See the <A
- HREF="#ref.session"
- >Session handling functions</A
- > section
- for more information.
- </P
- ></DD
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.variables.scope"
- >Variable scope</A
- ></H2
- ><P
- >
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:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3530"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1;
- include "b.inc";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Here the <VAR
- CLASS="varname"
- >$a</VAR
- > variable will be available within
- the included <TT
- CLASS="filename"
- >b.inc</TT
- > 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:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3535"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1; /* global scope */
-
- function Test()
- {
- echo $a; /* reference to local scope variable */
- }
-
- Test();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
This script will not produce any output because the echo statement
- refers to a local version of the <VAR
- CLASS="varname"
- >$a</VAR
- > 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.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.scope.global"
- >The global keyword</A
- ></H3
- ><P
- >
First, an example use of <VAR
- CLASS="literal"
- >global</VAR
- >:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3544"
- ></A
- ><P
- ><B
- >Example 12-1. Using global</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1;
- $b = 2;
-
- function Sum()
- {
- global $a, $b;
-
- $b = $a + $b;
- }
-
- Sum();
- echo $b;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The above script will output "3". By declaring
- <VAR
- CLASS="varname"
- >$a</VAR
- > and <VAR
- CLASS="varname"
- >$b</VAR
- > 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.
- </P
- ><P
- >
A second way to access variables from the global scope is to use
- the special PHP-defined <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > array. The
- previous example can be rewritten as:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3553"
- ></A
- ><P
- ><B
- >Example 12-2. Using <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > instead of global</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1;
- $b = 2;
-
- function Sum()
- {
- $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
- }
-
- Sum();
- echo $b;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > 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 <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > exists in any scope, this
- is because $GLOBALS is a <A
- HREF="#language.variables.superglobals"
- >superglobal</A
- >.
- Here's an example demonstrating the power of superglobals:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3562"
- ></A
- ><P
- ><B
- >Example 12-3. Example demonstrating superglobals and scope</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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'];
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.scope.static"
- >Using static variables</A
- ></H3
- ><P
- >
Another important feature of variable scoping is the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >static</I
- ></SPAN
- > 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:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3570"
- ></A
- ><P
- ><B
- >Example 12-4. Example demonstrating need for static variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function Test ()
- {
- $a = 0;
- echo $a;
- $a++;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This function is quite useless since every time it is called it
- sets <VAR
- CLASS="varname"
- >$a</VAR
- > to <VAR
- CLASS="literal"
- >0</VAR
- > and prints
- "0". The <VAR
- CLASS="varname"
- >$a</VAR
- >++ which increments the
- variable serves no purpose since as soon as the function exits the
- <VAR
- CLASS="varname"
- >$a</VAR
- > variable disappears. To make a useful
- counting function which will not lose track of the current count,
- the <VAR
- CLASS="varname"
- >$a</VAR
- > variable is declared static:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3580"
- ></A
- ><P
- ><B
- >Example 12-5. Example use of static variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function Test()
- {
- static $a = 0;
- echo $a;
- $a++;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Now, every time the Test() function is called it will print the
- value of <VAR
- CLASS="varname"
- >$a</VAR
- > and increment it.
- </P
- ><P
- >
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 <VAR
- CLASS="varname"
- >$count</VAR
- > to know when to stop:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3588"
- ></A
- ><P
- ><B
- >Example 12-6. Static variables with recursive functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function Test()
- {
- static $count = 0;
-
- $count++;
- echo $count;
- if ($count < 10) {
- Test ();
- }
- $count--;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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.
- </P
- ><P
- >
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3594"
- ></A
- ><P
- ><B
- >Example 12-7. Declaring static variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.scope.references"
- >References with global and static variables</A
- ></H3
- ><P
- >
The Zend Engine 1, driving PHP 4, implements the
- <A
- HREF="#language.variables.scope.static"
- >static</A
- > and
- <A
- HREF="#language.variables.scope.global"
- >global</A
- > modifier
- for variables in terms of <A
- HREF="#language.references"
- >
references</A
- >. For example, a true global variable
- imported inside a function scope with the <VAR
- CLASS="literal"
- >global</VAR
- >
- statement actually creates a reference to the global variable. This can
- lead to unexpected behaviour which the following example addresses:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3604"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Executing this example will result in the following output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >NULL
- object(stdClass)(0) {
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
A similar behaviour applies to the <VAR
- CLASS="literal"
- >static</VAR
- > statement.
- References are not stored statically:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3610"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Executing this example will result in the following output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Static object: NULL
- Static object: NULL
-
- Static object: NULL
- Static object: object(stdClass)(1) {
- ["property"]=>
- int(1)
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This example demonstrates that when assigning a reference to a static
- variable, it's not <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >remembered</I
- ></SPAN
- > when you call the
- <VAR
- CLASS="literal"
- >&get_instance_ref()</VAR
- > function a second time.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.variables.variable"
- >Variable variables</A
- ></H2
- ><P
- >
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:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3620"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = "hello";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
A variable variable takes the value of a variable and treats that
- as the name of a variable. In the above example,
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >hello</I
- ></SPAN
- >, can be used as the name of a variable
- by using two dollar signs. i.e.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3624"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $$a = "world";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
At this point two variables have been defined and stored in the
- PHP symbol tree: <VAR
- CLASS="varname"
- >$a</VAR
- > with contents "hello" and
- <VAR
- CLASS="varname"
- >$hello</VAR
- > with contents "world". Therefore, this
- statement:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3629"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "$a ${$a}";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
produces the exact same output as:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3632"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "$a $hello";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
i.e. they both produce: <SAMP
- CLASS="computeroutput"
- >hello world</SAMP
- >.
- </P
- ><P
- >
In order to use variable variables with arrays, you have to
- resolve an ambiguity problem. That is, if you write
- <VAR
- CLASS="varname"
- >$$a[1]</VAR
- > then the parser needs to know if you
- meant to use <VAR
- CLASS="varname"
- >$a[1]</VAR
- > as a variable, or if you
- wanted <VAR
- CLASS="varname"
- >$$a</VAR
- > as the variable and then the [1]
- index from that variable. The syntax for resolving this ambiguity
- is: <VAR
- CLASS="varname"
- >${$a[1]}</VAR
- > for the first case and
- <VAR
- CLASS="varname"
- >${$a}[1]</VAR
- > for the second.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Please note that variable variables cannot be used with PHP's
- <A
- HREF="#language.variables.superglobals"
- >Superglobal arrays</A
- >
- within functions or class methods.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.variables.external"
- >Variables from outside PHP</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.external.form"
- >HTML Forms (GET and POST)</A
- ></H3
- ><P
- >
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:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3651"
- ></A
- ><P
- ><B
- >Example 12-8. A simple HTML form</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Depending on your particular setup and personal preferences, there
- are many ways to access data from your HTML forms. Some examples are:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3656"
- ></A
- ><P
- ><B
- >Example 12-9. Accessing data from a simple POST HTML form</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><?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;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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, <VAR
- CLASS="literal"
- >http://www.example.com/test.php?id=3</VAR
- >
- contains GET data which is accessible with <VAR
- CLASS="varname"
- >$_GET['id']</VAR
- >.
- See also <A
- HREF="#reserved.variables.request"
- >$_REQUEST</A
- > and
- <A
- HREF="#function.import-request-variables"
- ><B
- CLASS="function"
- >import_request_variables()</B
- ></A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="#language.variables.superglobals"
- >Superglobal arrays</A
- >,
- like <VAR
- CLASS="varname"
- >$_POST</VAR
- > and <VAR
- CLASS="varname"
- >$_GET</VAR
- >, became
- available in PHP 4.1.0
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
As shown, before PHP 4.2.0 the default value for <A
- HREF="#ini.register-globals"
- >register_globals</A
- >
- was <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >on</I
- ></SPAN
- >. 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 <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >off</I
- ></SPAN
- > and code
- accordingly.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The <A
- HREF="#ini.magic-quotes-gpc"
- >magic_quotes_gpc</A
- >
- 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
- <A
- HREF="#function.addslashes"
- ><B
- CLASS="function"
- >addslashes()</B
- ></A
- >, <A
- HREF="#function.stripslashes"
- ><B
- CLASS="function"
- >stripslashes()</B
- ></A
- > and
- <A
- HREF="#ini.magic-quotes-sybase"
- >magic_quotes_sybase</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
PHP also understands arrays in the context of form variables
- (see the <A
- HREF="#faq.html"
- >related faq</A
- >). 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:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3682"
- ></A
- ><P
- ><B
- >Example 12-10. More complex form variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In PHP 3, the array form variable usage is limited to
- single-dimensional arrays. As of PHP 4, no such restriction applies.
- </P
- ><DIV
- CLASS="sect3"
- ><HR><H4
- CLASS="sect3"
- ><A
- NAME="language.variables.external.form.submit"
- >IMAGE SUBMIT variable names</A
- ></H4
- ><P
- >
When submitting a form, it is possible to use an image instead
- of the standard submit button with a tag like:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3689"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><input type="image" src="image.gif" name="sub" /></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
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.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.external.cookies"
- >HTTP Cookies</A
- ></H3
- ><P
- >
PHP transparently supports HTTP cookies as defined by <A
- HREF="http://www.netscape.com/newsref/std/cookie_spec.html"
- TARGET="_top"
- >Netscape's Spec</A
- >. Cookies are a
- mechanism for storing data in the remote browser and thus
- tracking or identifying return users. You can set cookies using
- the <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > 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 <A
- HREF="#function.header"
- ><B
- CLASS="function"
- >header()</B
- ></A
- > function. Cookie data
- is then available in the appropriate cookie data arrays, such
- as <VAR
- CLASS="varname"
- >$_COOKIE</VAR
- >, <VAR
- CLASS="varname"
- >$HTTP_COOKIE_VARS</VAR
- >
- as well as in <VAR
- CLASS="varname"
- >$_REQUEST</VAR
- >. See the
- <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > manual page for more details and
- examples.
- </P
- ><P
- >
If you wish to assign multiple values to a single cookie variable, you
- may assign it as an array. For example:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3703"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- setcookie("MyCookie[foo]", "Testing 1", time()+3600);
- setcookie("MyCookie[bar]", "Testing 2", time()+3600);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
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 <A
- HREF="#function.serialize"
- ><B
- CLASS="function"
- >serialize()</B
- ></A
- > or
- <A
- HREF="#function.explode"
- ><B
- CLASS="function"
- >explode()</B
- ></A
- > on the value first.
- </P
- ><P
- >
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.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3709"
- ></A
- ><P
- ><B
- >Example 12-11. A <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if (isset($_COOKIE['count'])) {
- $count = $_COOKIE['count'] + 1;
- } else {
- $count = 1;
- }
- setcookie("count", $count, time()+3600);
- setcookie("Cart[$count]", $item, time()+3600);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.external.dot-in-names"
- >Dots in incoming variable names</A
- ></H3
- ><P
- >
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:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $varname.ext; /* invalid variable name */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- Now, what the parser sees is a variable named
- <VAR
- CLASS="varname"
- >$varname</VAR
- >, 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.
- </P
- ><P
- >
For this reason, it is important to note that PHP will
- automatically replace any dots in incoming variable names with
- underscores.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.variables.determining-type-of"
- >Determining variable types</A
- ></H3
- ><P
- >
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:
- <A
- HREF="#function.gettype"
- ><B
- CLASS="function"
- >gettype()</B
- ></A
- >, <A
- HREF="#function.is-array"
- ><B
- CLASS="function"
- >is_array()</B
- ></A
- >,
- <A
- HREF="#function.is-float"
- ><B
- CLASS="function"
- >is_float()</B
- ></A
- >, <A
- HREF="#function.is-int"
- ><B
- CLASS="function"
- >is_int()</B
- ></A
- >,
- <A
- HREF="#function.is-object"
- ><B
- CLASS="function"
- >is_object()</B
- ></A
- >, and
- <A
- HREF="#function.is-string"
- ><B
- CLASS="function"
- >is_string()</B
- ></A
- >. See also the chapter on
- <A
- HREF="#language.types"
- >Types</A
- >.
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.constants"
- >Chapter 13. Constants</A
- ></H1
- ><P
- >
A constant is an identifier (name) for a simple value. As the name
- suggests, that value cannot change during the execution of the
- script (except for <A
- HREF="#language.constants.predefined"
- >
magic constants</A
- >, which aren't actually constants).
- A constant is case-sensitive by default. By convention, constant
- identifiers are always uppercase.
- </P
- ><P
- >
The name of a constant follows the same rules as any label in PHP. A
- valid constant name starts with a letter or underscore, followed
- by any number of letters, numbers, or underscores. As a regular
- expression, it would be expressed thusly:
- <VAR
- CLASS="literal"
- >[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*</VAR
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3736"
- ></A
- ><P
- ><B
- >Example 13-1. Valid and invalid constant names</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- // Valid constant names
- define("FOO", "something");
- define("FOO2", "something else");
- define("FOO_BAR", "something more")
-
- // Invalid constant names
- define("2FOO", "something");
-
- // This is valid, but should be avoided:
- // PHP may one day provide a magical constant
- // that will break your script
- define("__FOO__", "something");
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For our purposes here, a letter is a-z, A-Z, and the ASCII
- characters from 127 through 255 (0x7f-0xff).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Like <A
- HREF="#language.variables.predefined"
- >superglobals</A
- >, the scope of a constant is global. You
- can access constants anywhere in your script without regard to scope.
- For more information on scope, read the manual section on
- <A
- HREF="#language.variables.scope"
- >variable scope</A
- >.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.constants.syntax"
- >Syntax</A
- ></H2
- ><P
- >
You can define a constant by using the
- <A
- HREF="#function.define"
- ><B
- CLASS="function"
- >define()</B
- ></A
- >-function. Once a constant is defined,
- it can never be changed or undefined.
- </P
- ><P
- >
Only scalar data (<A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- >, <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >,
- <A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- > and <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >) can be contained
- in constants.
- </P
- ><P
- >
You can get the value of a constant by simply specifying its name.
- Unlike with variables, you should <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > prepend
- a constant with a <VAR
- CLASS="literal"
- >$</VAR
- >.
- You can also use the function <A
- HREF="#function.constant"
- ><B
- CLASS="function"
- >constant()</B
- ></A
- > to
- read a constant's value if you wish to obtain the constant's name
- dynamically.
- Use <A
- HREF="#function.get-defined-constants"
- ><B
- CLASS="function"
- >get_defined_constants()</B
- ></A
- > to get a list of
- all defined constants.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Constants and (global) variables are in a different namespace.
- This implies that for example <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > and
- <VAR
- CLASS="varname"
- >$TRUE</VAR
- > are generally different.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
If you use an undefined constant, PHP assumes that you mean
- the name of the constant itself, just as if you called it as
- a <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- > (CONSTANT vs "CONSTANT"). An error of level
- <A
- HREF="#ref.errorfunc"
- >E_NOTICE</A
- > will be issued
- when this happens. See also the manual entry on why
- <A
- HREF="#language.types.array.foo-bar"
- >$foo[bar]</A
- > is
- wrong (unless you first <A
- HREF="#function.define"
- ><B
- CLASS="function"
- >define()</B
- ></A
- >
- <VAR
- CLASS="literal"
- >bar</VAR
- > as a constant). If you simply want to check if a
- constant is set, use the <A
- HREF="#function.defined"
- ><B
- CLASS="function"
- >defined()</B
- ></A
- > function.
- </P
- ><P
- >
These are the differences between constants and variables:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Constants do not have a dollar sign (<VAR
- CLASS="literal"
- >$</VAR
- >)
- before them;
- </P
- ></LI
- ><LI
- ><P
- >
Constants may only be defined using the
- <A
- HREF="#function.define"
- ><B
- CLASS="function"
- >define()</B
- ></A
- > function, not by simple assignment;
- </P
- ></LI
- ><LI
- ><P
- >
Constants may be defined and accessed anywhere without regard
- to variable scoping rules;
- </P
- ></LI
- ><LI
- ><P
- >
Constants may not be redefined or undefined once they have been
- set; and
- </P
- ></LI
- ><LI
- ><P
- >
Constants may only evaluate to scalar values.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3784"
- ></A
- ><P
- ><B
- >Example 13-2. Defining Constants</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- define("CONSTANT", "Hello world.");
- echo CONSTANT; // outputs "Hello world."
- echo Constant; // outputs "Constant" and issues a notice.
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
-
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.constants.predefined"
- >Magic constants</A
- ></H2
- ><P
- >
PHP provides a large number of <A
- HREF="#reserved.constants"
- >predefined constants</A
- > to any script
- which it runs. Many of these constants, however, are created by
- various extensions, and will only be present when those extensions
- are available, either via dynamic loading or because they have
- been compiled in.
- </P
- ><P
- >
There are five magical constants that change depending on
- where they are used. For example, the value of
- <TT
- CLASS="constant"
- ><B
- >__LINE__</B
- ></TT
- > depends on the line that it's
- used on in your script. These special constants are
- case-insensitive and are as follows:
- </P
- ><P
- >
<DIV
- CLASS="table"
- ><A
- NAME="AEN3794"
- ></A
- ><P
- ><B
- >Table 13-1. A few "magical" PHP constants</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >Name</TH
- ><TH
- >Description</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >__LINE__</B
- ></TT
- ></TD
- ><TD
- >
The current line number of the file.
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >__FILE__</B
- ></TT
- ></TD
- ><TD
- >
The full path and filename of the file. If used inside an include,
- the name of the included file is returned.
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >__FUNCTION__</B
- ></TT
- ></TD
- ><TD
- >
The function name. (Added in PHP 4.3.0) As of PHP 5 this constant
- returns the function name as it was declared (case-sensitive). In
- PHP 4 its value is always lowercased.
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >__CLASS__</B
- ></TT
- ></TD
- ><TD
- >
The class name. (Added in PHP 4.3.0) As of PHP 5 this constant
- returns the class name as it was declared (case-sensitive). In PHP
- 4 its value is always lowercased.
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >__METHOD__</B
- ></TT
- ></TD
- ><TD
- >
The class method name. (Added in PHP 5.0.0) The method name is
- returned as it was declared (case-sensitive).
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
See also
- <A
- HREF="#function.get-class"
- ><B
- CLASS="function"
- >get_class()</B
- ></A
- >,
- <A
- HREF="#function.get-object-vars"
- ><B
- CLASS="function"
- >get_object_vars()</B
- ></A
- >,
- <A
- HREF="#function.file-exists"
- ><B
- CLASS="function"
- >file_exists()</B
- ></A
- > and
- <A
- HREF="#function.function-exists"
- ><B
- CLASS="function"
- >function_exists()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.expressions"
- >Chapter 14. Expressions</A
- ></H1
- ><P
- >
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".
- </P
- ><P
- >
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).
- </P
- ><P
- >
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.
- </P
- ><P
- >
Slightly more complex examples for expressions are functions. For
- instance, consider the following function:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3833"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo ()
- {
- return 5;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Assuming you're familiar with the concept of functions (if you're
- not, take a look at the chapter about <A
- HREF="#language.functions"
- >functions</A
- >), you'd assume
- that typing <VAR
- CLASS="literal"
- >$c = foo()</VAR
- > is essentially just like
- writing <VAR
- CLASS="literal"
- >$c = 5</VAR
- >, 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.
- </P
- ><P
- >
Of course, values in PHP don't have to be integers, and very often
- they aren't. PHP supports four scalar value types: <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >
- values, floating point values (<A
- HREF="#language.types.float"
- ><B
- CLASS="type"
- >float</B
- ></A
- >), <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >
- values and <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- > 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.
- </P
- ><P
- >
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'.
- </P
- ><P
- >
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 <A
- HREF="#language.operators.increment"
- >
increment and decrement operators</A
- >. In
- PHP/FI 2, 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').
- </P
- ><P
- >
A very common type of expressions are <A
- HREF="#language.operators.comparison"
- >comparison</A
- >
- expressions. These expressions evaluate to either <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > or <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >. 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 <VAR
- CLASS="literal"
- >if</VAR
- > statements.
- </P
- ><P
- >
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.
- </P
- ><P
- >
There is one more expression that may seem odd if you haven't seen
- it in other languages, the ternary conditional operator:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3855"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $first ? $second : $third
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
If the value of the first subexpression is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > (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.
- </P
- ><P
- >
The following example should help you understand pre- and
- post-increment and expressions in general a bit better:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN3861"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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. */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
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.
- </P
- ><P
- >
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 <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
-
-
-
- The constants <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > and <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > (case-insensitive) are the two
- possible boolean values. When necessary, an expression is
- automatically converted to boolean. See the
- <A
- HREF="#language.types.typecasting"
- >section about
- type-casting</A
- > for details about how.
- </P
- ><P
- >
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 <VAR
- CLASS="varname"
- >expr</VAR
- >
- to indicate any valid PHP expression.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.operators"
- >Chapter 15. Operators</A
- ></H1
- ><P
- >
An operator is something that you feed with one or more values (or
- expressions, in programming jargon) which yields another value (so that the
- construction itself becomes an expression). So you can think of functions
- or constructions that return a value (like print) as operators and those
- that return nothing (like echo) as any other thing.
- </P
- ><P
- >
There are three types of operators. Firstly there is the unary operator which
- operates on only one value, for example ! (the negation operator) or ++
- (the increment operator). The second group are termed binary operators; this
- group contains most of the operators that PHP supports, and a list follows
- below in the section <A
- HREF="#language.operators.precedence"
- >Operator
- Precedence</A
- >.
- </P
- ><P
- >
The third group is the ternary operator: ?:. It should be used to select
- between two expressions depending on a third one, rather than to select two
- sentences or paths of execution. Surrounding ternary expressions with
- parentheses is a very good idea.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.precedence"
- >Operator Precedence</A
- ></H2
- ><P
- >
The precedence of an operator specifies how "tightly" it binds two
- expressions together. For example, in the expression <VAR
- CLASS="literal"
- >1 +
- 5 * 3</VAR
- >, the answer is <VAR
- CLASS="literal"
- >16</VAR
- > and not
- <VAR
- CLASS="literal"
- >18</VAR
- > because the multiplication ("*") operator
- has a higher precedence than the addition ("+") operator.
- Parentheses may be used to force precedence, if necessary. For
- instance: <VAR
- CLASS="literal"
- >(1 + 5) * 3</VAR
- > evaluates to
- <VAR
- CLASS="literal"
- >18</VAR
- >. If operator precedence is equal, left to right
- associativity is used.
- </P
- ><P
- >
The following table lists the precedence of operators with the
- highest-precedence operators listed at the top of the table. Operators
- on the same line have equal precedence, in which case their
- associativity decides which order to evaluate them in.
- <DIV
- CLASS="table"
- ><A
- NAME="AEN3887"
- ></A
- ><P
- ><B
- >Table 15-1. Operator Precedence</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >Associativity</TH
- ><TH
- >Operators</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >non-associative</TD
- ><TD
- >new</TD
- ></TR
- ><TR
- ><TD
- >right</TD
- ><TD
- >[</TD
- ></TR
- ><TR
- ><TD
- >non-associative</TD
- ><TD
- >++ --</TD
- ></TR
- ><TR
- ><TD
- >non-associative</TD
- ><TD
- >! ~ - (int) (float) (string) (array) (object) @</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >* / %</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >+ - .</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- ><< >></TD
- ></TR
- ><TR
- ><TD
- >non-associative</TD
- ><TD
- >< <= > >=</TD
- ></TR
- ><TR
- ><TD
- >non-associative</TD
- ><TD
- >== != === !==</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >&</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >^</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >|</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >&&</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >||</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >? :</TD
- ></TR
- ><TR
- ><TD
- >right</TD
- ><TD
- >
= += -= *= /= .= %= &= |= ^= <<= >>=
- </TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >and</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >xor</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >or</TD
- ></TR
- ><TR
- ><TD
- >left</TD
- ><TD
- >,</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
Left associativity means that the expression is evaluated from left to right,
- right associativity means the opposite.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN3956"
- ></A
- ><P
- ><B
- >Example 15-1. Associativity</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 3 * 3 % 5; // (3 * 3) % 5 = 4
- $a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
-
- $a = 1;
- $b = 2;
- $a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Use parentheses to increase readability of the code.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Although <VAR
- CLASS="literal"
- >!</VAR
- > has a higher precedence than
- <VAR
- CLASS="literal"
- >=</VAR
- >, PHP will still allow expressions
- similar to the following: <VAR
- CLASS="literal"
- >if (!$a = foo())</VAR
- >,
- in which case the output from <VAR
- CLASS="literal"
- >foo()</VAR
- > is
- put into <VAR
- CLASS="varname"
- >$a</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.arithmetic"
- >Arithmetic Operators</A
- ></H2
- ><P
- >
Remember basic arithmetic from school? These work just
- like those.
- </P
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN3969"
- ></A
- ><P
- ><B
- >Table 15-2. Arithmetic Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Result</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >-$a</TD
- ><TD
- >Negation</TD
- ><TD
- >Opposite of $a.</TD
- ></TR
- ><TR
- ><TD
- >$a + $b</TD
- ><TD
- >Addition</TD
- ><TD
- >Sum of $a and $b.</TD
- ></TR
- ><TR
- ><TD
- >$a - $b</TD
- ><TD
- >Subtraction</TD
- ><TD
- >Difference of $a and $b.</TD
- ></TR
- ><TR
- ><TD
- >$a * $b</TD
- ><TD
- >Multiplication</TD
- ><TD
- >Product of $a and $b.</TD
- ></TR
- ><TR
- ><TD
- >$a / $b</TD
- ><TD
- >Division</TD
- ><TD
- >Quotient of $a and $b.</TD
- ></TR
- ><TR
- ><TD
- >$a % $b</TD
- ><TD
- >Modulus</TD
- ><TD
- >Remainder of $a divided by $b.</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
The division operator ("/") returns a float value anytime,
- even if the two operands are integers (or strings that get
- converted to integers).
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Remainder <VAR
- CLASS="literal"
- >$a % $b</VAR
- > is negative for negative
- <VAR
- CLASS="literal"
- >$a</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also the manual page on
- <A
- HREF="#ref.math"
- >Math functions</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.assignment"
- >Assignment Operators</A
- ></H2
- ><P
- >
The basic assignment operator is "=". Your first inclination might
- be to think of this as "equal to". Don't. It really means that the
- the left operand gets set to the value of the expression on the
- rights (that is, "gets set to").
- </P
- ><P
- >
The value of an assignment expression is the value assigned. That
- is, the value of "$a = 3" is 3. This allows you to do some tricky
- things:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4013"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
In addition to the basic assignment operator, there are "combined
- operators" for all of the <A
- HREF="#language.operators"
- >binary
- arithmetic</A
- > and string operators that allow you to use a value in an
- expression and then set its value to the result of that expression. For
- example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4017"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $a = 3;
- $a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
- $b = "Hello ";
- $b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Note that the assignment copies the original variable to the new
- one (assignment by value), so changes to one will not affect the
- other. This may also have relevance if you need to copy something
- like a large array inside a tight loop. Since PHP 4, assignment
- by reference has been supported, using the <SAMP
- CLASS="computeroutput"
- >$var =
- &$othervar;</SAMP
- > syntax, but this is not possible
- in PHP 3. 'Assignment by reference' means that both variables end
- up pointing at the same data, and nothing is copied anywhere.
- To learn more about references, please read <A
- HREF="#language.references"
- >References explained</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.bitwise"
- >Bitwise Operators</A
- ></H2
- ><P
- >
Bitwise operators allow you to turn specific bits within an
- integer on or off. If both the left- and right-hand parameters are
- strings, the bitwise operator will operate on the characters' ASCII
- values.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4026"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo 12 ^ 9; // Outputs '5'
-
- echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
- // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
-
- echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
- // 'a' ^ 'e' = #4
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN4028"
- ></A
- ><P
- ><B
- >Table 15-3. Bitwise Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Result</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >$a & $b</TD
- ><TD
- >And</TD
- ><TD
- >Bits that are set in both $a and $b are set.</TD
- ></TR
- ><TR
- ><TD
- >$a | $b</TD
- ><TD
- >Or</TD
- ><TD
- >Bits that are set in either $a or $b are set.</TD
- ></TR
- ><TR
- ><TD
- >$a ^ $b</TD
- ><TD
- >Xor</TD
- ><TD
- >
Bits that are set in $a or $b but not both are set.
- </TD
- ></TR
- ><TR
- ><TD
- >~ $a</TD
- ><TD
- >Not</TD
- ><TD
- >
Bits that are set in $a are not set, and vice versa.
- </TD
- ></TR
- ><TR
- ><TD
- >$a << $b</TD
- ><TD
- >Shift left</TD
- ><TD
- >
Shift the bits of $a $b steps to the left (each step means
- "multiply by two")
- </TD
- ></TR
- ><TR
- ><TD
- >$a >> $b</TD
- ><TD
- >Shift right</TD
- ><TD
- >
Shift the bits of $a $b steps to the right (each step means
- "divide by two")
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Don't right shift for more than 32 bits on 32 bits systems. Don't left shift
- in case it results to number longer than 32 bits.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.comparison"
- >Comparison Operators</A
- ></H2
- ><P
- >
Comparison operators, as their name implies, allow you to compare
- two values. You may also be interested in viewing
- <A
- HREF="#types.comparisons"
- >the type comparison tables</A
- >,
- as they show examples of various type related comparisons.
- </P
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN4067"
- ></A
- ><P
- ><B
- >Table 15-4. Comparison Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Result</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >$a == $b</TD
- ><TD
- >Equal</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a === $b</TD
- ><TD
- >Identical</TD
- ><TD
- >
<TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is equal to $b, and they are of the same
- type. (introduced in PHP 4)
- </TD
- ></TR
- ><TR
- ><TD
- >$a != $b</TD
- ><TD
- >Not equal</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a <> $b</TD
- ><TD
- >Not equal</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a !== $b</TD
- ><TD
- >Not identical</TD
- ><TD
- >
<TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not equal to $b, or they are not of the same
- type. (introduced in PHP 4)
- </TD
- ></TR
- ><TR
- ><TD
- >$a < $b</TD
- ><TD
- >Less than</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is strictly less than $b.</TD
- ></TR
- ><TR
- ><TD
- >$a > $b</TD
- ><TD
- >Greater than</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is strictly greater than $b.</TD
- ></TR
- ><TR
- ><TD
- >$a <= $b</TD
- ><TD
- >Less than or equal to </TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is less than or equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a >= $b</TD
- ><TD
- >Greater than or equal to </TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is greater than or equal to $b.</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
If you compare an integer with a string, the string is
- <A
- HREF="#language.types.string.conversion"
- >converted to a number</A
- >.
- If you compare two numerical strings, they are compared as integers. These
- rules also apply to the
- <A
- HREF="#control-structures.switch"
- >switch</A
- > statement.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4124"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- var_dump(0 == "a"); // 0 == 0 -> true
- var_dump("1" == "01"); // 1 == 1 -> true
-
- switch ("a") {
- case 0:
- echo "0";
- break;
- case "a": // never reached because "a" is already matched with 0
- echo "a";
- break;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Another conditional operator is the "?:" (or ternary) operator.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4127"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Example usage for: Ternary Operator
- $action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
-
- // The above is identical to this if/else statement
- if (empty($_POST['action'])) {
- $action = 'default';
- } else {
- $action = $_POST['action'];
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- The expression <VAR
- CLASS="literal"
- >(expr1) ? (expr2) : (expr3)</VAR
- >
- evaluates to <VAR
- CLASS="replaceable"
- >expr2</VAR
- > if
- <VAR
- CLASS="replaceable"
- >expr1</VAR
- > evaluates to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, and
- <VAR
- CLASS="replaceable"
- >expr3</VAR
- > if
- <VAR
- CLASS="replaceable"
- >expr1</VAR
- > evaluates to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
- </P
- ><P
- >
See also <A
- HREF="#function.strcasecmp"
- ><B
- CLASS="function"
- >strcasecmp()</B
- ></A
- >,
- <A
- HREF="#function.strcmp"
- ><B
- CLASS="function"
- >strcmp()</B
- ></A
- >,
- <A
- HREF="#language.operators.array"
- >Array operators</A
- >,
- and the manual section on
- <A
- HREF="#language.types"
- >Types</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.errorcontrol"
- >Error Control Operators</A
- ></H2
- ><P
- >
PHP supports one error control operator: the at sign (@). When
- prepended to an expression in PHP, any error messages that might
- be generated by that expression will be ignored.
- </P
- ><P
- >
If the <A
- HREF="#ini.track-errors"
- ><VAR
- CLASS="option"
- >track_errors</VAR
- ></A
- >
- feature is enabled, any error message generated by the expression
- will be saved in the variable
- <A
- HREF="#reserved.variables.phperrormsg"
- >$php_errormsg</A
- >.
- This variable will be overwritten on each error, so check early if you
- want to use it.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4149"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /* Intentional file error */
- $my_file = @file ('non_existent_file') or
- die ("Failed opening file: error was '$php_errormsg'");
-
- // this works for any expression, not just functions:
- $value = @$cache[$key];
- // will not issue a notice if the index $key doesn't exist.
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The @-operator works only on
- <A
- HREF="#language.expressions"
- >expressions</A
- >. A simple rule
- of thumb is: if you can take the value of something, you can prepend
- the @ operator to it. For instance, you can prepend it to variables,
- function and <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > calls, constants, and
- so forth. You cannot prepend it to function or class definitions,
- or conditional structures such as <VAR
- CLASS="literal"
- >if</VAR
- > and
- <VAR
- CLASS="literal"
- >foreach</VAR
- >, and so forth.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.error-reporting"
- ><B
- CLASS="function"
- >error_reporting()</B
- ></A
- > and the manual section for
- <A
- HREF="#ref.errorfunc"
- >Error Handling and Logging functions</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The "@" error-control operator prefix will not disable messages
- that are the result of parse errors.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Currently the "@" error-control operator prefix will even disable
- error reporting for critical errors that will terminate script
- execution. Among other things, this means that if you use "@" to
- suppress errors from a certain function and either it isn't
- available or has been mistyped, the script will die right there
- with no indication as to why.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.execution"
- >Execution Operators</A
- ></H2
- ><P
- >
PHP supports one execution operator: backticks (``). Note that
- these are not single-quotes! PHP will attempt to execute the
- contents of the backticks as a shell command; the output will be
- returned (i.e., it won't simply be dumped to output; it can be
- assigned to a variable). Use of the backtick operator is identical
- to <A
- HREF="#function.shell-exec"
- ><B
- CLASS="function"
- >shell_exec()</B
- ></A
- >.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4168"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $output = `ls -al`;
- echo "<pre>$output</pre>";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The backtick operator is disabled when <A
- HREF="#ini.safe-mode"
- >safe mode</A
- > is enabled
- or <A
- HREF="#function.shell-exec"
- ><B
- CLASS="function"
- >shell_exec()</B
- ></A
- > is disabled.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also the manual section on <A
- HREF="#ref.exec"
- >Program
- Execution functions</A
- >, <A
- HREF="#function.popen"
- ><B
- CLASS="function"
- >popen()</B
- ></A
- >
- <A
- HREF="#function.proc-open"
- ><B
- CLASS="function"
- >proc_open()</B
- ></A
- >, and
- <A
- HREF="#features.commandline"
- >Using PHP from the
- commandline</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.increment"
- >Incrementing/Decrementing Operators</A
- ></H2
- ><P
- >
PHP supports C-style pre- and post-increment and decrement
- operators.
- </P
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN4182"
- ></A
- ><P
- ><B
- >Table 15-5. Increment/decrement Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Effect</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >++$a</TD
- ><TD
- >Pre-increment</TD
- ><TD
- >Increments $a by one, then returns $a.</TD
- ></TR
- ><TR
- ><TD
- >$a++</TD
- ><TD
- >Post-increment</TD
- ><TD
- >Returns $a, then increments $a by one.</TD
- ></TR
- ><TR
- ><TD
- >--$a</TD
- ><TD
- >Pre-decrement</TD
- ><TD
- >Decrements $a by one, then returns $a.</TD
- ></TR
- ><TR
- ><TD
- >$a--</TD
- ><TD
- >Post-decrement</TD
- ><TD
- >Returns $a, then decrements $a by one.</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
Here's a simple example script:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4208"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- echo "<h3>Postincrement</h3>";
- $a = 5;
- echo "Should be 5: " . $a++ . "<br />\n";
- echo "Should be 6: " . $a . "<br />\n";
-
- echo "<h3>Preincrement</h3>";
- $a = 5;
- echo "Should be 6: " . ++$a . "<br />\n";
- echo "Should be 6: " . $a . "<br />\n";
-
- echo "<h3>Postdecrement</h3>";
- $a = 5;
- echo "Should be 5: " . $a-- . "<br />\n";
- echo "Should be 4: " . $a . "<br />\n";
-
- echo "<h3>Predecrement</h3>";
- $a = 5;
- echo "Should be 4: " . --$a . "<br />\n";
- echo "Should be 4: " . $a . "<br />\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
PHP follows Perl's convention when dealing with arithmetic operations
- on character variables and not C's. For example, in Perl 'Z'+1 turns
- into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ).
- Note that character variables can be incremented but not decremented.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4211"
- ></A
- ><P
- ><B
- >Example 15-2. Arithmetic Operations on Character Variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $i = 'W';
- for($n=0; $n<6; $n++)
- echo ++$i . "\n";
-
- /*
- Produces the output similar to the following:
-
- X
- Y
- Z
- AA
- AB
- AC
-
- */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Incrementing or decrementing booleans has no effect.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.logical"
- >Logical Operators</A
- ></H2
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN4217"
- ></A
- ><P
- ><B
- >Table 15-6. Logical Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Result</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >$a and $b</TD
- ><TD
- >And</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if both $a and $b are <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.</TD
- ></TR
- ><TR
- ><TD
- >$a or $b</TD
- ><TD
- >Or</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if either $a or $b is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.</TD
- ></TR
- ><TR
- ><TD
- >$a xor $b</TD
- ><TD
- >Xor</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if either $a or $b is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, but not both.</TD
- ></TR
- ><TR
- ><TD
- >! $a</TD
- ><TD
- >Not</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.</TD
- ></TR
- ><TR
- ><TD
- >$a && $b</TD
- ><TD
- >And</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if both $a and $b are <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.</TD
- ></TR
- ><TR
- ><TD
- >$a || $b</TD
- ><TD
- >Or</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if either $a or $b is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
The reason for the two different variations of "and" and "or"
- operators is that they operate at different precedences. (See
- <A
- HREF="#language.operators.precedence"
- >Operator
- Precedence</A
- >.)
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.string"
- >String Operators</A
- ></H2
- ><P
- >
There are two <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- > operators. The first is the
- concatenation operator ('.'), which returns the concatenation of its
- right and left arguments. The second is the concatenating assignment
- operator ('.='), which appends the argument on the right side to
- the argument on the left side. Please read <A
- HREF="#language.operators.assignment"
- >Assignment
- Operators</A
- > for more information.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4270"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = "Hello ";
- $b = $a . "World!"; // now $b contains "Hello World!"
-
- $a = "Hello ";
- $a .= "World!"; // now $a contains "Hello World!"
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
See also the manual sections on the
- <A
- HREF="#language.types.string"
- >String type</A
- > and
- <A
- HREF="#ref.strings"
- >String functions</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.array"
- >Array Operators</A
- ></H2
- ><DIV
- CLASS="table"
- ><A
- NAME="AEN4277"
- ></A
- ><P
- ><B
- >Table 15-7. Array Operators</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Example</TH
- ><TH
- >Name</TH
- ><TH
- >Result</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >$a + $b</TD
- ><TD
- >Union</TD
- ><TD
- >Union of $a and $b.</TD
- ></TR
- ><TR
- ><TD
- >$a == $b</TD
- ><TD
- >Equality</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a and $b have the same key/value pairs.</TD
- ></TR
- ><TR
- ><TD
- >$a === $b</TD
- ><TD
- >Identity</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a and $b have the same key/value pairs in the same
- order and of the same types.</TD
- ></TR
- ><TR
- ><TD
- >$a != $b</TD
- ><TD
- >Inequality</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a <> $b</TD
- ><TD
- >Inequality</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not equal to $b.</TD
- ></TR
- ><TR
- ><TD
- >$a !== $b</TD
- ><TD
- >Non-identity</TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if $a is not identical to $b.</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- ><P
- >
The <VAR
- CLASS="literal"
- >+</VAR
- > operator
- appends the right handed array to the left handed, whereas
- duplicated keys are NOT overwritten.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4318"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = array("a" => "apple", "b" => "banana");
- $b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
-
- $c = $a + $b; // Union of $a and $b
- echo "Union of \$a and \$b: \n";
- var_dump($c);
-
- $c = $b + $a; // Union of $b and $a
- echo "Union of \$b and \$a: \n";
- var_dump($c);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- When executed, this script will print the following:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Union of $a and $b:
- array(3) {
- ["a"]=>
- string(5) "apple"
- ["b"]=>
- string(6) "banana"
- ["c"]=>
- string(6) "cherry"
- }
- Union of $b and $a:
- array(3) {
- ["a"]=>
- string(4) "pear"
- ["b"]=>
- string(10) "strawberry"
- ["c"]=>
- string(6) "cherry"
- }</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Elements of arrays are equal for the comparison if they have the
- same key and value.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4323"
- ></A
- ><P
- ><B
- >Example 15-3. Comparing arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = array("apple", "banana");
- $b = array(1 => "banana", "0" => "apple");
-
- var_dump($a == $b); // bool(true)
- var_dump($a === $b); // bool(false)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also the manual sections on the
- <A
- HREF="#language.types.array"
- >Array type</A
- > and
- <A
- HREF="#ref.array"
- >Array functions</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.operators.type"
- >Type Operators</A
- ></H2
- ><P
- >
PHP has a single type operator: <VAR
- CLASS="literal"
- >instanceof</VAR
- >.
- <VAR
- CLASS="literal"
- >instanceof</VAR
- > is used to determine whether a given
- object is of a specified <A
- HREF="#language.oop"
- >object class</A
- >.
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >instanceof</VAR
- > operator was introduced in PHP 5.
- Before this time <A
- HREF="#function.is-a"
- ><B
- CLASS="function"
- >is_a()</B
- ></A
- > was used but
- <A
- HREF="#function.is-a"
- ><B
- CLASS="function"
- >is_a()</B
- ></A
- > has since been deprecated in favor of
- <VAR
- CLASS="literal"
- >instanceof</VAR
- >.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4340"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><?php
- class A { }
- class B { }
-
- $thing = new A;
-
- if ($thing instanceof A) {
- echo 'A';
- }
- if ($thing instanceof B) {
- echo 'B';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
As <VAR
- CLASS="varname"
- >$thing</VAR
- > is an <A
- HREF="#language.types.object"
- ><B
- CLASS="type"
- >object</B
- ></A
- > of type A, but
- not B, only the block dependent on the A type will be executed:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >A</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
See also <A
- HREF="#function.get-class"
- ><B
- CLASS="function"
- >get_class()</B
- ></A
- > and
- <A
- HREF="#function.is-a"
- ><B
- CLASS="function"
- >is_a()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.control-structures"
- >Chapter 16. Control Structures</A
- ></H1
- ><P
- >
Any PHP script is built out of a series of statements. A statement
- can be an assignment, a function call, a loop, a conditional
- statement of even a statement that does nothing (an empty
- statement). Statements usually end with a semicolon. In addition,
- statements can be grouped into a statement-group by encapsulating a
- group of statements with curly braces. A statement-group is a
- statement by itself as well. The various statement types are
- described in this chapter.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.if"
- ><VAR
- CLASS="literal"
- >if</VAR
- ></A
- ></H2
- ><P
- >
The <VAR
- CLASS="literal"
- >if</VAR
- > construct is one of the most important
- features of many languages, PHP included. It allows for
- conditional execution of code fragments. PHP features an
- <VAR
- CLASS="literal"
- >if</VAR
- > structure that is similar to that of C:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4358"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- ><?php
- if (expression)
- statement
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
As described in <A
- HREF="#language.expressions"
- >the section about
- expressions</A
- >, <VAR
- CLASS="replaceable"
- >expr</VAR
- > is evaluated to its
- Boolean value. If <VAR
- CLASS="replaceable"
- >expr</VAR
- > evaluates to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >,
- PHP will execute <VAR
- CLASS="replaceable"
- >statement</VAR
- >, and if it evaluates
- to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > - it'll ignore it. More information about what values evaluate
- to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > can be found in the <A
- HREF="#language.types.boolean.casting"
- >'Converting to boolean'</A
- >
- section.
- </P
- ><P
- >
The following example would display <SAMP
- CLASS="computeroutput"
- >a is bigger
- than b</SAMP
- > if <VAR
- CLASS="varname"
- >$a</VAR
- > is bigger
- than <VAR
- CLASS="varname"
- >$b</VAR
- >:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4373"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($a > $b)
- echo "a is bigger than b";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Often you'd want to have more than one statement to be executed
- conditionally. Of course, there's no need to wrap each statement
- with an <VAR
- CLASS="literal"
- >if</VAR
- > clause. Instead, you can group
- several statements into a statement group. For example, this code
- would display <SAMP
- CLASS="computeroutput"
- >a is bigger than b</SAMP
- >
- if <VAR
- CLASS="varname"
- >$a</VAR
- > is bigger than
- <VAR
- CLASS="varname"
- >$b</VAR
- >, and would then assign the value of
- <VAR
- CLASS="varname"
- >$a</VAR
- > into <VAR
- CLASS="varname"
- >$b</VAR
- >:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4382"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($a > $b) {
- echo "a is bigger than b";
- $b = $a;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
<VAR
- CLASS="literal"
- >If</VAR
- > statements can be nested indefinitely within other
- <VAR
- CLASS="literal"
- >if</VAR
- > statements, which provides you with complete
- flexibility for conditional execution of the various parts of your
- program.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.else"
- ><VAR
- CLASS="literal"
- >else</VAR
- ></A
- ></H2
- ><P
- >
Often you'd want to execute a statement if a certain condition is
- met, and a different statement if the condition is not met. This
- is what <VAR
- CLASS="literal"
- >else</VAR
- > is for. <VAR
- CLASS="literal"
- >else</VAR
- >
- extends an <VAR
- CLASS="literal"
- >if</VAR
- > statement to execute a statement
- in case the expression in the <VAR
- CLASS="literal"
- >if</VAR
- > statement
- evaluates to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >. For example, the following
- code would display <SAMP
- CLASS="computeroutput"
- >a is bigger than
- b</SAMP
- > if <VAR
- CLASS="varname"
- >$a</VAR
- > is bigger than
- <VAR
- CLASS="varname"
- >$b</VAR
- >, and <SAMP
- CLASS="computeroutput"
- >a is NOT bigger
- than b</SAMP
- > otherwise:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4400"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($a > $b) {
- echo "a is bigger than b";
- } else {
- echo "a is NOT bigger than b";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
-
- The <VAR
- CLASS="literal"
- >else</VAR
- > statement is only executed if the
- <VAR
- CLASS="literal"
- >if</VAR
- > expression evaluated to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, and if there were any
- <VAR
- CLASS="literal"
- >elseif</VAR
- > expressions - only if they evaluated to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > as well (see <A
- HREF="#control-structures.elseif"
- >elseif</A
- >).
-
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.elseif"
- ><VAR
- CLASS="literal"
- >elseif</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >elseif</VAR
- >, as its name suggests, is a combination
- of <VAR
- CLASS="literal"
- >if</VAR
- > and <VAR
- CLASS="literal"
- >else</VAR
- >. Like
- <VAR
- CLASS="literal"
- >else</VAR
- >, it extends an <VAR
- CLASS="literal"
- >if</VAR
- >
- statement to execute a different statement in case the original
- <VAR
- CLASS="literal"
- >if</VAR
- > expression evaluates to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >. However, unlike
- <VAR
- CLASS="literal"
- >else</VAR
- >, it will execute that alternative
- expression only if the <VAR
- CLASS="literal"
- >elseif</VAR
- > conditional
- expression evaluates to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >. For example, the
- following code would display <SAMP
- CLASS="computeroutput"
- >a is bigger than
- b</SAMP
- >, <SAMP
- CLASS="computeroutput"
- >a equal to b</SAMP
- >
- or <SAMP
- CLASS="computeroutput"
- >a is smaller than b</SAMP
- >:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4425"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($a > $b) {
- echo "a is bigger than b";
- } elseif ($a == $b) {
- echo "a is equal to b";
- } else {
- echo "a is smaller than b";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
There may be several <VAR
- CLASS="literal"
- >elseif</VAR
- >s within the same
- <VAR
- CLASS="literal"
- >if</VAR
- > statement. The first
- <VAR
- CLASS="literal"
- >elseif</VAR
- > expression (if any) that evaluates to
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > would be executed. In PHP, you can also
- write 'else if' (in two words) and the behavior would be identical
- to the one of 'elseif' (in a single word). The syntactic meaning
- is slightly different (if you're familiar with C, this is the same
- behavior) but the bottom line is that both would result in exactly
- the same behavior.
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >elseif</VAR
- > statement is only executed if the
- preceding <VAR
- CLASS="literal"
- >if</VAR
- > expression and any preceding
- <VAR
- CLASS="literal"
- >elseif</VAR
- > expressions evaluated to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, and the current
- <VAR
- CLASS="literal"
- >elseif</VAR
- > expression evaluated to
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.alternative-syntax"
- >Alternative syntax for control structures</A
- ></H2
- ><P
- >
PHP offers an alternative syntax for some of its control
- structures; namely, <VAR
- CLASS="literal"
- >if</VAR
- >,
- <VAR
- CLASS="literal"
- >while</VAR
- >, <VAR
- CLASS="literal"
- >for</VAR
- >,
- <VAR
- CLASS="literal"
- >foreach</VAR
- >, and <VAR
- CLASS="literal"
- >switch</VAR
- >.
- In each case, the basic form of the alternate syntax is to change
- the opening brace to a colon (:) and the closing brace to
- <VAR
- CLASS="literal"
- >endif;</VAR
- >, <VAR
- CLASS="literal"
- >endwhile;</VAR
- >,
- <VAR
- CLASS="literal"
- >endfor;</VAR
- >, <VAR
- CLASS="literal"
- >endforeach;</VAR
- >, or
- <VAR
- CLASS="literal"
- >endswitch;</VAR
- >, respectively.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4452"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php if ($a == 5): ?>
- A is equal to 5
- <?php endif; ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
In the above example, the HTML block "A is equal to 5" is nested within an
- <VAR
- CLASS="literal"
- >if</VAR
- > statement written in the alternative syntax. The
- HTML block would be displayed only if <VAR
- CLASS="varname"
- >$a</VAR
- > is equal to 5.
- </P
- ><P
- >
The alternative syntax applies to <VAR
- CLASS="literal"
- >else</VAR
- > and
- <VAR
- CLASS="literal"
- >elseif</VAR
- > as well. The following is an
- <VAR
- CLASS="literal"
- >if</VAR
- > structure with <VAR
- CLASS="literal"
- >elseif</VAR
- > and
- <VAR
- CLASS="literal"
- >else</VAR
- > in the alternative format:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4463"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($a == 5):
- echo "a equals 5";
- echo "...";
- elseif ($a == 6):
- echo "a equals 6";
- echo "!!!";
- else:
- echo "a is neither 5 nor 6";
- endif;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
See also <A
- HREF="#control-structures.while"
- >while</A
- >,
- <A
- HREF="#control-structures.for"
- >for</A
- >, and <A
- HREF="#control-structures.if"
- >if</A
- > for further examples.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.while"
- ><VAR
- CLASS="literal"
- >while</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >while</VAR
- > loops are the simplest type of loop in
- PHP. They behave just like their C counterparts. The basic form
- of a <VAR
- CLASS="literal"
- >while</VAR
- > statement is:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4475"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >while (expr)
- statement</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The meaning of a <VAR
- CLASS="literal"
- >while</VAR
- > statement is simple. It
- tells PHP to execute the nested statement(s) repeatedly, as long
- as the <VAR
- CLASS="literal"
- >while</VAR
- > expression evaluates to
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >. The value of the expression is checked
- each time at the beginning of the loop, so even if this value
- changes during the execution of the nested statement(s), execution
- will not stop until the end of the iteration (each time PHP runs
- the statements in the loop is one iteration). Sometimes, if the
- <VAR
- CLASS="literal"
- >while</VAR
- > expression evaluates to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > from the very beginning, the nested
- statement(s) won't even be run once.
- </P
- ><P
- >
Like with the <VAR
- CLASS="literal"
- >if</VAR
- > statement, you can group
- multiple statements within the same <VAR
- CLASS="literal"
- >while</VAR
- > loop
- by surrounding a group of statements with curly braces, or by
- using the alternate syntax:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4486"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >while (expr):
- statement
- ...
- endwhile;</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The following examples are identical, and both print numbers from
- 1 to 10:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4489"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /* example 1 */
-
- $i = 1;
- while ($i <= 10) {
- echo $i++; /* the printed value would be
- $i before the increment
- (post-increment) */
- }
-
- /* example 2 */
-
- $i = 1;
- while ($i <= 10):
- echo $i;
- $i++;
- endwhile;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.do.while"
- ><VAR
- CLASS="literal"
- >do-while</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >do-while</VAR
- > loops are very similar to
- <VAR
- CLASS="literal"
- >while</VAR
- > loops, except the truth expression is
- checked at the end of each iteration instead of in the beginning.
- The main difference from regular <VAR
- CLASS="literal"
- >while</VAR
- > loops is
- that the first iteration of a <VAR
- CLASS="literal"
- >do-while</VAR
- > loop is
- guaranteed to run (the truth expression is only checked at the end
- of the iteration), whereas it's may not necessarily run with a
- regular <VAR
- CLASS="literal"
- >while</VAR
- > loop (the truth expression is
- checked at the beginning of each iteration, if it evaluates to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > right from the beginning, the loop
- execution would end immediately).
- </P
- ><P
- >
There is just one syntax for <VAR
- CLASS="literal"
- >do-while</VAR
- > loops:
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4503"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $i = 0;
- do {
- echo $i;
- } while ($i > 0);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The above loop would run one time exactly, since after the first
- iteration, when truth expression is checked, it evaluates to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > ($i is not bigger than 0) and the loop
- execution ends.
- </P
- ><P
- >
Advanced C users may be familiar with a different usage of the
- <VAR
- CLASS="literal"
- >do-while</VAR
- > loop, to allow stopping execution in
- the middle of code blocks, by encapsulating them with
- <VAR
- CLASS="literal"
- >do-while</VAR
- > (0), and using the <A
- HREF="#control-structures.break"
- ><VAR
- CLASS="literal"
- >break</VAR
- ></A
- >
- statement. The following code fragment demonstrates this:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4512"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- do {
- if ($i < 5) {
- echo "i is not big enough";
- break;
- }
- $i *= $factor;
- if ($i < $minimum_limit) {
- break;
- }
- echo "i is ok";
-
- /* process i */
-
- } while (0);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Don't worry if you don't understand this right away or at all.
- You can code scripts and even powerful scripts without using this
- 'feature'.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.for"
- ><VAR
- CLASS="literal"
- >for</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >for</VAR
- > loops are the most complex loops in PHP.
- They behave like their C counterparts. The syntax of a
- <VAR
- CLASS="literal"
- >for</VAR
- > loop is:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4521"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >for (expr1; expr2; expr3)
- statement</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The first expression (<VAR
- CLASS="varname"
- >expr1</VAR
- >) is
- evaluated (executed) once unconditionally at the beginning of the
- loop.
- </P
- ><P
- >
In the beginning of each iteration,
- <VAR
- CLASS="varname"
- >expr2</VAR
- > is evaluated. If it evaluates to
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, the loop continues and the nested
- statement(s) are executed. If it evaluates to
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, the execution of the loop ends.
- </P
- ><P
- >
At the end of each iteration, <VAR
- CLASS="varname"
- >expr3</VAR
- > is
- evaluated (executed).
- </P
- ><P
- >
Each of the expressions can be empty.
- <VAR
- CLASS="varname"
- >expr2</VAR
- > being empty means the loop should
- be run indefinitely (PHP implicitly considers it as
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, like C). This may not be as useless as
- you might think, since often you'd want to end the loop using a
- conditional <A
- HREF="#control-structures.break"
- ><VAR
- CLASS="literal"
- >break</VAR
- ></A
- >
- statement instead of using the <VAR
- CLASS="literal"
- >for</VAR
- > truth
- expression.
- </P
- ><P
- >
Consider the following examples. All of them display numbers from
- 1 to 10:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4538"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /* example 1 */
-
- for ($i = 1; $i <= 10; $i++) {
- echo $i;
- }
-
- /* example 2 */
-
- for ($i = 1; ; $i++) {
- if ($i > 10) {
- break;
- }
- echo $i;
- }
-
- /* example 3 */
-
- $i = 1;
- for (; ; ) {
- if ($i > 10) {
- break;
- }
- echo $i;
- $i++;
- }
-
- /* example 4 */
-
- for ($i = 1; $i <= 10; print $i, $i++);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Of course, the first example appears to be the nicest one (or
- perhaps the fourth), but you may find that being able to use empty
- expressions in <VAR
- CLASS="literal"
- >for</VAR
- > loops comes in handy in many
- occasions.
- </P
- ><P
- >
PHP also supports the alternate "colon syntax" for
- <VAR
- CLASS="literal"
- >for</VAR
- > loops.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4544"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >for (expr1; expr2; expr3):
- statement
- ...
- endfor;</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.foreach"
- ><VAR
- CLASS="literal"
- >foreach</VAR
- ></A
- ></H2
- ><P
- >
PHP 4 introduced a <VAR
- CLASS="literal"
- >foreach</VAR
- > construct, much
- like Perl and some other languages. This simply gives an easy way to
- iterate over arrays. <VAR
- CLASS="literal"
- >foreach</VAR
- > works only on arrays, and
- will issue an error when you try to use it on a variable with a different
- data type or an uninitialized variable. There are two syntaxes; the
- second is a minor but useful extension of the first:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4552"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >foreach (array_expression as $value)
- statement
- foreach (array_expression as $key => $value)
- statement</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The first form loops over the array given by
- <VAR
- CLASS="literal"
- >array_expression</VAR
- >. On each loop, the value of
- the current element is assigned to <VAR
- CLASS="literal"
- >$value</VAR
- > and
- the internal array pointer is advanced by one (so on the next
- loop, you'll be looking at the next element).
- </P
- ><P
- >
The second form does the same thing, except that the current
- element's key will be assigned to the variable
- <VAR
- CLASS="literal"
- >$key</VAR
- > on each loop.
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- When <VAR
- CLASS="literal"
- >foreach</VAR
- > first starts executing, the
- internal array pointer is automatically reset to the first element
- of the array. This means that you do not need to call
- <A
- HREF="#function.reset"
- ><B
- CLASS="function"
- >reset()</B
- ></A
- > before a <VAR
- CLASS="literal"
- >foreach</VAR
- >
- loop.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Also note that <VAR
- CLASS="literal"
- >foreach</VAR
- > operates on a copy of
- the specified array and not the array itself. Therefore, the
- array pointer is not modified as with the
- <A
- HREF="#function.each"
- ><B
- CLASS="function"
- >each()</B
- ></A
- > construct, and changes to the array
- element returned are not reflected in the original array.
- However, the internal pointer of the original array
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >is</I
- ></SPAN
- > advanced with the processing of the
- array. Assuming the foreach loop runs to completion, the
- array's internal pointer will be at the end of the array.
- </P
- ><P
- >
As of PHP 5, you can easily modify array's elements by preceding
- <VAR
- CLASS="literal"
- >$value</VAR
- > with &. This will assign
- <A
- HREF="#language.references"
- >reference</A
- > instead of copying
- the value.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4574"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $arr = array(1, 2, 3, 4);
- foreach ($arr as &$value) {
- $value = $value * 2;
- }
- // $arr is now array(2, 4, 6, 8)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- This is possible only if iterated array can be referenced (i.e. is
- variable).
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <VAR
- CLASS="literal"
- >foreach</VAR
- > does not support the ability to
- suppress error messages using '@'.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
You may have noticed that the following are functionally
- identical:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4581"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $arr = array("one", "two", "three");
- reset($arr);
- while (list(, $value) = each($arr)) {
- echo "Value: $value<br />\n";
- }
-
- foreach ($arr as $value) {
- echo "Value: $value<br />\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- The following are also functionally identical:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4583"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $arr = array("one", "two", "three");
- reset($arr);
- while (list($key, $value) = each($arr)) {
- echo "Key: $key; Value: $value<br />\n";
- }
-
- foreach ($arr as $key => $value) {
- echo "Key: $key; Value: $value<br />\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Some more examples to demonstrate usages:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4586"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /* foreach example 1: value only */
-
- $a = array(1, 2, 3, 17);
-
- foreach ($a as $v) {
- echo "Current value of \$a: $v.\n";
- }
-
- /* foreach example 2: value (with key printed for illustration) */
-
- $a = array(1, 2, 3, 17);
-
- $i = 0; /* for illustrative purposes only */
-
- foreach ($a as $v) {
- echo "\$a[$i] => $v.\n";
- $i++;
- }
-
- /* foreach example 3: key and value */
-
- $a = array(
- "one" => 1,
- "two" => 2,
- "three" => 3,
- "seventeen" => 17
- );
-
- foreach ($a as $k => $v) {
- echo "\$a[$k] => $v.\n";
- }
-
- /* foreach example 4: multi-dimensional arrays */
- $a = array();
- $a[0][0] = "a";
- $a[0][1] = "b";
- $a[1][0] = "y";
- $a[1][1] = "z";
-
- foreach ($a as $v1) {
- foreach ($v1 as $v2) {
- echo "$v2\n";
- }
- }
-
- /* foreach example 5: dynamic arrays */
-
- foreach (array(1, 2, 3, 4, 5) as $v) {
- echo "$v\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.break"
- ><VAR
- CLASS="literal"
- >break</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >break</VAR
- > ends execution of the current
- <VAR
- CLASS="literal"
- >for</VAR
- >, <VAR
- CLASS="literal"
- >foreach</VAR
- >,
- <VAR
- CLASS="literal"
- >while</VAR
- >, <VAR
- CLASS="literal"
- >do-while</VAR
- > or
- <VAR
- CLASS="literal"
- >switch</VAR
- > structure.
- </P
- ><P
- >
<VAR
- CLASS="literal"
- >break</VAR
- > accepts an optional numeric argument
- which tells it how many nested enclosing structures are to be
- broken out of.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4601"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $arr = array('one', 'two', 'three', 'four', 'stop', 'five');
- while (list(, $val) = each($arr)) {
- if ($val == 'stop') {
- break; /* You could also write 'break 1;' here. */
- }
- echo "$val<br />\n";
- }
-
- /* Using the optional argument. */
-
- $i = 0;
- while (++$i) {
- switch ($i) {
- case 5:
- echo "At 5<br />\n";
- break 1; /* Exit only the switch. */
- case 10:
- echo "At 10; quitting<br />\n";
- break 2; /* Exit the switch and the while. */
- default:
- break;
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.continue"
- ><VAR
- CLASS="literal"
- >continue</VAR
- ></A
- ></H2
- ><P
- >
<VAR
- CLASS="literal"
- >continue</VAR
- > is used within looping structures to
- skip the rest of the current loop iteration and continue execution
- at the beginning of the next iteration.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Note that in PHP the
- <A
- HREF="#control-structures.switch"
- >switch</A
- > statement is
- considered a looping structure for the purposes of
- <VAR
- CLASS="literal"
- >continue</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<VAR
- CLASS="literal"
- >continue</VAR
- > accepts an optional numeric argument
- which tells it how many levels of enclosing loops it should skip
- to the end of.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4615"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- while (list($key, $value) = each($arr)) {
- if (!($key % 2)) { // skip odd members
- continue;
- }
- do_something_odd($value);
- }
-
- $i = 0;
- while ($i++ < 5) {
- echo "Outer<br />\n";
- while (1) {
- echo " Middle<br />\n";
- while (1) {
- echo " Inner<br />\n";
- continue 3;
- }
- echo "This never gets output.<br />\n";
- }
- echo "Neither does this.<br />\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Omitting the semicolon after <VAR
- CLASS="literal"
- >continue</VAR
- > can lead to
- confusion. Here's an example of what you shouldn't do.
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4620"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- for ($i = 0; $i < 5; ++$i) {
- if ($i == 2)
- continue
- print "$i\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
One can expect the result to be :
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >0
- 1
- 3
- 4</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
but this script will output :
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >2</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
because the return value of the <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- >
- call is <VAR
- CLASS="literal"
- >int(1)</VAR
- >, and it will look like the
- optional numeric argument mentioned above.
- </P
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.switch"
- ><VAR
- CLASS="literal"
- >switch</VAR
- ></A
- ></H2
- ><P
- >
The <VAR
- CLASS="literal"
- >switch</VAR
- > statement is similar to a series of
- IF statements on the same expression. In many occasions, you may
- want to compare the same variable (or expression) with many
- different values, and execute a different piece of code depending
- on which value it equals to. This is exactly what the
- <VAR
- CLASS="literal"
- >switch</VAR
- > statement is for.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Note that unlike some other languages, the
- <A
- HREF="#control-structures.continue"
- >continue</A
- > statement
- applies to switch and acts similar to <VAR
- CLASS="literal"
- >break</VAR
- >. If you
- have a switch inside a loop and wish to continue to the next iteration of
- the outer loop, use <VAR
- CLASS="literal"
- >continue 2</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The following two examples are two different ways to write the
- same thing, one using a series of <VAR
- CLASS="literal"
- >if</VAR
- > and
- <VAR
- CLASS="literal"
- >elseif</VAR
- > statements, and the other using the
- <VAR
- CLASS="literal"
- >switch</VAR
- > statement:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4644"
- ></A
- ><P
- ><B
- >Example 16-1. <VAR
- CLASS="literal"
- >switch</VAR
- > structure</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if ($i == 0) {
- echo "i equals 0";
- } elseif ($i == 1) {
- echo "i equals 1";
- } elseif ($i == 2) {
- echo "i equals 2";
- }
-
- switch ($i) {
- case 0:
- echo "i equals 0";
- break;
- case 1:
- echo "i equals 1";
- break;
- case 2:
- echo "i equals 2";
- break;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4648"
- ></A
- ><P
- ><B
- >Example 16-2. <VAR
- CLASS="literal"
- >switch</VAR
- > structure allows usage of strings</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- switch ($i) {
- case "apple":
- echo "i is apple";
- break;
- case "bar":
- echo "i is bar";
- break;
- case "cake":
- echo "i is cake";
- break;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
It is important to understand how the <VAR
- CLASS="literal"
- >switch</VAR
- >
- statement is executed in order to avoid mistakes. The
- <VAR
- CLASS="literal"
- >switch</VAR
- > statement executes line by line
- (actually, statement by statement). In the beginning, no code is
- executed. Only when a <VAR
- CLASS="literal"
- >case</VAR
- > statement is found
- with a value that matches the value of the
- <VAR
- CLASS="literal"
- >switch</VAR
- > expression does PHP begin to execute the
- statements. PHP continues to execute the statements until the end
- of the <VAR
- CLASS="literal"
- >switch</VAR
- > block, or the first time it sees
- a <VAR
- CLASS="literal"
- >break</VAR
- > statement. If you don't write a
- <VAR
- CLASS="literal"
- >break</VAR
- > statement at the end of a case's
- statement list, PHP will go on executing the statements of the
- following case. For example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4660"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- switch ($i) {
- case 0:
- echo "i equals 0";
- case 1:
- echo "i equals 1";
- case 2:
- echo "i equals 2";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Here, if <VAR
- CLASS="varname"
- >$i</VAR
- > is equal to 0, PHP would execute all of the echo
- statements! If <VAR
- CLASS="varname"
- >$i</VAR
- > is equal to 1, PHP would execute the last two
- echo statements. You would get the expected behavior ('i equals 2'
- would be displayed) only if <VAR
- CLASS="varname"
- >$i</VAR
- > is equal to 2. Thus,
- it is important not to forget <VAR
- CLASS="literal"
- >break</VAR
- > statements
- (even though you may want to avoid supplying them on purpose under
- certain circumstances).
- </P
- ><P
- >
In a <VAR
- CLASS="literal"
- >switch</VAR
- > statement, the condition is
- evaluated only once and the result is compared to each
- <VAR
- CLASS="literal"
- >case</VAR
- > statement. In an <VAR
- CLASS="literal"
- >elseif</VAR
- >
- statement, the condition is evaluated again. If your condition is
- more complicated than a simple compare and/or is in a tight loop,
- a <VAR
- CLASS="literal"
- >switch</VAR
- > may be faster.
- </P
- ><P
- >
The statement list for a case can also be empty, which simply
- passes control into the statement list for the next case.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4673"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- switch ($i) {
- case 0:
- case 1:
- case 2:
- echo "i is less than 3 but not negative";
- break;
- case 3:
- echo "i is 3";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
A special case is the <VAR
- CLASS="literal"
- >default</VAR
- > case. This case matches
- anything that wasn't matched by the other cases, and should be the last
- <VAR
- CLASS="literal"
- >case</VAR
- > statement. For example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4678"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- switch ($i) {
- case 0:
- echo "i equals 0";
- break;
- case 1:
- echo "i equals 1";
- break;
- case 2:
- echo "i equals 2";
- break;
- default:
- echo "i is not equal to 0, 1 or 2";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >case</VAR
- > expression may be any expression that
- evaluates to a simple type, that is, integer or floating-point
- numbers and strings. Arrays or objects cannot be used here unless
- they are dereferenced to a simple type.
- </P
- ><P
- >
The alternative syntax for control structures is supported with
- switches. For more information, see <A
- HREF="#control-structures.alternative-syntax"
- >Alternative syntax
- for control structures</A
- > .
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4684"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- switch ($i):
- case 0:
- echo "i equals 0";
- break;
- case 1:
- echo "i equals 1";
- break;
- case 2:
- echo "i equals 2";
- break;
- default:
- echo "i is not equal to 0, 1 or 2";
- endswitch;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="control-structures.declare"
- ><VAR
- CLASS="literal"
- >declare</VAR
- ></A
- ></H2
- ><P
- >
The <VAR
- CLASS="literal"
- >declare</VAR
- > construct is used to
- set execution directives for a block of code.
- The syntax of <VAR
- CLASS="literal"
- >declare</VAR
- > is similar to
- the syntax of other flow control constructs:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4692"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >declare (directive)
- statement</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >directive</VAR
- > section allows the
- behavior of the <VAR
- CLASS="literal"
- >declare</VAR
- > block to
- be set.
- Currently only one directive is recognized: the
- <VAR
- CLASS="literal"
- >ticks</VAR
- > directive. (See below for more
- information on the
- <A
- HREF="#control-structures.declare.ticks"
- >ticks</A
- >
- directive)
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >statement</VAR
- > part of the
- <VAR
- CLASS="literal"
- >declare</VAR
- > block will be executed -- how
- it is executed and what side effects occur during execution
- may depend on the directive set in the
- <VAR
- CLASS="literal"
- >directive</VAR
- > block.
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >declare</VAR
- > construct can also be used in the global
- scope, affecting all code following it.
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN4705"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // these are the same:
-
- // you can use this:
- declare(ticks=1) {
- // entire script here
- }
-
- // or you can use this:
- declare(ticks=1);
- // entire script here
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="control-structures.declare.ticks"
- >Ticks</A
- ></H3
- ><P
- >A tick is an event that occurs for every
- <VAR
- CLASS="varname"
- >N</VAR
- > low-level statements executed
- by the parser within the <VAR
- CLASS="literal"
- >declare</VAR
- > block.
- The value for <VAR
- CLASS="varname"
- >N</VAR
- > is specified
- using <VAR
- CLASS="literal"
- >ticks=<VAR
- CLASS="varname"
- >N</VAR
- ></VAR
- >
- within the <VAR
- CLASS="literal"
- >declare</VAR
- > blocks's
- <VAR
- CLASS="literal"
- >directive</VAR
- > section.
- </P
- ><P
- >
The event(s) that occur on each tick are specified using the
- <A
- HREF="#function.register-tick-function"
- ><B
- CLASS="function"
- >register_tick_function()</B
- ></A
- >. See the example
- below for more details. Note that more than one event can occur
- for each tick.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4720"
- ></A
- ><P
- ><B
- >Example 16-3. Profile a section of PHP code</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // A function that records the time when it is called
- function profile($dump = FALSE)
- {
- static $profile;
-
- // Return the times stored in profile, then erase it
- if ($dump) {
- $temp = $profile;
- unset($profile);
- return($temp);
- }
-
- $profile[] = microtime();
- }
-
- // Set up a tick handler
- register_tick_function("profile");
-
- // Initialize the function before the declare block
- profile();
-
- // Run a block of code, throw a tick every 2nd statement
- declare(ticks=2) {
- for ($x = 1; $x < 50; ++$x) {
- echo similar_text(md5($x), md5($x*$x)), "<br />;";
- }
- }
-
- // Display the data stored in the profiler
- print_r(profile(TRUE));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- The example profiles the PHP code within the 'declare'
- block, recording the time at which every second low-level
- statement in the block was executed. This information can
- then be used to find the slow areas within particular
- segments of code. This process can be performed using other
- methods: using ticks is more convenient and easier to
- implement.
- </P
- ><P
- >
Ticks are well suited for debugging, implementing simple
- multitasking, background I/O and many other tasks.
- </P
- ><P
- >
See also <A
- HREF="#function.register-tick-function"
- ><B
- CLASS="function"
- >register_tick_function()</B
- ></A
- > and
- <A
- HREF="#function.unregister-tick-function"
- ><B
- CLASS="function"
- >unregister_tick_function()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="function.return"
- >return</A
- ></H2
- ><P
- >
If called from within a function, the <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- >
- statement immediately ends execution of the current function, and
- returns its argument as the value of the function
- call. <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > will also end the execution of
- an <A
- HREF="#function.eval"
- ><B
- CLASS="function"
- >eval()</B
- ></A
- > statement or script file.
- </P
- ><P
- >
If called from the global scope, then execution of the current
- script file is ended. If the current script file was
- <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >ed or <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >ed,
- then control is passed back to the calling file. Furthermore, if
- the current script file was <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >ed, then
- the value given to <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > will be returned as
- the value of the <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > call. If
- <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > is called from within the main script
- file, then script execution ends. If the current script file was
- named by the <A
- HREF="#ini.auto-prepend-file"
- >auto_prepend_file</A
- > or <A
- HREF="#ini.auto-append-file"
- >auto_append_file</A
- >
- configuration options in <TT
- CLASS="filename"
- >php.ini</TT
- >,
- then that script file's execution is ended.
- </P
- ><P
- >For more information, see <A
- HREF="#functions.returning-values"
- >Returning values</A
- >.
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Note that since <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > is a language
- construct and not a function, the parentheses surrounding its
- arguments are <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >only</I
- ></SPAN
- > required if the argument
- contains an expression. It is common to leave them out while returning a variable.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="function.require"
- ><A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- ></A
- ></H2
- ><P
- >
The <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > statement includes and evaluates
- the specific file.
- </P
- ><P
- >
<A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > includes and evaluates a specific file.
- Detailed information on how this inclusion works is described in the
- documentation for <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >.
- </P
- ><P
- >
<A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > and <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >
- are identical in every way except how they handle failure.
- <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > produces a
- <A
- HREF="#internal.e-warning"
- >Warning</A
- > while
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > results in a <A
- HREF="#internal.e-error"
- >
Fatal Error</A
- >. In other words, don't hesitate to use
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > if you want a missing file to halt processing
- of the page. <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > does not behave this way, the
- script will continue regardless. Be sure to have an appropriate
- <A
- HREF="#ini.include-path"
- >include_path</A
- > setting as well.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4769"
- ></A
- ><P
- ><B
- >Example 16-4. Basic <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > examples</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- require 'prepend.php';
-
- require $somefile;
-
- require ('somefile.txt');
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See the <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > documentation for more examples.
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Prior to PHP 4.0.2, the following applies: <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >
- will always attempt to read the target file, even if the line it's on
- never executes. The conditional statement won't affect
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >. However, if the line on which the
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > occurs is not executed, neither will any of
- the code in the target file be executed. Similarly, looping structures
- do not affect the behaviour of <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >. Although
- the code contained in the target file is still subject to the loop, the
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > itself happens only once.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >Because this is a
- language construct and not a function, it cannot be called using
- <A
- HREF="#functions.variable-functions"
- >variable functions</A
- ></P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >Windows versions of PHP
- prior to PHP 4.3.0 do not support accessing remote files via this function, even if
- <A
- HREF="#ini.allow-url-fopen"
- >allow_url_fopen</A
- > is enabled.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >, <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- >,
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >, <A
- HREF="#function.eval"
- ><B
- CLASS="function"
- >eval()</B
- ></A
- >,
- <A
- HREF="#function.file"
- ><B
- CLASS="function"
- >file()</B
- ></A
- >, <A
- HREF="#function.readfile"
- ><B
- CLASS="function"
- >readfile()</B
- ></A
- >,
- <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- > and <A
- HREF="#ini.include-path"
- >include_path</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="function.include"
- ><A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- ></A
- ></H2
- ><P
- >
The <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > statement includes and evaluates
- the specified file.
- </P
- ><P
- >
The documentation below also applies to <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >.
- The two constructs are identical in every way except how they handle
- failure. <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > produces a
- <A
- HREF="#internal.e-warning"
- >Warning</A
- > while <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >
- results in a <A
- HREF="#internal.e-error"
- >Fatal Error</A
- >.
- In other words, use <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > if you want
- a missing file to halt processing of the page. <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > does
- not behave this way, the script will continue regardless. Be sure to have an
- appropriate <A
- HREF="#ini.include-path"
- >include_path</A
- > setting as well.
- Be warned that parse error in required file doesn't cause processing halting.
- </P
- ><P
- >
Files for including are first looked in include_path relative to the current working directory
- and then in include_path relative to the directory of current script. E.g. if your include_path
- is <VAR
- CLASS="literal"
- >.</VAR
- >, current working directory is <TT
- CLASS="filename"
- >/www/</TT
- >,
- you included <TT
- CLASS="filename"
- >include/a.php</TT
- > and there is <VAR
- CLASS="literal"
- >include "b.php"</VAR
- >
- in that file, <TT
- CLASS="filename"
- >b.php</TT
- > is first looked in <TT
- CLASS="filename"
- >/www/</TT
- >
- and then in <TT
- CLASS="filename"
- >/www/include/</TT
- >.
- If filename begins with <VAR
- CLASS="literal"
- >../</VAR
- >, it is looked only in
- include_path relative to the current working directory.
- </P
- ><P
- >
When a file is included, the code it contains inherits the
- <A
- HREF="#language.variables.scope"
- >variable scope</A
- > of the
- line on which the include occurs. Any variables available at that line
- in the calling file will be available within the called file, from that
- point forward.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4824"
- ></A
- ><P
- ><B
- >Example 16-5. Basic <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >vars.php
- <?php
-
- $color = 'green';
- $fruit = 'apple';
-
- ?>
-
- test.php
- <?php
-
- echo "A $color $fruit"; // A
-
- include 'vars.php';
-
- echo "A $color $fruit"; // A green apple
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
If the include occurs inside a function within the calling file,
- then all of the code contained in the called file will behave as
- though it had been defined inside that function. So, it will follow
- the variable scope of that function.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4830"
- ></A
- ><P
- ><B
- >Example 16-6. Including within functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- function foo()
- {
- global $color;
-
- include 'vars.php';
-
- echo "A $color $fruit";
- }
-
- /* vars.php is in the scope of foo() so *
- * $fruit is NOT available outside of this *
- * scope. $color is because we declared it *
- * as global. */
-
- foo(); // A green apple
- echo "A $color $fruit"; // A green
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
When a file is included, parsing drops out of PHP mode and
- into HTML mode at the beginning of the target file, and resumes
- again at the end. For this reason, any code inside the target
- file which should be executed as PHP code must be enclosed within
- <A
- HREF="#language.basic-syntax.phpmode"
- >valid PHP start
- and end tags</A
- >.
- </P
- ><P
- >
If "<A
- HREF="#ini.allow-url-fopen"
- >URL fopen wrappers</A
- >"
- are enabled in PHP (which they are in the default configuration),
- you can specify the file to be included using a URL (via HTTP or
- other supported wrapper - see <A
- HREF="#wrappers"
- >Appendix L</A
- > for a list
- of protocols) instead of a local pathname. If the target server interprets
- the target file as PHP code, variables may be passed to the included
- file using a URL request string as used with HTTP GET. This is
- not strictly speaking the same thing as including the file and having
- it inherit the parent file's variable scope; the script is actually
- being run on the remote server and the result is then being
- included into the local script.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >Windows versions of PHP
- prior to PHP 4.3.0 do not support accessing remote files via this function, even if
- <A
- HREF="#ini.allow-url-fopen"
- >allow_url_fopen</A
- > is enabled.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4842"
- ></A
- ><P
- ><B
- >Example 16-7. <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > through HTTP</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- /* This example assumes that www.example.com is configured to parse .php
- * files and not .txt files. Also, 'Works' here means that the variables
- * $foo and $bar are available within the included file. */
-
- // Won't work; file.txt wasn't handled by www.example.com as PHP
- include 'http://www.example.com/file.txt?foo=1&bar=2';
-
- // Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
- // local filesystem.
- include 'file.php?foo=1&bar=2';
-
- // Works.
- include 'http://www.example.com/file.php?foo=1&bar=2';
-
- $foo = 1;
- $bar = 2;
- include 'file.txt'; // Works.
- include 'file.php'; // Works.
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- See also <A
- HREF="#features.remote-files"
- >Remote files</A
- >,
- <A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- > and <A
- HREF="#function.file"
- ><B
- CLASS="function"
- >file()</B
- ></A
- > for related
- information.
- </P
- ><P
- >
Because <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > and <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >
- are special language constructs, you must enclose them within a statement
- block if it's inside a conditional block.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4853"
- ></A
- ><P
- ><B
- >Example 16-8. include() and conditional blocks</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- // This is WRONG and will not work as desired.
- if ($condition)
- include $file;
- else
- include $other;
-
-
- // This is CORRECT.
- if ($condition) {
- include $file;
- } else {
- include $other;
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Handling Returns: It is possible to execute a <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- >
- statement inside an included file in order to terminate processing in that
- file and return to the script which called it. Also, it's possible to return
- values from included files. You can take the value of the include call as
- you would a normal function. This is not, however, possible when including
- remote files unless the output of the remote file has
- <A
- HREF="#language.basic-syntax.phpmode"
- >valid PHP start
- and end tags</A
- > (as with any local file). You can declare the needed
- variables within those tags and they will be introduced at whichever point
- the file was included.
- </P
- ><P
- >
Because <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > is a special language construct,
- parentheses are not needed around its argument. Take care when comparing
- return value.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4861"
- ></A
- ><P
- ><B
- >Example 16-9. Comparing return value of include</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // won't work, evaluated as include(('vars.php') == 'OK'), i.e. include('')
- if (include('vars.php') == 'OK') {
- echo 'OK';
- }
-
- // works
- if ((include 'vars.php') == 'OK') {
- echo 'OK';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 3, the return may not appear inside a block unless it's
- a function block, in which case the <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > applies
- to that function and not the whole file.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4869"
- ></A
- ><P
- ><B
- >Example 16-10. <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > and the <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > statement</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >return.php
- <?php
-
- $var = 'PHP';
-
- return $var;
-
- ?>
-
- noreturn.php
- <?php
-
- $var = 'PHP';
-
- ?>
-
- testreturns.php
- <?php
-
- $foo = include 'return.php';
-
- echo $foo; // prints 'PHP'
-
- $bar = include 'noreturn.php';
-
- echo $bar; // prints 1
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<VAR
- CLASS="literal"
- >$bar</VAR
- > is the value <VAR
- CLASS="literal"
- >1</VAR
- > because the include
- was successful. Notice the difference between the above examples. The first uses
- <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > within the included file while the other does not.
- If the file can't be included, <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > is returned and
- <VAR
- CLASS="literal"
- >E_WARNING</VAR
- > is issued.
- </P
- ><P
- >
If there are functions defined in the included file, they can be used in the
- main file independent if they are before <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- > or after.
- If the file is included twice, PHP 5 issues fatal error because functions
- were already declared, while PHP 4 doesn't complain about functions
- defined after <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- >.
- It is recommended to use <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > instead of
- checking if the file was already included and conditionally return inside
- the included file.
- </P
- ><P
- >
A few other ways to "include" files into variables are with
- <A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- >, <A
- HREF="#function.file"
- ><B
- CLASS="function"
- >file()</B
- ></A
- > or by using
- <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > along with
- <A
- HREF="#ref.outcontrol"
- >Output Control Functions</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >Because this is a
- language construct and not a function, it cannot be called using
- <A
- HREF="#functions.variable-functions"
- >variable functions</A
- ></P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >, <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- >,
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >, <A
- HREF="#function.readfile"
- ><B
- CLASS="function"
- >readfile()</B
- ></A
- >,
- <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- >, and
- <A
- HREF="#ini.include-path"
- >include_path</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="function.require-once"
- ><A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- ></A
- ></H2
- ><P
- >
The <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > statement includes and evaluates
- the specified file during the execution of the script.
- This is a behavior similar to the <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > statement,
- with the only difference being that if the code from a file has already
- been included, it will not be included again. See the documentation for
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > for more information on how this statement
- works.
- </P
- ><P
- >
<A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > should be used in cases where
- the same file might be included and evaluated more than once during a
- particular execution of a script, and you want to be sure that it is
- included exactly once to avoid problems with function redefinitions,
- variable value reassignments, etc.
- </P
- ><P
- >
For examples on using <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > and
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >, look at the
- <A
- HREF="http://pear.php.net/"
- TARGET="_top"
- >PEAR</A
- > code included in the
- latest PHP source code distributions.
- </P
- ><P
- >
Return values are the same as with <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >. If the file
- was already included, this function returns <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > was added in PHP 4.0.1pl2
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Be aware, that the behaviour of <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- >
- and <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > may not be what you expect
- on a non case sensitive operating system (such as Windows).
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4924"
- ></A
- ><P
- ><B
- >Example 16-11. <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > is case insensitive on Windows</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- require_once("a.php"); // this will include a.php
- require_once("A.php"); // this will include a.php again on Windows! (PHP 4 only)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- This behaviour changed in PHP 5 - the path is normalized first so that
- <TT
- CLASS="filename"
- >C:\PROGRA~1\A.php</TT
- > is realized the same as
- <TT
- CLASS="filename"
- >C:\Program Files\a.php</TT
- > and the file is required just once.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >Windows versions of PHP
- prior to PHP 4.3.0 do not support accessing remote files via this function, even if
- <A
- HREF="#ini.allow-url-fopen"
- >allow_url_fopen</A
- > is enabled.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >,
- <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >, <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >,
- <A
- HREF="#function.get-required-files"
- ><B
- CLASS="function"
- >get_required_files()</B
- ></A
- >,
- <A
- HREF="#function.get-included-files"
- ><B
- CLASS="function"
- >get_included_files()</B
- ></A
- >, <A
- HREF="#function.readfile"
- ><B
- CLASS="function"
- >readfile()</B
- ></A
- >, and
- <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="function.include-once"
- ><A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- ></A
- ></H2
- ><P
- >
The <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > statement includes and evaluates
- the specified file during the execution of the script.
- This is a behavior similar to the <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > statement,
- with the only difference being that if the code from a file has already
- been included, it will not be included again. As the name suggests,
- it will be included just once.
- </P
- ><P
- >
<A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > should be used in cases where
- the same file might be included and evaluated more than once during a
- particular execution of a script, and you want to be sure that it is
- included exactly once to avoid problems with function redefinitions,
- variable value reassignments, etc.
- </P
- ><P
- >
For more examples on using <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > and
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >, look at the
- <A
- HREF="http://pear.php.net/"
- TARGET="_top"
- >PEAR</A
- > code included in the latest
- PHP source code distributions.
- </P
- ><P
- >
Return values are the same as with <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >. If the file
- was already included, this function returns <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > was added in PHP 4.0.1pl2
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Be aware, that the behaviour of <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >
- and <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > may not be what you expect
- on a non case sensitive operating system (such as Windows).
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4965"
- ></A
- ><P
- ><B
- >Example 16-12. <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- > is case insensitive on Windows</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- include_once("a.php"); // this will include a.php
- include_once("A.php"); // this will include a.php again on Windows! (PHP 4 only)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- This behaviour changed in PHP 5 - the path is normalized first so that
- <TT
- CLASS="filename"
- >C:\PROGRA~1\A.php</TT
- > is realized the same as
- <TT
- CLASS="filename"
- >C:\Program Files\a.php</TT
- > and the file is included just once.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >Windows versions of PHP
- prior to PHP 4.3.0 do not support accessing remote files via this function, even if
- <A
- HREF="#ini.allow-url-fopen"
- >allow_url_fopen</A
- > is enabled.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >,
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >, <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- >,
- <A
- HREF="#function.get-required-files"
- ><B
- CLASS="function"
- >get_required_files()</B
- ></A
- >,
- <A
- HREF="#function.get-included-files"
- ><B
- CLASS="function"
- >get_included_files()</B
- ></A
- >, <A
- HREF="#function.readfile"
- ><B
- CLASS="function"
- >readfile()</B
- ></A
- >,
- and <A
- HREF="#function.virtual"
- ><B
- CLASS="function"
- >virtual()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.functions"
- >Chapter 17. Functions</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="functions.user-defined"
- >User-defined functions</A
- ></H2
- ><P
- >
A function may be defined using syntax such as the following:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4988"
- ></A
- ><P
- ><B
- >Example 17-1. Pseudo code to demonstrate function uses</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo($arg_1, $arg_2, /* ..., */ $arg_n)
- {
- echo "Example function.\n";
- return $retval;
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Any valid PHP code may appear inside a function, even other
- functions and <A
- HREF="#keyword.class"
- >class</A
- >
- definitions.
- </P
- ><P
- >
In PHP 3, functions must be defined before they are referenced. No
- such requirement exists since PHP 4. <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >Except</I
- ></SPAN
- > when
- a function is conditionally defined such as shown in the two examples
- below.
- </P
- ><P
- >
When a function is defined in a conditional manner such as the two
- examples shown. Its definition must be processed <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >prior</I
- ></SPAN
- >
- to being called.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN4998"
- ></A
- ><P
- ><B
- >Example 17-2. Conditional functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $makefoo = true;
-
- /* We can't call foo() from here
- since it doesn't exist yet,
- but we can call bar() */
-
- bar();
-
- if ($makefoo) {
- function foo()
- {
- echo "I don't exist until program execution reaches me.\n";
- }
- }
-
- /* Now we can safely call foo()
- since $makefoo evaluated to true */
-
- if ($makefoo) foo();
-
- function bar()
- {
- echo "I exist immediately upon program start.\n";
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5002"
- ></A
- ><P
- ><B
- >Example 17-3. Functions within functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo()
- {
- function bar()
- {
- echo "I don't exist until foo() is called.\n";
- }
- }
-
- /* We can't call bar() yet
- since it doesn't exist. */
-
- foo();
-
- /* Now we can call bar(),
- foo()'s processesing has
- made it accessible. */
-
- bar();
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
PHP does not support function overloading, nor is it possible to
- undefine or redefine previously-declared functions.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Function names are case-insensitive, though it is usually good form
- to call functions as they appear in their declaration.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
PHP 3 does not support variable numbers of arguments to functions,
- although default arguments are supported (see <A
- HREF="#functions.arguments.default"
- >Default argument
- values</A
- > for more information). Both are supported, as of PHP 4: see <A
- HREF="#functions.variable-arg-list"
- >Variable-length argument
- lists</A
- > and the function references for
- <A
- HREF="#function.func-num-args"
- ><B
- CLASS="function"
- >func_num_args()</B
- ></A
- >,
- <A
- HREF="#function.func-get-arg"
- ><B
- CLASS="function"
- >func_get_arg()</B
- ></A
- >, and
- <A
- HREF="#function.func-get-args"
- ><B
- CLASS="function"
- >func_get_args()</B
- ></A
- > for more information.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="functions.arguments"
- >Function arguments</A
- ></H2
- ><P
- >
Information may be passed to functions via the argument list,
- which is a comma-delimited list of expressions.
- </P
- ><P
- >
PHP supports passing arguments by value (the default), <A
- HREF="#functions.arguments.by-reference"
- >passing by
- reference</A
- >, and <A
- HREF="#functions.arguments.default"
- >default argument
- values</A
- >. Variable-length argument lists are supported only
- in PHP 4 and later; see <A
- HREF="#functions.variable-arg-list"
- >Variable-length argument
- lists</A
- > and the function references for
- <A
- HREF="#function.func-num-args"
- ><B
- CLASS="function"
- >func_num_args()</B
- ></A
- >,
- <A
- HREF="#function.func-get-arg"
- ><B
- CLASS="function"
- >func_get_arg()</B
- ></A
- >, and
- <A
- HREF="#function.func-get-args"
- ><B
- CLASS="function"
- >func_get_args()</B
- ></A
- > for more information. A
- similar effect can be achieved in PHP 3 by passing an array of
- arguments to a function:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5025"
- ></A
- ><P
- ><B
- >Example 17-4. Passing arrays to functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function takes_array($input)
- {
- echo "$input[0] + $input[1] = ", $input[0]+$input[1];
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="functions.arguments.by-reference"
- >Making arguments be passed by reference</A
- ></H3
- ><P
- >
By default, function arguments are passed by value (so that if
- you change the value of the argument within the function, it does
- not get changed outside of the function). If you wish to allow a
- function to modify its arguments, you must pass them by
- reference.
- </P
- ><P
- >
If you want an argument to a function to always be passed by
- reference, you can prepend an ampersand (&) to the argument
- name in the function definition:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5033"
- ></A
- ><P
- ><B
- >Example 17-5. Passing function parameters by reference</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function add_some_extra(&$string)
- {
- $string .= 'and something extra.';
- }
- $str = 'This is a string, ';
- add_some_extra($str);
- echo $str; // outputs 'This is a string, and something extra.'
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="functions.arguments.default"
- >Default argument values</A
- ></H3
- ><P
- >
A function may define C++-style default values for scalar
- arguments as follows:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5040"
- ></A
- ><P
- ><B
- >Example 17-6. Use of default parameters in functions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function makecoffee($type = "cappuccino")
- {
- return "Making a cup of $type.\n";
- }
- echo makecoffee();
- echo makecoffee("espresso");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The output from the above snippet is:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Making a cup of cappuccino.
- Making a cup of espresso.</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Also PHP allows you to use arrays and special type NULL as
- default values, for example:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5048"
- ></A
- ><P
- ><B
- >Example 17-7. Using non-scalar types as default values</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
- {
- $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
- return "Making a cup of ".join(", ", $types)." with $device.\n";
- }
- echo makecoffee();
- echo makecoffee(array("cappuccino", "lavazza"), "teapot");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
-
- </P
- ><P
- >
The default value must be a constant expression, not (for
- example) a variable, a class member or a function call.
- </P
- ><P
- >
Note that when using default arguments, any defaults should be on
- the right side of any non-default arguments; otherwise, things
- will not work as expected. Consider the following code snippet:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5054"
- ></A
- ><P
- ><B
- >Example 17-8. Incorrect usage of default function arguments</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function makeyogurt($type = "acidophilus", $flavour)
- {
- return "Making a bowl of $type $flavour.\n";
- }
-
- echo makeyogurt("raspberry"); // won't work as expected
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The output of the above example is:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Warning: Missing argument 2 in call to makeyogurt() in
- /usr/local/etc/httpd/htdocs/php3test/functest.html on line 41
- Making a bowl of raspberry .</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Now, compare the above with this:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5062"
- ></A
- ><P
- ><B
- >Example 17-9. Correct usage of default function arguments</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function makeyogurt($flavour, $type = "acidophilus")
- {
- return "Making a bowl of $type $flavour.\n";
- }
-
- echo makeyogurt("raspberry"); // works as expected
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The output of this example is:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Making a bowl of acidophilus raspberry.</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- As of PHP 5, default values may be passed by reference.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="functions.variable-arg-list"
- >Variable-length argument lists</A
- ></H3
- ><P
- >
PHP 4 and above has support for variable-length argument lists in
- user-defined functions. This is really quite easy, using the
- <A
- HREF="#function.func-num-args"
- ><B
- CLASS="function"
- >func_num_args()</B
- ></A
- >,
- <A
- HREF="#function.func-get-arg"
- ><B
- CLASS="function"
- >func_get_arg()</B
- ></A
- >, and
- <A
- HREF="#function.func-get-args"
- ><B
- CLASS="function"
- >func_get_args()</B
- ></A
- > functions.
- </P
- ><P
- >
No special syntax is required, and argument lists may still be
- explicitly provided with function definitions and will behave as
- normal.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="functions.returning-values"
- >Returning values</A
- ></H2
- ><P
- >
Values are returned by using the optional return statement. Any
- type may be returned, including lists and objects. This causes the
- function to end its execution immediately and pass control back to
- the line from which it was called. See <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- >
- for more information.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5082"
- ></A
- ><P
- ><B
- >Example 17-10. Use of <A
- HREF="#function.return"
- ><B
- CLASS="function"
- >return()</B
- ></A
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function square($num)
- {
- return $num * $num;
- }
- echo square(4); // outputs '16'.
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
You can't return multiple values from a function, but similar
- results can be obtained by returning a list.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5088"
- ></A
- ><P
- ><B
- >Example 17-11. Returning an array to get multiple values</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function small_numbers()
- {
- return array (0, 1, 2);
- }
- list ($zero, $one, $two) = small_numbers();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
To return a reference from a function, you have to use
- the reference operator & in both the function declaration and
- when assigning the returned value to a variable:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5093"
- ></A
- ><P
- ><B
- >Example 17-12. Returning a reference from a function</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function &returns_reference()
- {
- return $someref;
- }
-
- $newref =& returns_reference();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
For more information on references, please check out <A
- HREF="#language.references"
- >References Explained</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="functions.variable-functions"
- >Variable functions</A
- ></H2
- ><P
- >
PHP supports the concept of variable functions. This means that if
- a variable name has parentheses appended to it, PHP will look for
- a function with the same name as whatever the variable evaluates
- to, and will attempt to execute it. Among other things, this can
- be used to implement callbacks, function tables, and so forth.
- </P
- ><P
- >
Variable functions won't work with language constructs such
- as <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- >, <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- >,
- <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >, <A
- HREF="#function.isset"
- ><B
- CLASS="function"
- >isset()</B
- ></A
- >,
- <A
- HREF="#function.empty"
- ><B
- CLASS="function"
- >empty()</B
- ></A
- >, <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >,
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > and the like. You need to use
- your own wrapper function to utilize any of these constructs
- as variable functions.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5110"
- ></A
- ><P
- ><B
- >Example 17-13. Variable function example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo() {
- echo "In foo()<br />\n";
- }
-
- function bar($arg = '')
- {
- echo "In bar(); argument was '$arg'.<br />\n";
- }
-
- // This is a wrapper function around echo
- function echoit($string)
- {
- echo $string;
- }
-
- $func = 'foo';
- $func(); // This calls foo()
-
- $func = 'bar';
- $func('test'); // This calls bar()
-
- $func = 'echoit';
- $func('test'); // This calls echoit()
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
You can also call an object's method by using the variable functions
- feature.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5114"
- ></A
- ><P
- ><B
- >Example 17-14. Variable method example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Foo
- {
- function Variable()
- {
- $name = 'Bar';
- $this->$name(); // This calls the Bar() method
- }
-
- function Bar()
- {
- echo "This is Bar";
- }
- }
-
- $foo = new Foo();
- $funcname = "Variable";
- $foo->$funcname(); // This calls $foo->Variable()
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.call-user-func"
- ><B
- CLASS="function"
- >call_user_func()</B
- ></A
- >,
- <A
- HREF="#language.variables.variable"
- >
variable variables</A
- > and <A
- HREF="#function.function-exists"
- ><B
- CLASS="function"
- >function_exists()</B
- ></A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="functions.internal"
- >Internal (built-in) functions</A
- ></H2
- ><P
- >
PHP comes standard with many functions and constructs. There are also
- functions that require specific PHP extensions compiled in otherwise
- you'll get fatal "undefined function" errors. For example, to use
- <A
- HREF="#ref.image"
- >image</A
- > functions such as
- <A
- HREF="#function.imagecreatetruecolor"
- ><B
- CLASS="function"
- >imagecreatetruecolor()</B
- ></A
- >, you'll need your PHP compiled
- with <SPAN
- CLASS="productname"
- >GD</SPAN
- > support. Or, to use <A
- HREF="#function.mysql-connect"
- ><B
- CLASS="function"
- >mysql_connect()</B
- ></A
- > you'll
- need your PHP compiled in with <A
- HREF="#ref.mysql"
- >MySQL</A
- >
- support. There are many core functions that are included in every
- version of PHP like the <A
- HREF="#ref.strings"
- >string</A
- > and
- <A
- HREF="#ref.var"
- >variable</A
- > functions. A call
- to <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > or
- <A
- HREF="#function.get-loaded-extensions"
- ><B
- CLASS="function"
- >get_loaded_extensions()</B
- ></A
- > will show you which
- extensions are loaded into your PHP. Also note that many extensions are
- enabled by default and that the PHP manual is split up by extension.
- See the <A
- HREF="#configuration"
- >configuration</A
- >,
- <A
- HREF="#install"
- >installation</A
- >, and individual
- extension chapters, for information on how to setup your PHP.
- </P
- ><P
- >
Reading and understanding a function's prototype is explained within the
- manual section titled
- <A
- HREF="#about.prototypes"
- >how to read a function definition</A
- >.
- It's important to realize what a function returns or if a function works
- directly on a passed in value. For example,
- <A
- HREF="#function.str-replace"
- ><B
- CLASS="function"
- >str_replace()</B
- ></A
- > will return the modified string while
- <A
- HREF="#function.usort"
- ><B
- CLASS="function"
- >usort()</B
- ></A
- > works on the actual passed in variable
- itself. Each manual page also has specific information for each
- function like information on function parameters, behavior changes,
- return values for both success and failure, and availability information.
- Knowing these important (yet often subtle) differences is crucial for
- writing correct PHP code.
- </P
- ><P
- >
See also <A
- HREF="#function.function-exists"
- ><B
- CLASS="function"
- >function_exists()</B
- ></A
- >,
- <A
- HREF="#funcref"
- >the function reference</A
- >,
- <A
- HREF="#function.get-extension-funcs"
- ><B
- CLASS="function"
- >get_extension_funcs()</B
- ></A
- >, and
- <A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.oop"
- >Chapter 18. Classes and Objects (PHP 4)</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="keyword.class"
- ><VAR
- CLASS="literal"
- >class</VAR
- ></A
- ></H2
- ><P
- >
A class is a collection of variables and functions working with
- these variables. A class is defined using the following syntax:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5151"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Cart {
- var $items; // Items in our shopping cart
-
- // Add $num articles of $artnr to the cart
-
- function add_item($artnr, $num) {
- $this->items[$artnr] += $num;
- }
-
- // Take $num articles of $artnr out of the cart
-
- function remove_item($artnr, $num) {
- if ($this->items[$artnr] > $num) {
- $this->items[$artnr] -= $num;
- return true;
- } elseif ($this->items[$artnr] == $num) {
- unset($this->items[$artnr]);
- return true;
- } else {
- return false;
- }
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This defines a class named Cart that consists of an associative
- array of articles in the cart and two functions to add and remove
- items from this cart.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
You can <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >NOT</I
- ></SPAN
- > break up a class definition into
- multiple files. You also can <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >NOT</I
- ></SPAN
- > break a class
- definition into multiple PHP blocks, unless the break is within a method
- declaration. The following will not work:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5159"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class test {
- ?>
- <?php
- function test() {
- print 'OK';
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
However, the following is allowed:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5163"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class test {
- function test() {
- ?>
- <?php
- print 'OK';
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
The following cautionary notes are valid for PHP 4.
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The name <VAR
- CLASS="literal"
- >stdClass</VAR
- > is used interally by
- Zend and is reserved. You cannot have a class named
- <VAR
- CLASS="literal"
- >stdClass</VAR
- > in PHP.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The function names <VAR
- CLASS="literal"
- >__sleep</VAR
- > and
- <VAR
- CLASS="literal"
- >__wakeup</VAR
- > are magical in PHP classes. You
- cannot have functions with these names in any of your
- classes unless you want the magic functionality associated
- with them. See below for more information.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
PHP reserves all function names starting with __ as magical.
- It is recommended that you do not use function names with
- __ in PHP unless you want some documented magic functionality.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
In PHP 4, only constant initializers for <VAR
- CLASS="literal"
- >var</VAR
- >
- variables are allowed. To initialize variables with non-constant
- values, you need an initialization function which is called
- automatically when an object is being constructed from the
- class. Such a function is called a constructor (see below).
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5178"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Cart {
- /* None of these will work in PHP 4. */
- var $todays_date = date("Y-m-d");
- var $name = $firstname;
- var $owner = 'Fred ' . 'Jones';
- /* Arrays containing constant values will, though. */
- var $items = array("VCR", "TV");
- }
-
- /* This is how it should be done. */
- class Cart {
- var $todays_date;
- var $name;
- var $owner;
- var $items = array("VCR", "TV");
-
- function Cart() {
- $this->todays_date = date("Y-m-d");
- $this->name = $GLOBALS['firstname'];
- /* etc. . . */
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Classes are types, that is, they are blueprints for actual
- variables. You have to create a variable of the desired type with
- the <VAR
- CLASS="literal"
- >new</VAR
- > operator.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5182"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $cart = new Cart;
- $cart->add_item("10", 1);
-
- $another_cart = new Cart;
- $another_cart->add_item("0815", 3);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
This creates the objects <VAR
- CLASS="varname"
- >$cart</VAR
- > and
- <VAR
- CLASS="varname"
- >$another_cart</VAR
- >, both of the class Cart. The function
- add_item() of the <VAR
- CLASS="varname"
- >$cart</VAR
- > object is being called to add 1
- item of article number 10 to the <VAR
- CLASS="varname"
- >$cart</VAR
- >. 3 items of
- article number 0815 are being added to <VAR
- CLASS="varname"
- >$another_cart</VAR
- >.
- </P
- ><P
- >
Both, <VAR
- CLASS="varname"
- >$cart</VAR
- > and <VAR
- CLASS="varname"
- >$another_cart</VAR
- >, have
- functions add_item(), remove_item() and a variable items. These are
- distinct functions and variables. You can think of the objects as
- something similar to directories in a filesystem. In a filesystem you can
- have two different files <TT
- CLASS="filename"
- >README.TXT</TT
- >, as long as they are in different
- directories. Just like with directories where you'll have to type the
- full pathname in order to reach each file from the toplevel directory, you
- have to specify the complete name of the function you want to call: In PHP
- terms, the toplevel directory would be the global namespace, and the
- pathname separator would be <VAR
- CLASS="literal"
- >-></VAR
- >. Thus, the names
- <VAR
- CLASS="varname"
- >$cart->items</VAR
- > and
- <VAR
- CLASS="varname"
- >$another_cart->items</VAR
- > name two different variables.
- Note that the variable is named <VAR
- CLASS="varname"
- >$cart->items</VAR
- >, not
- <VAR
- CLASS="varname"
- >$cart->$items</VAR
- >, that is, a variable name in PHP has
- only a single dollar sign.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5199"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // correct, single $
- $cart->items = array("10" => 1);
-
- // invalid, because $cart->$items becomes $cart->""
- $cart->$items = array("10" => 1);
-
- // correct, but may or may not be what was intended:
- // $cart->$myvar becomes $cart->items
- $myvar = 'items';
- $cart->$myvar = array("10" => 1);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
Within a class definition, you do not know under which name the object
- will be accessible in your program: at the time the Cart class was
- written, it was unknown that the object will be named
- <VAR
- CLASS="varname"
- >$cart</VAR
- > or <VAR
- CLASS="varname"
- >$another_cart</VAR
- > later. Thus,
- you cannot write <VAR
- CLASS="varname"
- >$cart->items</VAR
- > within the Cart class
- itself. Instead, in order to be able to access it's own functions and
- variables from within a class, one can use the pseudo-variable
- <VAR
- CLASS="varname"
- >$this</VAR
- > which can be read as 'my own' or 'current
- object'. Thus, '<VAR
- CLASS="varname"
- >$this->items[$artnr]</VAR
- > +=
- <VAR
- CLASS="varname"
- >$num</VAR
- >' can be read as 'add <VAR
- CLASS="varname"
- >$num</VAR
- > to
- the <VAR
- CLASS="varname"
- >$artnr</VAR
- > counter of my own items array' or 'add
- <VAR
- CLASS="varname"
- >$num</VAR
- > to the <VAR
- CLASS="varname"
- >$artnr</VAR
- > counter of the
- items array within the current object'.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- There are some nice functions to handle classes and objects. You might want
- to take a look at the <A
- HREF="#ref.classobj"
- >Class/Object
- Functions</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="keyword.extends"
- ><VAR
- CLASS="literal"
- >extends</VAR
- ></A
- ></H2
- ><P
- >
Often you need classes with similar variables and functions
- to another existing class. In fact, it is good practice to
- define a generic class which can be used in all your
- projects and adapt this class for the needs of each of your
- specific projects. To facilitate this, classes can be
- extensions of other classes. The extended or derived class
- has all variables and functions of the base class (this is
- called 'inheritance' despite the fact that nobody died) and what
- you add in the extended definition. It is not possible to
- subtract from a class, that is, to undefine any existing
- functions or variables. An extended class is always dependent
- on a single base class, that is, multiple inheritance is
- not supported. Classes are extended using the keyword 'extends'.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5219"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Named_Cart extends Cart {
- var $owner;
-
- function set_owner ($name) {
- $this->owner = $name;
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
This defines a class Named_Cart that has all variables and functions of
- Cart plus an additional variable <VAR
- CLASS="varname"
- >$owner</VAR
- > and an
- additional function set_owner(). You create a named cart the usual way and
- can now set and get the carts owner. You can still use normal cart
- functions on named carts:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5223"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $ncart = new Named_Cart; // Create a named cart
- $ncart->set_owner("kris"); // Name that cart
- print $ncart->owner; // print the cart owners name
- $ncart->add_item("10", 1); // (inherited functionality from cart)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
This is also called a "parent-child" relationship. You create a class,
- parent, and use <VAR
- CLASS="literal"
- >extends</VAR
- > to create a new class
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >based</I
- ></SPAN
- > on the parent class: the child class. You can
- even use this new child class and create another class based on this child
- class.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Classes must be defined before they are used! If you want the class
- <VAR
- CLASS="literal"
- >Named_Cart</VAR
- > to extend the class
- <VAR
- CLASS="literal"
- >Cart</VAR
- >, you will have to define the class
- <VAR
- CLASS="literal"
- >Cart</VAR
- > first. If you want to create another class called
- <VAR
- CLASS="literal"
- >Yellow_named_cart</VAR
- > based on the class
- <VAR
- CLASS="literal"
- >Named_Cart</VAR
- > you have to define
- <VAR
- CLASS="literal"
- >Named_Cart</VAR
- > first. To make it short: the order in which
- the classes are defined is important.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop.constructor"
- ><VAR
- CLASS="literal"
- >Constructors</VAR
- ></A
- ></H2
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
In PHP 3 and PHP 4 constructors behave differently. The PHP 4
- semantics are strongly preferred.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
Constructors are functions in a class that are automatically
- called when you create a new instance of a class with
- <VAR
- CLASS="literal"
- >new</VAR
- >. In PHP 3, a
- function becomes a constructor when it has the same name as
- the class. In PHP 4, a function becomes a constructor, when
- it has the same name as the class it is defined in - the
- difference is subtle, but crucial (see below).
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5243"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Works in PHP 3 and PHP 4.
- class Auto_Cart extends Cart {
- function Auto_Cart() {
- $this->add_item("10", 1);
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
This defines a class Auto_Cart that is a Cart plus a constructor
- which initializes the cart with one item of article number "10"
- each time a new Auto_Cart is being made with "new". Constructors
- can take arguments and these arguments can be optional, which
- makes them much more useful. To be able to still use the class
- without parameters, all parameters to constructors should be
- made optional by providing default values.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5246"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Works in PHP 3 and PHP 4.
- class Constructor_Cart extends Cart {
- function Constructor_Cart($item = "10", $num = 1) {
- $this->add_item ($item, $num);
- }
- }
-
- // Shop the same old boring stuff.
-
- $default_cart = new Constructor_Cart;
-
- // Shop for real...
-
- $different_cart = new Constructor_Cart("20", 17);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
You also can use the <VAR
- CLASS="literal"
- >@</VAR
- > operator to
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >mute</I
- ></SPAN
- > errors occurring in the constructor, e.g.
- <VAR
- CLASS="literal"
- >@new</VAR
- >.
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
In PHP 3, derived classes and constructors have a number of
- limitations. The following examples should be read carefully
- to understand these limitations.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5254"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class A {
- function A() {
- echo "I am the constructor of A.<br />\n";
- }
- }
-
- class B extends A {
- function C() {
- echo "I am a regular function.<br />\n";
- }
- }
-
- // no constructor is being called in PHP 3.
- $b = new B;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
In PHP 3, no constructor is being called in the above example.
- The rule in PHP 3 is: 'A constructor is a function of the same
- name as the class.'. The name of the class is B, and there is
- no function called B() in class B. Nothing happens.
- </P
- ><P
- >
This is fixed in PHP 4 by introducing another rule: If a class
- has no constructor, the constructor of the base class is being
- called, if it exists. The above example would have printed
- 'I am the constructor of A.<br />' in PHP 4.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5258"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class A
- {
- function A()
- {
- echo "I am the constructor of A.<br />\n";
- }
-
- function B()
- {
- echo "I am a regular function named B in class A.<br />\n";
- echo "I am not a constructor in A.<br />\n";
- }
- }
-
- class B extends A
- {
- function C()
- {
- echo "I am a regular function.<br />\n";
- }
- }
-
- // This will call B() as a constructor.
- $b = new B;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
In PHP 3, the function B() in class A will suddenly become a
- constructor in class B, although it was never intended to be.
- The rule in PHP 3 is: 'A constructor is a function of the same
- name as the class.'. PHP 3 does not care if the function is
- being defined in class B, or if it has been inherited.
- </P
- ><P
- >
This is fixed in PHP 4 by modifying the rule to: 'A constructor
- is a function of the same name as the class it is being defined
- in.'. Thus in PHP 4, the class B would have no constructor function
- of its own and the constructor of the base class would have been
- called, printing 'I am the constructor of A.<br />'.
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Neither PHP 3 nor PHP 4 call constructors of the base class
- automatically from a constructor of a derived class. It is
- your responsibility to propagate the call to constructors
- upstream where appropriate.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- There are no destructors in PHP 3 or PHP 4. You may use
- <A
- HREF="#function.register-shutdown-function"
- ><B
- CLASS="function"
- >register_shutdown_function()</B
- ></A
- > instead
- to simulate most effects of destructors.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Destructors are functions that are called automatically
- when an object is destroyed, either with <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >
- or by simply going out of scope. There are no destructors
- in PHP.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="keyword.paamayim-nekudotayim"
- >Scope Resolution Operator (<VAR
- CLASS="literal"
- >::</VAR
- >)</A
- ></H2
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The following is valid for PHP 4 and later only.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
Sometimes it is useful to refer to functions and variables
- in base classes or to refer to functions in classes that
- have not yet any instances. The :: operator is being used
- for this.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5275"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class A {
- function example() {
- echo "I am the original function A::example().<br />\n";
- }
- }
-
- class B extends A {
- function example() {
- echo "I am the redefined function B::example().<br />\n";
- A::example();
- }
- }
-
- // there is no object of class A.
- // this will print
- // I am the original function A::example().<br />
- A::example();
-
- // create an object of class B.
- $b = new B;
-
- // this will print
- // I am the redefined function B::example().<br />
- // I am the original function A::example().<br />
- $b->example();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
The above example calls the function example() in
- class A, but there is no object of class A, so that
- we cannot write $a->example() or similar. Instead we
- call example() as a 'class function', that is, as a
- function of the class itself, not any object of that
- class.
- </P
- ><P
- >
There are class functions, but there are no class variables.
- In fact, there is no object at all at the time of the call.
- Thus, a class function may not use any object variables (but
- it can use local and global variables), and it may no use
- <VAR
- CLASS="varname"
- >$this</VAR
- > at all.
- </P
- ><P
- >
In the above example, class B redefines the function example().
- The original definition in class A is shadowed
- and no longer available, unless you are referring specifically
- to the implementation of example() in class A using the
- ::-operator. Write A::example() to do this (in fact, you
- should be writing parent::example(), as shown in the next
- section).
- </P
- ><P
- >
In this context, there is a current object and it may have object
- variables. Thus, when used from WITHIN an object function, you may use
- <VAR
- CLASS="varname"
- >$this</VAR
- > and object variables.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="keyword.parent"
- ><VAR
- CLASS="literal"
- >parent</VAR
- ></A
- ></H2
- ><P
- >
You may find yourself writing code that refers to
- variables and functions in base classes. This is
- particularly true if your derived class is a refinement
- or specialisation of code in your base class.
- </P
- ><P
- >
Instead of using the literal name of the base class in your
- code, you should be using the special name
- <VAR
- CLASS="literal"
- >parent</VAR
- >, which refers to the name of your
- base class as given in the <VAR
- CLASS="literal"
- >extends</VAR
- >
- declaration of your class. By doing this, you avoid using the
- name of your base class in more than one place. Should
- your inheritance tree change during implementation, the
- change is easily made by simply changing the
- <VAR
- CLASS="literal"
- >extends</VAR
- > declaration of your class.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5291"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class A {
- function example() {
- echo "I am A::example() and provide basic functionality.<br />\n";
- }
- }
-
- class B extends A {
- function example() {
- echo "I am B::example() and provide additional functionality.<br />\n";
- parent::example();
- }
- }
-
- $b = new B;
-
- // This will call B::example(), which will in turn call A::example().
- $b->example();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop.serialization"
- >Serializing objects - objects in sessions</A
- ></H2
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 3, objects will lose their class association
- throughout the process of serialization and unserialization.
- The resulting variable is of type object, but has no class
- and no methods, thus it is pretty useless (it has become
- just like an array with a funny syntax).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The following information is valid for PHP 4 only.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
<A
- HREF="#function.serialize"
- ><B
- CLASS="function"
- >serialize()</B
- ></A
- > returns a string containing a
- byte-stream representation of any value that can be stored in
- PHP. <A
- HREF="#function.unserialize"
- ><B
- CLASS="function"
- >unserialize()</B
- ></A
- > can use this string to
- recreate the original variable values. Using serialize to
- save an object will save all variables in an object. The
- functions in an object will not be saved, only the name of
- the class.
- </P
- ><P
- >
In order to be able to <A
- HREF="#function.unserialize"
- ><B
- CLASS="function"
- >unserialize()</B
- ></A
- > an object, the
- class of that object needs to be defined. That is, if you have an object
- <VAR
- CLASS="varname"
- >$a</VAR
- > of class A on page1.php and serialize this, you'll
- get a string that refers to class A and contains all values of variabled
- contained in <VAR
- CLASS="varname"
- >$a</VAR
- >. If you want to be able to unserialize
- this on page2.php, recreating <VAR
- CLASS="varname"
- >$a</VAR
- > of class A, the
- definition of class A must be present in page2.php. This can be done for
- example by storing the class definition of class A in an include file and
- including this file in both page1.php and page2.php.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5307"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="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);
- // store $s somewhere where page2.php can find it.
- $fp = fopen("store", "w");
- fwrite($fp, $s);
- fclose($fp);
-
- // page2.php:
-
- // this is needed for the unserialize to work properly.
- include("classa.inc");
-
- $s = implode("", @file("store"));
- $a = unserialize($s);
-
- // now use the function show_one() of the $a object.
- $a->show_one();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
If you are using sessions and use <A
- HREF="#function.session-register"
- ><B
- CLASS="function"
- >session_register()</B
- ></A
- >
- to register objects, these objects are serialized automatically
- at the end of each PHP page, and are unserialized automatically on
- each of the following pages. This basically means that these objects
- can show up on any of your pages once they become part of your
- session.
- </P
- ><P
- >
It is strongly recommended that you include the class
- definitions of all such registered objects on all of your
- pages, even if you do not actually use these classes on all
- of your pages. If you don't and an object is being
- unserialized without its class definition being present, it
- will lose its class association and become an object of class
- <VAR
- CLASS="literal"
- >stdClass</VAR
- > without any functions available
- at all, that is, it will become quite useless.
- </P
- ><P
- >
So if in the example above <VAR
- CLASS="varname"
- >$a</VAR
- > became part of a session
- by running <VAR
- CLASS="literal"
- >session_register("a")</VAR
- >, you should include the
- file <VAR
- CLASS="literal"
- >classa.inc</VAR
- > on all of your pages, not only page1.php
- and page2.php.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop.magic-functions"
- >The magic functions <VAR
- CLASS="literal"
- >__sleep</VAR
- > and <VAR
- CLASS="literal"
- >__wakeup</VAR
- ></A
- ></H2
- ><P
- >
<A
- HREF="#function.serialize"
- ><B
- CLASS="function"
- >serialize()</B
- ></A
- > checks if your class has a function with
- the magic name <VAR
- CLASS="literal"
- >__sleep</VAR
- >. If so, that function is
- being run prior to any serialization. It can clean up the object
- and is supposed to return an array with the names of all variables
- of that object that should be serialized.
- </P
- ><P
- >
The intended use of <VAR
- CLASS="literal"
- >__sleep</VAR
- > is to close any
- database connections that object may have, committing pending
- data or perform similar cleanup tasks. Also, the function is
- useful if you have very large objects which need not be
- saved completely.
- </P
- ><P
- >
Conversely, <A
- HREF="#function.unserialize"
- ><B
- CLASS="function"
- >unserialize()</B
- ></A
- > checks for the
- presence of a function with the magic name
- <VAR
- CLASS="literal"
- >__wakeup</VAR
- >. If present, this function can
- reconstruct any resources that object may have.
- </P
- ><P
- >
The intended use of <VAR
- CLASS="literal"
- >__wakeup</VAR
- > is to
- reestablish any database connections that may have been lost
- during serialization and perform other reinitialization
- tasks.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop.newref"
- >References inside the constructor</A
- ></H2
- ><P
- >
Creating references within the constructor can lead to confusing
- results. This tutorial-like section helps you to avoid problems.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5334"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Foo {
- function Foo($name) {
- // create a reference inside the global array $globalref
- global $globalref;
- $globalref[] = &$this;
- // set name to passed value
- $this->setName($name);
- // and put it out
- $this->echoName();
- }
-
- function echoName() {
- echo "<br />", $this->name;
- }
-
- function setName($name) {
- $this->name = $name;
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Let us check out if there is a difference between
- <VAR
- CLASS="varname"
- >$bar1</VAR
- > which has been created using
- the copy <VAR
- CLASS="literal"
- >=</VAR
- > operator and
- <VAR
- CLASS="varname"
- >$bar2</VAR
- > which has been created using
- the reference <VAR
- CLASS="literal"
- >=&</VAR
- > operator...
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5341"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $bar1 = new Foo('set in constructor');
- $bar1->echoName();
- $globalref[0]->echoName();
-
- /* output:
- set in constructor
- set in constructor
- set in constructor */
-
- $bar2 =& new Foo('set in constructor');
- $bar2->echoName();
- $globalref[1]->echoName();
-
- /* output:
- set in constructor
- set in constructor
- set in constructor */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Apparently there is no difference, but in fact there is a
- very significant one: <VAR
- CLASS="varname"
- >$bar1</VAR
- > and
- <VAR
- CLASS="varname"
- >$globalref[0]</VAR
- > are _NOT_ referenced, they
- are NOT the same variable. This is because "new" does not
- return a reference by default, instead it returns a copy.
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- There is no performance loss (since PHP 4 and up use reference
- counting) returning copies instead of references. On the
- contrary it is most often better to simply work with copies
- instead of references, because creating references takes some
- time where creating copies virtually takes no time (unless none
- of them is a large array or object and one of them gets changed
- and the other(s) one(s) subsequently, then it would be wise to
- use references to change them all concurrently).
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- To prove what is written above let us watch the code below.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5348"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // now we will change the name. what do you expect?
- // you could expect that both $bar1 and $globalref[0] change their names...
- $bar1->setName('set from outside');
-
- // as mentioned before this is not the case.
- $bar1->echoName();
- $globalref[0]->echoName();
-
- /* output:
- set from outside
- set in constructor */
-
- // let us see what is different with $bar2 and $globalref[1]
- $bar2->setName('set from outside');
-
- // luckily they are not only equal, they are the same variable
- // thus $bar2->name and $globalref[1]->name are the same too
- $bar2->echoName();
- $globalref[1]->echoName();
-
- /* output:
- set from outside
- set from outside */
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
Another final example, try to understand it.
-
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5351"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class A {
- function A($i) {
- $this->value = $i;
- // try to figure out why we do not need a reference here
- $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;
- }
- }
-
- // try to understand why using a simple copy here would yield
- // in an undesired result in the *-marked line
- $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();
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This example will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >class A: 10
- class B: 10
- class B: 10
- class A: 11
- class B: 11
- class B: 11</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop.object-comparison"
- >Comparing objects</A
- ></H2
- ><P
- >
In PHP 4, objects are compared in a very simple manner, namely: Two object
- instances are equal if they have the same attributes and values, and are
- instances of the same class. Similar rules are applied when comparing two
- objects using the identity operator (<VAR
- CLASS="literal"
- >===</VAR
- >).
- </P
- ><P
- >
If we were to execute the code in the example below:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5360"
- ></A
- ><P
- ><B
- >Example 18-1. Example of object comparison in PHP 4</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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 "Compare instances created with the same parameters\n";
- compareObjects($o, $q);
-
- echo "\nCompare instances created with different parameters\n";
- compareObjects($o, $p);
-
- echo "\nCompare an instance of a parent class with one from a subclass\n";
- compareObjects($o, $r);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- We will see:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Compare instances created with the same parameters
- o1 == o2 : TRUE
- o1 != o2 : FALSE
- o1 === o2 : TRUE
- o1 !== o2 : FALSE
-
- Compare instances created with different parameters
- o1 == o2 : FALSE
- o1 != o2 : TRUE
- o1 === o2 : FALSE
- o1 !== o2 : TRUE
-
- Compare an instance of a parent class with one from a subclass
- o1 == o2 : FALSE
- o1 != o2 : TRUE
- o1 === o2 : FALSE
- o1 !== o2 : TRUE</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Which is the output we will expect to obtain given the comparison rules
- above. Only instances with the same values for their attributes and from the same
- class are considered equal and identical.
- </P
- ><P
- >
Even in the cases where we have object composition, the same comparison
- rules apply. In the example below we create a container class that stores
- an associative array of <B
- CLASS="classname"
- >Flag</B
- > objects.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5366"
- ></A
- ><P
- ><B
- >Example 18-2. Compound object comparisons in PHP 4</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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 "\nComposite objects u(o,p) and v(q,p)\n";
- compareObjects($u, $v);
-
- echo "\nu(o,p) and w(q)\n";
- compareObjects($u, $w);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Which gives the expected output:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Composite objects u(o,p) and 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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.oop5"
- >Chapter 19. Classes and Objects (PHP 5)</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="op5.intro"
- >Introduction</A
- ></H2
- ><P
- >
In PHP 5 there is a new Object Model. PHP's handling of objects has been
- completely rewritten, allowing for better performance and more features.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.basic"
- >The Basics</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.basic.class"
- >class</A
- ></H3
- ><P
- >
Every class definition begins with the keyword class, followed by a class
- name, which can be any name that isn't a <A
- HREF="#reserved"
- >reserved</A
- >
- word in PHP. Followed by a pair of curly braces, of
- which contains the definition of the classes members and methods. Within
- each method, except for <A
- HREF="#language.oop5.static"
- >static</A
- >
- methods, a pseudo variable <VAR
- CLASS="varname"
- >$this</VAR
- > is available.
- <VAR
- CLASS="varname"
- >$this</VAR
- > is a reference to the same instance that
- called the method.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5384"
- ></A
- ><P
- ><B
- >Example 19-1. Simple Class definition</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class SimpleClass
- {
- // member declaration
- public $var = 'a default value';
-
- // method declaration
- public function displayVar() {
- echo $this->var;
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.basic.new"
- >new</A
- ></H3
- ><P
- >
To create an instance of an object, a new object must be created and
- assigned to a variable. An object will always be assigned when
- creating a new object unless the object has a
- <A
- HREF="#language.oop5.decon"
- >constructor</A
- > defined that throws an
- <A
- HREF="#language.exceptions"
- >exception</A
- > on error.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5392"
- ></A
- ><P
- ><B
- >Example 19-2. Creating an instance</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $instance = new SimpleClass()
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
When assigning an already created instance of an object to a new variable, the new variable
- will access the same instance as the object that was assigned. This
- behaviour is the same when passing instances to a function. A new instance
- of an already created object can be made by
- <A
- HREF="#language.oop5.cloning"
- >cloning</A
- > it.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5397"
- ></A
- ><P
- ><B
- >Example 19-3. Object Assignment</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $assigned = $instance;
- $reference =& $instance;
-
- $instance->var = '$assigned will have this value';
-
- $instance = null; // $instance and $reference become null
-
- var_dump($instance);
- var_dump($reference);
- var_dump($assigned);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >NULL
- NULL
- object(SimpleClass)#1 (1) {
- ["var"]=>
- string(30) "$assigned will have this value"
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.basic.extends"
- >extends</A
- ></H3
- ><P
- >
A class can inherit methods and members of another class by using the
- extends keyword in the declaration. It is not possible to extend multiple
- classes, a class can only inherit one base class.
- </P
- ><P
- >
The inherited methods and members can be overrided, unless the parent
- class has defined a method as <A
- HREF="#language.oop5.final"
- >final</A
- >,
- by redeclaring them within the same name defined in the parent class.
- It is possible to access the overrided method or members by
- referencing them with <A
- HREF="#language.oop5.paamayim-nekudotayim"
- >parent::</A
- >
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5408"
- ></A
- ><P
- ><B
- >Example 19-4. Simple Class Inherintance</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ExtendClass extends SimpleClass
- {
- // Redefine the parent method
- function displayVar()
- {
- echo "Extending class\n";
- parent::displayVar();
- }
- }
-
- $extended = new ExtendClass();
- $extended->displayVar();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Extending class
- a default value</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.autoload"
- >Autoloading Objects</A
- ></H2
- ><P
- >
Many developers writing object-oriented applications create
- one PHP source file per-class definition. One of the biggest
- annoyances is having to write a long list of needed includes
- at the beginning of each script (one for each class).
- </P
- ><P
- >
In PHP 5, this is no longer necessary. You may define an
- __autoload function which is automatically
- called in case you are trying to use a class which hasn't been
- defined yet. By calling this function the scripting engine is given
- a last chance to load the class before PHP fails with an error.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Exceptions thrown in __autoload function cannot be catched in the
- <A
- HREF="#language.exceptions"
- >catch</A
- > block and result in fatal
- error.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5421"
- ></A
- ><P
- ><B
- >Example 19-5. Autoload example</B
- ></P
- ><P
- >
This example attempts to load the classes <VAR
- CLASS="literal"
- >MyClass1</VAR
- >
- and <VAR
- CLASS="literal"
- >MyClass2</VAR
- > from the files <TT
- CLASS="filename"
- >MyClass1.php</TT
- >
- and <TT
- CLASS="filename"
- >MyClass2.php</TT
- > respectively.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function __autoload($class_name) {
- require_once $class_name . '.php';
- }
-
- $obj = new MyClass1();
- $obj2 = new MyClass2();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.decon"
- >Constructors and Destructors</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.decon.constructor"
- >Constructor</A
- ></H3
- >void <B
- CLASS="methodname"
- >__construct</B
- > ( [mixed args [, ...]])<BR
- ></BR
- ><P
- >
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.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Parent constructors are not called implicitly if the child class defines
- a constructor. In order to run a parent constructor, a call to
- <B
- CLASS="function"
- >parent::__construct()</B
- > within the child constructor is
- required.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5445"
- ></A
- ><P
- ><B
- >Example 19-6. using new unified constructors</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
For backwards compatibility, if PHP 5 cannot find a
- <B
- CLASS="function"
- >__construct()</B
- > 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
- <B
- CLASS="function"
- >__construct()</B
- > which was used for different semantics.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.decon.destructor"
- >Destructor</A
- ></H3
- >void <B
- CLASS="methodname"
- >__destruct</B
- > ( void )<BR
- ></BR
- ><P
- >
PHP 5 introduces a destructor concept similar to that of other
- object-oriented languages, such as C++. The destructor method will be
- called as soon as all references to a particular object are removed or when
- the object is explicitly destroyed.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5458"
- ></A
- ><P
- ><B
- >Example 19-7. Destructor Example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyDestructableClass {
- function __construct() {
- print "In constructor\n";
- $this->name = "MyDestructableClass";
- }
-
- function __destruct() {
- print "Destroying " . $this->name . "\n";
- }
- }
-
- $obj = new MyDestructableClass();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
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 <B
- CLASS="function"
- >parent::__destruct()</B
- > in the destructor
- body.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.visibility"
- >Visibility</A
- ></H2
- ><P
- >
The visibility of a property or method can be defined by prefixing the
- declaration with the keywords: public, protected or private. Public
- declared items can be accessed everywhere. Protected limits access to
- inherited classes (and to the class that defines the item). Private limits
- visibility only to the class that defines the item.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.visiblity-members"
- >Members Visibility</A
- ></H3
- ><P
- >
Class members must be defined with public, private, or protected.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5470"
- ></A
- ><P
- ><B
- >Example 19-8. Member declaration</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /**
- * Define MyClass
- */
- class MyClass
- {
- public $public = 'Public';
- protected $protected = 'Protected';
- private $private = 'Private';
-
- function printHello()
- {
- echo $this->public;
- echo $this->protected;
- echo $this->private;
- }
- }
-
- $obj = new MyClass();
- echo $obj->public; // Works
- echo $obj->protected; // Fatal Error
- echo $obj->private; // Fatal Error
- $obj->printHello(); // Shows Public, Protected and Private
-
-
- /**
- * Define MyClass2
- */
- class MyClass2 extends MyClass
- {
- // We can redeclare the public and protected method, but not private
- protected $protected = 'Protected2';
-
- function printHello()
- {
- echo $this->public;
- echo $this->protected;
- echo $this->private;
- }
- }
-
- $obj2 = new MyClass2();
- echo $obj->public; // Works
- echo $obj2->private; // Undefined
- echo $obj2->protected; // Fatal Error
- $obj2->printHello(); // Shows Public, Protected2, not Private
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The PHP 4 method of declaring a variable with the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >var</I
- ></SPAN
- > keyword is no longer valid
- for PHP 5 objects. For compatibility a variable declared
- in php will be assumed with public visibility, and a
- <TT
- CLASS="constant"
- ><B
- >E_STRICT</B
- ></TT
- > warning will be issued.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.visiblity-methods"
- >Method Visibility</A
- ></H3
- ><P
- >
Class methods must be defined with public, private, or protected. Methods
- without any declaration are defined as public.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5481"
- ></A
- ><P
- ><B
- >Example 19-9. Method Declaration</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /**
- * Define MyClass
- */
- class MyClass
- {
- // Contructors must be public
- public function __construct() { }
-
- // Declare a public method
- public function MyPublic() { }
-
- // Declare a protected method
- protected function MyProtected() { }
-
- // Declare a private method
- private function MyPrivate() { }
-
- // This is public
- function Foo()
- {
- $this->MyPublic();
- $this->MyProtected();
- $this->MyPrivate();
- }
- }
-
- $myclass = new MyClass;
- $myclass->MyPublic(); // Works
- $myclass->MyProtected(); // Fatal Error
- $myclass->MyPrivate(); // Fatal Error
- $myclass->Foo(); // Public, Protected and Private work
-
-
- /**
- * Define MyClass2
- */
- class MyClass2 extends MyClass
- {
- // This is public
- function Foo2()
- {
- $this->MyPublic();
- $this->MyProtected();
- $this->MyPrivate(); // Fatal Error
- }
- }
-
- $myclass2 = new MyClass2;
- $myclass2->MyPublic(); // Works
- $myclass2->Foo2(); // Public and Protected work, not Private
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.paamayim-nekudotayim"
- >Scope Resolution Operator (::)</A
- ></H2
- ><P
- >
The Scope Resolution Operator (also called Paamayim Nekudotayim) or in
- simpler terms, the double colon, is a token that allows access to
- <A
- HREF="#language.oop5.static"
- >static</A
- >,
- <A
- HREF="#language.oop5.constants"
- >constant</A
- >, and overridden
- members or methods of a class.
- </P
- ><P
- >
When referencing these items from outside the class definition, use
- the name of the class.
- </P
- ><P
- >
Paamayim Nekudotayim would, at first, seem like a strange choice for
- naming a double-colon. However, while writing the Zend Engine 0.5
- (which powers PHP 3), that's what the Zend team decided to call it.
- It actually does mean double-colon - in Hebrew!
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5491"
- ></A
- ><P
- ><B
- >Example 19-10. :: from outside the class definition</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyClass {
- const CONST_VALUE = 'A constant value';
- }
-
- echo MyClass::CONST_VALUE;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Two special keywords <VAR
- CLASS="varname"
- >self</VAR
- > and <VAR
- CLASS="varname"
- >parent</VAR
- >
- are used to access members or methods from inside the class definition.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5497"
- ></A
- ><P
- ><B
- >Example 19-11. :: from inside the class definition</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class OtherClass extends MyClass
- {
- public static $my_static = 'static var';
-
- public static function doubleColon() {
- echo parent::CONST_VALUE . "\n";
- echo self::$my_static . "\n";
- }
- }
-
- OtherClass::doubleColon();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
When an extending class overrides the parents definition of a method,
- PHP will not call the parent's method. It's up to the extended class
- on whether or not the parent's method is called. This also applies to <A
- HREF="#language.oop5.decon"
- >Constructors and Destructors</A
- >, <A
- HREF="#language.oop5.overloading"
- >Overloading</A
- >, and <A
- HREF="#language.oop5.magic"
- >Magic</A
- > method definitions.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5504"
- ></A
- ><P
- ><B
- >Example 19-12. Calling a parent's method</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyClass
- {
- protected function myFunc() {
- echo "MyClass::myFunc()\n";
- }
- }
-
- class OtherClass extends MyClass
- {
- // Override parent's definition
- public function myFunc()
- {
- // But still call the parent function
- parent::myFunc();
- echo "OtherClass::myFunc()\n";
- }
- }
-
- $class = new OtherClass();
- $class->myFunc();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.static"
- >Static Keyword</A
- ></H2
- ><P
- >
Declaring class members or methods as static, makes them callable
- from outside the object context. A member or method declared
- with static can not be accessed with a variable that is an instance
- of the object and cannot be re-defined in an extending class.
- </P
- ><P
- >
The static declaration must be after the visibility declaration. For
- compatibility with PHP 4, if no <A
- HREF="#language.oop5.visibility"
- >visibility</A
- >
- declaration is used, then the member or method will be treated
- as if it was declared as <VAR
- CLASS="literal"
- >public static</VAR
- >.
- </P
- ><P
- >
Because static methods are callable without an instance of
- the object created, the pseudo variable <VAR
- CLASS="varname"
- >$this</VAR
- > is
- not available inside the method declared as static.
- </P
- ><P
- >
In fact <VAR
- CLASS="literal"
- >static</VAR
- > method calls are resolved at compile
- time. When using an explicit class name the method is already identified
- completley and no inheritance rules apply. If the call is done by
- <VAR
- CLASS="literal"
- >self</VAR
- > then <VAR
- CLASS="literal"
- >self</VAR
- > is translated to
- the current class, that is the class the code belongs to. Here also no
- inheritance rules apply.
- </P
- ><P
- >
Static properties cannot be accessed through the object using the arrow
- operator ->.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5520"
- ></A
- ><P
- ><B
- >Example 19-13. Static member example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Foo
- {
- public static $my_static = 'foo';
-
- public function staticValue() {
- return self::$my_static;
- }
- }
-
- class Bar extends Foo
- {
- public function fooStatic() {
- return parent::$my_static;
- }
- }
-
-
- print Foo::$my_static . "\n";
-
- $foo = new Foo();
- print $foo->staticValue() . "\n";
- print $foo->my_static . "\n"; // Undefined "Property" my_static
-
- // $foo::my_static is not possible
-
- print Bar::$my_static . "\n";
- $bar = new Bar();
- print $bar->fooStatic() . "\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5523"
- ></A
- ><P
- ><B
- >Example 19-14. Static method example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Foo {
- public static function aStaticMethod() {
- // ...
- }
- }
-
- Foo::aStaticMethod();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.constants"
- >Object Constants</A
- ></H2
- ><P
- >
It is possible to define constant values on a per-class basis remaining the
- same and unchangeable. Constants differ from normal variables in that you
- don't use the <VAR
- CLASS="varname"
- >$</VAR
- > symbol to declare or use them. Like
- <A
- HREF="#language.oop5.static"
- >static</A
- > members, constant values
- can not be accessed from an instance of the object.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5531"
- ></A
- ><P
- ><B
- >Example 19-15. Defining and using a constant</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyClass
- {
- const constant = 'constant value';
-
- function showConstant() {
- echo self::constant . "\n";
- }
- }
-
- echo MyClass::constant . "\n";
-
- $class = new MyClass();
- $class->showConstant();
- // echo $class::constant; is not allowed
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.abstract"
- >Object Abstraction</A
- ></H2
- ><P
- >
PHP 5 introduces abstract classes and methods. It is not allowed to create
- an instance of a class that has been defined as abstract. Any class that
- contains at least one abstract method must also be abstract. Methods
- defined as abstract simply declare the method's signature they cannot
- define the implementation.
- </P
- ><P
- >
The class that implements the abstract method must define with the same
- <A
- HREF="#language.oop5.visibility"
- >visibillity</A
- > or weaker. If the
- abstract method is defined as protected, the function implementation must be
- defined as either protected or public.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5539"
- ></A
- ><P
- ><B
- >Example 19-16. Abstract class example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- abstract class AbstractClass
- {
- // Force Extending class to define this method
- abstract protected function getValue();
-
- // Common method
- public function printOut() {
- print $this->getValue();
- }
- }
-
- class ConcreteClass1 extends AbstractClass
- {
- protected function getValue() {
- return "ConcreteClass1";
- }
- }
-
- class ConcreteClass2 extends AbstractClass
- {
- protected function getValue() {
- return "ConcreteClass2";
- }
-
- }
-
- $class1 = new ConcreteClass1;
- $class1->printOut();
-
- $class2 = new ConcreteClass2;
- $class2->printOut();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Old code that has no user-defined classes or functions named
- 'abstract' should run without modifications.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.interfaces"
- >Object Interfaces</A
- ></H2
- ><P
- >
Object interfaces allow you to create code which specifies which methods a
- class must implement, without having to define how these methods are
- handled.
- </P
- ><P
- >
Interfaces are defined using the interface keyword, in the same way as a
- standard class, but without any of the methods having their contents
- defined. Classes which implement an interface should do so using the
- implements keyword, and must have definitions for all the methods listed
- in the interface. Classes may implement more than one interface if desired
- by listing each interface split by a comma.
- </P
- ><P
- >
All methods declared in an interface must be public, this is the nature of an
- interface.
- </P
- ><P
- >
Stating that a class implements an interface, and then not implementing all
- the methods in the interface will result in a fatal error telling you which
- methods have not been implemented.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5549"
- ></A
- ><P
- ><B
- >Example 19-17. Interface example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Declare the interface 'iTemplate'
- interface iTemplate
- {
- public function setVariable($name, $var);
- public function getHtml($template);
- }
-
- // Implement the interface
- // This will work
- class Template implements iTemplate
- {
- private $vars = array();
-
- public function setVariable($name, $var)
- {
- $this->vars[$name] = $var;
- }
-
- public function getHtml($template)
- {
- foreach($this->vars as $name => $value) {
- $template = str_replace('{' . $name . '}', $value, $template);
- }
-
- return $template;
- }
- }
-
- // This will not work
- // Fatal error: Class BadTemplate contains 1 abstract methods
- // and must therefore be declared abstract (iTemplate::getHtml)
- class BadTemplate implements iTemplate
- {
- private $vars = array();
-
- public function setVariable($name, $var)
- {
- $this->vars[$name] = $var;
- }
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.overloading"
- >Overloading</A
- ></H2
- ><P
- >
Both method calls and member accesses can be overloaded via the
- __call, __get and __set methods. These methods will only be
- triggered when your object or inherited object doesn't contain the
- member or method you're trying to access.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.overloading.members"
- >Member overloading</A
- ></H3
- >void <B
- CLASS="methodname"
- >__set</B
- > ( string name, mixed value)<BR
- ></BR
- >mixed <B
- CLASS="methodname"
- >__get</B
- > ( mixed name)<BR
- ></BR
- ><P
- >
Class members can be overloaded to run custom code defined in your class
- by defining these specially named methods. The <VAR
- CLASS="varname"
- >$name</VAR
- >
- parameter used is the name of the variable that should be set or retrieved.
- The __set() method's <VAR
- CLASS="varname"
- >$value</VAR
- > parameter specifies the
- value that the object should set set the <VAR
- CLASS="varname"
- >$name</VAR
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5576"
- ></A
- ><P
- ><B
- >Example 19-18. overloading with __get and __set example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Setter
- {
- public $n;
- private $x = array("a" => 1, "b" => 2, "c" => 3);
-
- function __get($nm)
- {
- print "Getting [$nm]\n";
-
- if (isset($this->x[$nm])) {
- $r = $this->x[$nm];
- print "Returning: $r\n";
- return $r;
- } else {
- echo "Nothing!\n";
- }
- }
-
- function __set($nm, $val)
- {
- print "Setting [$nm] to $val\n";
-
- if (isset($this->x[$nm])) {
- $this->x[$nm] = $val;
- echo "OK!\n";
- } else {
- echo "Not OK!\n";
- }
- }
- }
-
- $foo = new Setter();
- $foo->n = 1;
- $foo->a = 100;
- $foo->a++;
- $foo->z++;
- var_dump($foo);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Setting [a] to 100
- OK!
- Getting [a]
- Returning: 100
- Setting [a] to 101
- OK!
- Getting [z]
- Nothing!
- Setting [z] to 1
- Not OK!
- object(Setter)#1 (2) {
- ["n"]=>
- int(1)
- ["x:private"]=>
- array(3) {
- ["a"]=>
- int(101)
- ["b"]=>
- int(2)
- ["c"]=>
- int(3)
- }
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.overloading.methods"
- >Method overloading</A
- ></H3
- >mixed <B
- CLASS="methodname"
- >__call</B
- > ( string name, array arguments)<BR
- ></BR
- ><P
- >
Class methods can be overloaded to run custom code defined in your class
- by defining this specially named method. The <VAR
- CLASS="varname"
- >$name</VAR
- >
- parameter used is the name as the function name that was requested
- to be used. The arguments that were passed in the function will be
- defined as an array in the <VAR
- CLASS="varname"
- >$arguments</VAR
- > parameter.
- The value returned from the __call() method will be returned to the
- caller of the method.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5595"
- ></A
- ><P
- ><B
- >Example 19-19. overloading with __call example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Caller
- {
- private $x = array(1, 2, 3);
-
- function __call($m, $a)
- {
- print "Method $m called:\n";
- var_dump($a);
- return $this->x;
- }
- }
-
- $foo = new Caller();
- $a = $foo->test(1, "2", 3.4, true);
- var_dump($a);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Will Output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Method test called:
- array(4) {
- [0]=>
- int(1)
- [1]=>
- string(1) "2"
- [2]=>
- float(3.4)
- [3]=>
- bool(true)
- }
- array(3) {
- [0]=>
- int(1)
- [1]=>
- int(2)
- [2]=>
- int(3)
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.iterations"
- >Object Iteration</A
- ></H2
- ><P
- >
- PHP 5 provides a way for objects to be defined so it is possible to iterate
- through a list of items, with, for example a <A
- HREF="#control-structures.foreach"
- >foreach</A
- > statement. By default,
- all <A
- HREF="#language.oop5.visibility"
- >visible</A
- > properties will be used
- for the iteration.
-
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5605"
- ></A
- ><P
- ><B
- >Example 19-20. Simple Object Iteration</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyClass
- {
- public $var1 = 'value 1';
- public $var2 = 'value 2';
- public $var3 = 'value 3';
-
- protected $protected = 'protected var';
- private $private = 'private var';
-
- function iterateVisible() {
- echo "MyClass::iterateVisible:\n";
- foreach($this as $key => $value) {
- print "$key => $value\n";
- }
- }
- }
-
- $class = new MyClass();
-
- foreach($class as $key => $value) {
- print "$key => $value\n";
- }
- echo "\n";
-
-
- $class->iterateVisible();
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >var1 => value 1
- var2 => value 2
- var3 => value 3
-
- MyClass::iterateVisible:
- var1 => value 1
- var2 => value 2
- var3 => value 3
- protected => protected var
- private => private var</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
As the output shows, the <A
- HREF="#control-structures.foreach"
- >foreach</A
- > iterated through all
- <A
- HREF="#language.oop5.visibility"
- >visible</A
- > variables that can be
- accessed. To take it a step further you can <VAR
- CLASS="varname"
- >implement</VAR
- > one
- of PHP 5's internal <A
- HREF="#language.oop5.interfaces"
- >interface</A
- > named
- <VAR
- CLASS="varname"
- >Iterator</VAR
- >. This allows the object to decide what and how
- the object will be iterated.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5616"
- ></A
- ><P
- ><B
- >Example 19-21. Object Iteration implementing Iterator</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyIterator implements Iterator
- {
- private $var = array();
-
- public function __construct($array)
- {
- if (is_array($array)) {
- $this->var = $array;
- }
- }
-
- public function rewind() {
- echo "rewinding\n";
- reset($this->var);
- }
-
- public function current() {
- $var = current($this->var);
- echo "current: $var\n";
- return $var;
- }
-
- public function key() {
- $var = key($this->var);
- echo "key: $var\n";
- return $var;
- }
-
- public function next() {
- $var = next($this->var);
- echo "next: $var\n";
- return $var;
- }
-
- public function valid() {
- $var = $this->current() !== false;
- echo "valid: {$var}\n";
- return $var;
- }
- }
-
- $values = array(1,2,3);
- $it = new MyIterator($values);
-
- foreach ($it as $a => $b) {
- print "$a: $b\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >rewinding
- current: 1
- valid: 1
- current: 1
- key: 0
- 0: 1
- next: 2
- current: 2
- valid: 1
- current: 2
- key: 1
- 1: 2
- next: 3
- current: 3
- valid: 1
- current: 3
- key: 2
- 2: 3
- next:
- current:
- valid:</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
You can also define your class so that it doesn't have to define
- all the <VAR
- CLASS="varname"
- >Iterator</VAR
- > functions by simply implementing
- the PHP 5 <VAR
- CLASS="varname"
- >IteratorAggregate</VAR
- > interface.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5624"
- ></A
- ><P
- ><B
- >Example 19-22. Object Iteration implementing IteratorAggregate</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class MyCollection implements IteratorAggregate
- {
- private $items = array();
- private $count = 0;
-
- // Required definition of interface IteratorAggregate
- public function getIterator() {
- return new MyIterator($this->items);
- }
-
- public function add($value) {
- $this->items[$this->count++] = $value;
- }
- }
-
- $coll = new MyCollection();
- $coll->add('value 1');
- $coll->add('value 2');
- $coll->add('value 3');
-
- foreach ($coll as $key => $val) {
- echo "key/value: [$key -> $val]\n\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Will output:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >rewinding
- current: value 1
- valid: 1
- current: value 1
- key: 0
- key/value: [0 -> value 1]
-
- next: value 2
- current: value 2
- valid: 1
- current: value 2
- key: 1
- key/value: [1 -> value 2]
-
- next: value 3
- current: value 3
- valid: 1
- current: value 3
- key: 2
- key/value: [2 -> value 3]
-
- next:
- current:
- valid:</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For more examples of iterators, see the
- <A
- HREF="#ref.spl"
- >SPL Extension</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.patterns"
- >Patterns</A
- ></H2
- ><P
- >
Patterns are ways to describe best practices and good designs.
- They show a flexible solution to common programming problems.
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.patterns.factory"
- >Factory</A
- ></H3
- ><P
- >
The Factory pattern allows for the instantation of objects
- at runtime. It is called a Factory Pattern since it is
- responsible for "manufacturing" an object.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5638"
- ></A
- ><P
- ><B
- >Example 19-23. Factory Method</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Example
- {
- // The factory method
- function &factory($type)
- {
- if (include_once 'Drivers/' . $type . '.php') {
- $classname = 'Driver_' . $type;
- return new $classname;
- } else {
- throw new Exception ('Driver not found');
- }
- }
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Defining this method in a class allows drivers to be loaded on the
- fly. If the <VAR
- CLASS="literal"
- >Example</VAR
- > class was a database
- abstraction class, loading a <VAR
- CLASS="literal"
- >MySQL</VAR
- > and
- <VAR
- CLASS="literal"
- >SQLite</VAR
- > driver could be done as follows:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Load a MySQL Driver
- $mysql = Example::factory('MySQL');
-
- // Load a SQLite Driver
- $sqlite = Example::factory('SQLite');
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.patterns.singleton"
- >Singleton</A
- ></H3
- ><P
- >
The Singleton pattern applies to situations in which
- there needs to be a single instance of a class.
- The most common example of this is a database connection.
- Implementing this pattern allows a programmer to make this
- single instance easily accessible by many other objects.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5649"
- ></A
- ><P
- ><B
- >Example 19-24. Singleton Function</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Example
- {
- // Hold an instance of the class
- static private $instance;
-
- // A private constructor
- private function __construct()
- {
- echo 'I am constructed';
- }
-
- // The singleton method
- static public function singleton()
- {
- if (!isset(self::$instance)) {
- $c = __CLASS__;
- self::$instance = new $c;
- }
-
- return self::$instance;
- }
-
- // Example method
- public function bark()
- {
- echo 'Woof!';
- }
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This allows a single instance of the <VAR
- CLASS="literal"
- >Example</VAR
- >
- class to be retrieved.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // This would fail because the constructor is private
- $test = new Example;
-
- // This will always retrieve a single instance of the class
- $test = Example::singleton();
- $test->bark();
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.magic"
- >Magic Methods</A
- ></H2
- ><P
- >
The function names
- <VAR
- CLASS="literal"
- >__construct</VAR
- >,
- <VAR
- CLASS="literal"
- >__destruct</VAR
- >
- (see <A
- HREF="#language.oop5.decon"
- >Constructors and Destructors</A
- >),
- <VAR
- CLASS="literal"
- >__call</VAR
- >,
- <VAR
- CLASS="literal"
- >__get</VAR
- >,
- <VAR
- CLASS="literal"
- >__set</VAR
- >
- (see <A
- HREF="#language.oop5.overloading"
- >Overloading</A
- >),
- <VAR
- CLASS="literal"
- >__sleep</VAR
- >,
- <VAR
- CLASS="literal"
- >__wakeup</VAR
- >, and
- <VAR
- CLASS="literal"
- >__toString</VAR
- >
- are magical in PHP classes. You
- cannot have functions with these names in any of your
- classes unless you want the magic functionality associated
- with them.
- </P
- ><DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
PHP reserves all function names starting with __ as magical.
- It is recommended that you do not use function names with
- __ in PHP unless you want some documented magic functionality.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.magic.sleep"
- ><VAR
- CLASS="literal"
- >__sleep</VAR
- > and <VAR
- CLASS="literal"
- >__wakeup</VAR
- ></A
- ></H3
- ><P
- >
<A
- HREF="#function.serialize"
- ><B
- CLASS="function"
- >serialize()</B
- ></A
- > checks if your class has a function with
- the magic name <VAR
- CLASS="literal"
- >__sleep</VAR
- >. If so, that function is
- being run prior to any serialization. It can clean up the object
- and is supposed to return an array with the names of all variables
- of that object that should be serialized.
- </P
- ><P
- >
The intended use of <VAR
- CLASS="literal"
- >__sleep</VAR
- > is to close any
- database connections that object may have, committing pending
- data or perform similar cleanup tasks. Also, the function is
- useful if you have very large objects which need not be
- saved completely.
- </P
- ><P
- >
Conversely, <A
- HREF="#function.unserialize"
- ><B
- CLASS="function"
- >unserialize()</B
- ></A
- > checks for the
- presence of a function with the magic name
- <VAR
- CLASS="literal"
- >__wakeup</VAR
- >. If present, this function can
- reconstruct any resources that object may have.
- </P
- ><P
- >
The intended use of <VAR
- CLASS="literal"
- >__wakeup</VAR
- > is to
- reestablish any database connections that may have been lost
- during serialization and perform other reinitialization
- tasks.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.magic.tostring"
- ><VAR
- CLASS="literal"
- >__toString</VAR
- ></A
- ></H3
- ><P
- >
The <VAR
- CLASS="literal"
- >__toString</VAR
- > method allows a class to decide
- how it will react when it is converted to a string.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5689"
- ></A
- ><P
- ><B
- >Example 19-25. Simple example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Declare a simple class
- class TestClass
- {
- public $foo;
-
- public function __construct($foo) {
- $this->foo = $foo;
- }
-
- public function __toString() {
- return $this->foo;
- }
- }
-
- $class = new TestClass('Hello');
- echo $class;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Hello</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
It is worth noting that the <VAR
- CLASS="literal"
- >__toString</VAR
- > method
- will only be called when it is directly combined with
- <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- > or <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5698"
- ></A
- ><P
- ><B
- >Example 19-26. Cases where <VAR
- CLASS="literal"
- >__toString</VAR
- > is called</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // __toString called
- echo $class;
-
- // __toString called (still a normal parameter for echo)
- echo 'text', $class;
-
- // __toString not called (concatenation operator used first)
- echo 'text' . $class;
-
- // __toString not called (cast to string first)
- echo (string) $class;
-
- // __toString not called (cast to string first)
- echo "text $class";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.final"
- >Final Keyword</A
- ></H2
- ><P
- >
PHP 5 introduces the final keyword, which prevents child classes from
- overriding a method by prefixing the definition with final. If the class
- itself is being defined final then it cannot be extended.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5705"
- ></A
- ><P
- ><B
- >Example 19-27. Final methods example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class BaseClass {
- public function test() {
- echo "BaseClass::test() called\n";
- }
-
- final public function moreTesting() {
- echo "BaseClass::moreTesting() called\n";
- }
- }
-
- class ChildClass extends BaseClass {
- public function moreTesting() {
- echo "ChildClass::moreTesting() called\n";
- }
- }
- // Results in Fatal error: Cannot override final method BaseClass::moreTesting()
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5708"
- ></A
- ><P
- ><B
- >Example 19-28. Final class example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- final class BaseClass {
- public function test() {
- echo "BaseClass::test() called\n";
- }
-
- // Here it doesn't matter if you specify the function as final or not
- final public function moreTesting() {
- echo "BaseClass::moreTesting() called\n";
- }
- }
-
- class ChildClass extends BaseClass {
- }
- // Results in Fatal error: Class ChildClass may not inherit from final class (BaseClass)
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.cloning"
- >Object cloning</A
- ></H2
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5715"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >$copy_of_object = clone $object;</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
When an object is cloned, PHP 5 will perform a shallow copy of all of the
- object's properties. Any properties that are references to other variables,
- will remain references. If a __clone() method is defined, then the newly
- created object's __clone() method will be called, to allow any necessary
- properties that need to be changed.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5718"
- ></A
- ><P
- ><B
- >Example 19-29. Cloning an object</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class SubObject
- {
- static $instances = 0;
- public $instance;
-
- public function __construct() {
- $this->instance = ++self::$instances;
- }
-
- public function __clone() {
- $this->instance = ++self::$instances;
- }
- }
-
- class MyCloneable
- {
- public $object1;
- public $object2;
-
- function __clone()
- {
- // Force a copy of this->object, otherwise
- // it will point to same object.
- $this->object1 = clone($this->object1);
- }
- }
-
- $obj = new MyCloneable();
-
- $obj->object1 = new SubObject();
- $obj->object2 = new SubObject();
-
- $obj2 = clone $obj;
-
-
- print("Original Object:\n");
- print_r($obj);
-
- print("Cloned Object:\n");
- print_r($obj2);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Original Object:
- MyCloneable Object
- (
- [object1] => SubObject Object
- (
- [instance] => 1
- )
-
- [object2] => SubObject Object
- (
- [instance] => 2
- )
-
- )
- Cloned Object:
- MyCloneable Object
- (
- [object1] => SubObject Object
- (
- [instance] => 3
- )
-
- [object2] => SubObject Object
- (
- [instance] => 2
- )
-
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.object-comparison"
- >Comparing objects</A
- ></H2
- ><P
- >
In PHP 5, object comparison is 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).
- </P
- ><P
- >
When using the comparison operator (<VAR
- CLASS="literal"
- >==</VAR
- >),
- 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.
- </P
- ><P
- >
On the other hand, when using the identity operator (<VAR
- CLASS="literal"
- >===</VAR
- >),
- object variables are identical if and only if they refer to the same
- instance of the same class.
- </P
- ><P
- >
An example will clarify these rules.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5731"
- ></A
- ><P
- ><B
- >Example 19-30. Example of object comparison in PHP 5</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- {
- public $flag;
-
- function Flag($flag = true) {
- $this->flag = $flag;
- }
- }
-
- class OtherFlag
- {
- public $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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- This example will output:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.reflection"
- >Reflection</A
- ></H2
- ><DIV
- CLASS="sect2"
- ><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.introduction"
- >Introduction</A
- ></H3
- ><P
- >
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.
- </P
- ><P
- >
The reflection API is an object-oriented extension to the Zend Engine,
- consisting of the following classes:
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5741"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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 { }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For details on these classes, have a look at the next chapters.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
If we were to execute the code in the example below:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5746"
- ></A
- ><P
- ><B
- >Example 19-31. Basic usage of the reflection API</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- Reflection::export(new ReflectionClass('Exception'));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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> public method __construct ] {
-
- - Parameters [2] {
- Parameter #0 [ <required> $message ]
- Parameter #1 [ <required> $code ]
- }
- }
-
- 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 ] {
- }
- }
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionfunction"
- ><B
- CLASS="classname"
- >ReflectionFunction</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionFunction</B
- > class lets you
- reverse-engineer functions.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5756"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionFunction implements Reflector
- {
- final private __clone()
- 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 mixed invokeArgs(array args)
- public bool returnsReference()
- public ReflectionParameter[] getParameters()
- public int getNumberOfParameters()
- public int getNumberOfRequiredParameters()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <B
- CLASS="function"
- >invokeArgs()</B
- > was added in PHP 5.1.0.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
To introspect a function, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionFunction</B
- > class. You can then call
- any of the above methods on this instance.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5763"
- ></A
- ><P
- ><B
- >Example 19-32. Using the <B
- CLASS="classname"
- >ReflectionFunction</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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');
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The method <B
- CLASS="function"
- >invoke()</B
- > accepts a variable number of
- arguments which are passed to the function just as in
- <A
- HREF="#function.call-user-func"
- ><B
- CLASS="function"
- >call_user_func()</B
- ></A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionparameter"
- ><B
- CLASS="classname"
- >ReflectionParameter</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionParameter</B
- > class retrieves
- information about a function's or method's parameters.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5776"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionParameter implements Reflector
- {
- final private __clone()
- public object __construct(string name)
- public string __toString()
- public static string export()
- public string getName()
- public bool isPassedByReference()
- public ReflectionClass getClass()
- public bool allowsNull()
- public bool isOptional()
- public bool isDefaultValueAvailable()
- public mixed getDefaultValue()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <B
- CLASS="function"
- >getDefaultValue()</B
- >,
- <B
- CLASS="function"
- >isDefaultValueAvailable()</B
- >,
- <B
- CLASS="function"
- >isOptional()</B
- > were added in PHP 5.1.0.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
To introspect function parameters, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionFunction</B
- > or
- <B
- CLASS="classname"
- >ReflectionMethod</B
- > classes and then use their
- <B
- CLASS="function"
- >getParameters()</B
- > method to retrieve an array of parameters.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5787"
- ></A
- ><P
- ><B
- >Example 19-33. Using the <B
- CLASS="classname"
- >ReflectionParameter</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo($a, $b, $c) { }
- function bar(Exception $a, &$b, $c) { }
- function baz(ReflectionFunction $a, $b = 1, $c = null) { }
- 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".
- " Is optional?: %s\n".
- "}\n",
- $i,
- $param->getName(),
- var_export($param->getClass(), 1),
- var_export($param->allowsNull(), 1),
- var_export($param->isPassedByReference(), 1),
- $param->isOptional() ? 'yes' : 'no'
- );
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionclass"
- ><B
- CLASS="classname"
- >ReflectionClass</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionClass</B
- > class lets
- you reverse-engineer classes.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5796"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionClass implements Reflector
- {
- final private __clone()
- public object __construct(string name)
- public string __toString()
- public static string export()
- public string getName()
- public bool isInternal()
- public bool isUserDefined()
- public bool isInstantiable()
- public bool hasMethod(string name)
- 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 ReflectionClass[] getInterfaces()
- public bool isInterface()
- public bool isAbstract()
- public bool isFinal()
- public int getModifiers()
- public bool isInstance(stdclass object)
- public stdclass newInstance(mixed* args)
- public ReflectionClass getParentClass()
- public bool isSubclassOf(ReflectionClass class)
- public array getStaticProperties()
- public array getDefaultProperties()
- public bool isIterateable()
- public bool implementsInterface(string name)
- public ReflectionExtension getExtension()
- public string getExtensionName()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <B
- CLASS="function"
- >hasMethod()</B
- > was added in PHP 5.1.0.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
To introspect a class, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionClass</B
- > class. You can then
- call any of the above methods on this instance.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5803"
- ></A
- ><P
- ><B
- >Example 19-34. Using the <B
- CLASS="classname"
- >ReflectionClass</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The method <B
- CLASS="function"
- >newInstance()</B
- > accepts a variable number of
- arguments which are passed to the function just as in
- <A
- HREF="#function.call-user-func"
- ><B
- CLASS="function"
- >call_user_func()</B
- ></A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <VAR
- CLASS="literal"
- >$class = new ReflectionClass('Foo'); $class->isInstance($arg)</VAR
- >
- is equivalent to <VAR
- CLASS="literal"
- >$arg instanceof Foo</VAR
- > or
- <VAR
- CLASS="literal"
- >is_a($arg, 'Foo')</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionmethod"
- ><B
- CLASS="classname"
- >ReflectionMethod</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionMethod</B
- > class lets you
- reverse-engineer class methods.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5821"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionMethod extends ReflectionFunction
- {
- public __construct(mixed class, string name)
- public string __toString()
- public static string export()
- public mixed invoke(stdclass object, mixed* args)
- public moxed invokeArgs(stdclass object, array args)
- public bool isFinal()
- public bool isAbstract()
- public bool isPublic()
- public bool isPrivate()
- public bool isProtected()
- public bool isStatic()
- public bool isConstructor()
- public bool isDestructor()
- public int getModifiers()
- public ReflectionClass getDeclaringClass()
-
- // Inherited from ReflectionFunction
- final private __clone()
- 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()
- public int getNumberOfParameters()
- public int getNumberOfRequiredParameters()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
To introspect a method, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionMethod</B
- > class. You can then call
- any of the above methods on this instance.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5825"
- ></A
- ><P
- ><B
- >Example 19-35. Using the <B
- CLASS="classname"
- >ReflectionMethod</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Counter
- {
- private static $c = 0;
-
- /**
- * Increment counter
- *
- * @final
- * @static
- * @access public
- * @return int
- */
- final public static function increment()
- {
- 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));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Trying to invoke private, protected or abstract methods will result
- in an exception being thrown from the <B
- CLASS="function"
- >invoke()</B
- >
- method.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- For static methods as seen above, you should pass NULL as the first
- argument to <B
- CLASS="function"
- >invoke()</B
- >. For non-static methods, pass
- an instance of the class.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionproperty"
- ><B
- CLASS="classname"
- >ReflectionProperty</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionProperty</B
- > class lets you
- reverse-engineer class properties.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5840"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionProperty implements Reflector
- {
- final private __clone()
- 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()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
To introspect a property, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionProperty</B
- > class. You can then
- call any of the above methods on this instance.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5844"
- ></A
- ><P
- ><B
- >Example 19-36. Using the <B
- CLASS="classname"
- >ReflectionProperty</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Trying to get or set private or protected class property's values
- will result in an exception being thrown.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.reflectionextension"
- ><B
- CLASS="classname"
- >ReflectionExtension</B
- ></A
- ></H3
- ><P
- >
The <B
- CLASS="classname"
- >ReflectionExtension</B
- > class lets you
- reverse-engineer extensions. You can retrieve all loaded extensions
- at runtime using the <A
- HREF="#function.get-loaded-extensions"
- ><B
- CLASS="function"
- >get_loaded_extensions()</B
- ></A
- >.
- </P
- ><DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5856"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class ReflectionExtension implements Reflector {
- final private __clone()
- 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()
- public ReflectionClass[] getClasses()
- public array getClassNames()
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- ><P
- >
To introspect an extension, you will first have to create an instance
- of the <B
- CLASS="classname"
- >ReflectionExtension</B
- > class. You can then call
- any of the above methods on this instance.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5860"
- ></A
- ><P
- ><B
- >Example 19-37. Using the <B
- CLASS="classname"
- >ReflectionExtension</B
- > class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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" .
- "Classes : [%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),
-
- sizeof($ext->getClassNames()),
- var_export($ext->getClassNames(), 1)
- );
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="language.oop5.reflection.extending"
- >Extending the reflection classes</A
- ></H3
- ><P
- >
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.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5867"
- ></A
- ><P
- ><B
- >Example 19-38. Extending the built-in classes</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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'));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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:
- <VAR
- CLASS="literal"
- >
Fatal error: Internal error: Failed to retrieve the reflection object
- </VAR
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.oop5.typehinting"
- >Type Hinting</A
- ></H2
- ><P
- >
PHP 5 introduces Type Hinting. Functions are now able to force parameters
- to be objects by specifying the name of the class in the function prototype.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5876"
- ></A
- ><P
- ><B
- >Example 19-39. Type Hinting example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // An example class
- class MyClass
- {
- /**
- * A test function
- *
- * First parameter must be an object of type OtherClass
- */
- public function test(OtherClass $otherclass) {
- echo $otherclass->var;
- }
- }
-
- // Another example class
- class OtherClass {
- public $var = 'Hello World';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Failing to satisfy the type hint results in a fatal error.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // An instance of each class
- $myclass = new MyClass;
- $otherclass = new OtherClass;
-
- // Fatal Error: Argument 1 must be an object of class OtherClass
- $myclass->test('hello');
-
- // Fatal Error: Argument 1 must be an instance of OtherClass
- $foo = new stdClass;
- $myclass->test($foo);
-
- // Fatal Error: Argument 1 must not be null
- $myclass->test(null);
-
- // Works: Prints Hello World
- $myclass->test($otherclass);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Type hinting also works with functions:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // An example class
- class MyClass {
- public $var = 'Hello World';
- }
-
- /**
- * A test function
- *
- * First parameter must be an object of type MyClass
- */
- function MyFunction (MyClass $foo) {
- echo $foo->var;
- }
-
- // Works
- $myclass = new MyClass;
- MyFunction($myclass);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Type Hints can only be of the <A
- HREF="#language.types.object"
- ><B
- CLASS="type"
- >object</B
- ></A
- > type. Traditional
- type hinting with <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >int</B
- ></A
- > and <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- > are not
- supported.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.exceptions"
- >Chapter 20. Exceptions</A
- ></H1
- ><P
- >
PHP 5 has an exception model similar to that of other programming languages.
- An exception can be thrown, try and caught within PHP. A Try block must
- include at least one catch block. Multiple catch blocks can be used to
- catch different classtypes; execution will continue after that last catch
- block defined in sequence. Exceptions can be thrown within catch blocks.
- </P
- ><P
- >
When an exception is thrown, code following the statement will not be
- executed and PHP will attempt to find the first matching catch block. If an
- exception is not caught a PHP Fatal Error will be issued with an Uncaught
- Exception message, unless there has been a handler defined with
- <A
- HREF="#function.set-exception-handler"
- ><B
- CLASS="function"
- >set_exception_handler()</B
- ></A
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5892"
- ></A
- ><P
- ><B
- >Example 20-1. Throwing an Exception</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- try {
- $error = 'Always throw this error';
- throw new Exception($error);
-
- // Code following an exception is not executed.
- echo 'Never executed';
-
- } catch (Exception $e) {
- echo 'Caught exception: ', $e->getMessage(), "\n";
- }
-
- // Continue execution
- echo 'Hello World';
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.exceptions.extending"
- >Extending Exceptions</A
- ></H2
- ><P
- >
A User defined Exception class can be defined by extending the built-in
- Exception class. The members and properties below, show what is accessible
- within the child class that derives from the built-in Exception class.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5898"
- ></A
- ><P
- ><B
- >Example 20-2. The Built in Exception class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- class Exception
- {
- protected $message = 'Unknown exception'; // exception message
- protected $code = 0; // user defined exception code
- protected $file; // source filename of exception
- protected $line; // source line of exception
-
- function __construct($message = null, $code = 0);
-
- final function getMessage(); // message of exception
- final function getCode(); // code of exception
- final function getFile(); // source filename
- final function getLine(); // source line
- final function getTrace(); // an array of the backtrace()
- final function getTraceAsString(); // formated string of trace
-
- /* Overrideable */
- function __toString(); // formated string for display
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
If a class extends the built-in Exception class and re-defines the <A
- HREF="#language.oop5.decon"
- >constructor</A
- >, it is highly recomended
- that it also call <A
- HREF="#language.oop5.paamayim-nekudotayim"
- >parent::__construct()</A
- >
- to ensure all available data has been properly assigned. The <A
- HREF="#language.oop5.magic"
- >__toString()</A
- > method can be overriden
- to provide a custom output when the object is presented as a string.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5905"
- ></A
- ><P
- ><B
- >Example 20-3. Extending the Exception class</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /**
- * Define a custom exception class
- */
- class MyException extends Exception
- {
- // Redefine the exception so message isn't optional
- public function __construct($message, $code = 0) {
- // some code
-
- // make sure everything is assigned properly
- parent::__construct($message, $code);
- }
-
- // custom string representation of object */
- public function __toString() {
- return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
- }
-
- public function customFunction() {
- echo "A Custom function for this type of exception\n";
- }
- }
-
-
- /**
- * Create a class to test the exception
- */
- class TestException
- {
- public $var;
-
- const THROW_NONE = 0;
- const THROW_CUSTOM = 1;
- const THROW_DEFAULT = 2;
-
- function __construct($avalue = self::THROW_NONE) {
-
- switch ($avalue) {
- case self::THROW_CUSTOM:
- // throw custom exception
- throw new MyException('1 is an invalid parameter', 5);
- break;
-
- case self::THROW_DEFAULT:
- // throw default one.
- throw new Exception('2 isnt allowed as a parameter', 6);
- break;
-
- default:
- // No exception, object will be created.
- $this->var = $avalue;
- break;
- }
- }
- }
-
-
- // Example 1
- try {
- $o = new TestException(TestException::THROW_CUSTOM);
- } catch (MyException $e) { // Will be caught
- echo "Caught my exception\n", $e;
- $e->customFunction();
- } catch (Exception $e) { // Skipped
- echo "Caught Default Exception\n", $e;
- }
-
- // Continue execution
- var_dump($o);
- echo "\n\n";
-
-
- // Example 2
- try {
- $o = new TestException(TestException::THROW_DEFAULT);
- } catch (MyException $e) { // Doesn't match this type
- echo "Caught my exception\n", $e;
- $e->customFunction();
- } catch (Exception $e) { // Will be caught
- echo "Caught Default Exception\n", $e;
- }
-
- // Continue execution
- var_dump($o);
- echo "\n\n";
-
-
- // Example 3
- try {
- $o = new TestException(TestException::THROW_CUSTOM);
- } catch (Exception $e) { // Will be caught
- echo "Default Exception caught\n", $e;
- }
-
- // Continue execution
- var_dump($o);
- echo "\n\n";
-
-
- // Example 4
- try {
- $o = new TestException();
- } catch (Exception $e) { // Skipped, no exception
- echo "Default Exception caught\n", $e;
- }
-
- // Continue execution
- var_dump($o);
- echo "\n\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="language.references"
- >Chapter 21. References Explained</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="language.references.whatare"
- >What References Are</A
- ></H2
- ><P
- >
- References in PHP are a means to access the same variable content
- by different names. They are not like C pointers, they are symbol
- table aliases. Note that in PHP, variable name and variable content
- are different, so the same content can have different names.
- The most close analogy is with Unix filenames and files -
- variable names are directory entries, while variable contents is
- the file itself. References can be thought of as hardlinking in
- Unix filesystem.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.whatdo"
- >What References Do</A
- ></H2
- ><P
- >
PHP references allow you to make two variables to refer to the
- same content. Meaning, when you do:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5916"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a =& $b;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- it means that <VAR
- CLASS="varname"
- >$a</VAR
- > and <VAR
- CLASS="varname"
- >$b</VAR
- >
- point to the same variable.
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <VAR
- CLASS="varname"
- >$a</VAR
- > and <VAR
- CLASS="varname"
- >$b</VAR
- > are completely
- equal here, that's not <VAR
- CLASS="varname"
- >$a</VAR
- > is pointing to
- <VAR
- CLASS="varname"
- >$b</VAR
- > or vice versa, that's
- <VAR
- CLASS="varname"
- >$a</VAR
- > and <VAR
- CLASS="varname"
- >$b</VAR
- > pointing to the
- same place.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If array with references is copied, its values are not dereferenced.
- This is valid also for arrays passed by value to functions.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The same syntax can be used with functions, that return references,
- and with <VAR
- CLASS="literal"
- >new</VAR
- > operator (in PHP 4.0.4 and later):
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5932"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $bar =& new fooclass();
- $foo =& find_var($bar);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Not using the <VAR
- CLASS="literal"
- >&</VAR
- > operator causes a copy of the
- object to be made. If you use <VAR
- CLASS="literal"
- >$this</VAR
- > in the class it
- will operate on the current instance of the class. The assignment without
- <VAR
- CLASS="literal"
- >&</VAR
- > will copy the instance (i.e. the object) and
- <VAR
- CLASS="literal"
- >$this</VAR
- > will operate on the copy, which is not always
- what is desired. Usually you want to have a single instance to work with,
- due to performance and memory consumption issues.
- </P
- ><P
- >
While you can use the <VAR
- CLASS="literal"
- >@</VAR
- > operator to
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >mute</I
- ></SPAN
- > any errors in the constructor when using it as
- <VAR
- CLASS="literal"
- >@new</VAR
- >, this does not work when using the
- <VAR
- CLASS="literal"
- >&new</VAR
- > statement. This is a limitation of the Zend
- Engine and will therefore result in a parser error.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
If you assign a reference to a variable declared <VAR
- CLASS="literal"
- >global</VAR
- >
- inside a function, the reference will be visible only inside the function.
- You can avoid this by using the <VAR
- CLASS="varname"
- >$GLOBALS</VAR
- > array.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5949"
- ></A
- ><P
- ><B
- >Example 21-1. Referencing global variables inside function</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $var1 = "Example variable";
- $var2 = "";
-
- function global_references($use_globals)
- {
- global $var1, $var2;
- if (!$use_globals) {
- $var2 =& $var1; // visible only inside the function
- } else {
- $GLOBALS["var2"] =& $var1; // visible also in global context
- }
- }
-
- global_references(false);
- echo "var2 is set to '$var2'\n"; // var2 is set to ''
- global_references(true);
- echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Think about <VAR
- CLASS="literal"
- >global $var;</VAR
- > as a shortcut to <VAR
- CLASS="literal"
- >$var
- =& $GLOBALS['var'];</VAR
- >. Thus assigning other reference
- to <VAR
- CLASS="literal"
- >$var</VAR
- > only changes the local variable's reference.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you assign a value to a variable with references in a <A
- HREF="#control-structures.foreach"
- >foreach</A
- > statement,
- the references are modified too.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5958"
- ></A
- ><P
- ><B
- >Example 21-2. References and foreach statement</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $ref = 0;
- $row =& $ref;
- foreach (array(1, 2, 3) as $row) {
- // do something
- }
- echo $ref; // 3 - last element of the iterated array
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
Complex arrays are sometimes rather copied than referenced. Thus following
- example will not work as expected.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN5963"
- ></A
- ><P
- ><B
- >Example 21-3. References with complex arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $top = array(
- 'A' => array(),
- 'B' => array(
- 'B_b' => array(),
- ),
- );
-
- $top['A']['parent'] = &$top;
- $top['B']['parent'] = &$top;
- $top['B']['B_b']['data'] = 'test';
- print_r($top['A']['parent']['B']['B_b']); // array()
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
The second thing references do is to pass variables
- by-reference. This is done by making a local variable in a function and
- a variable in the calling scope reference to the same content. Example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5967"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo(&$var)
- {
- $var++;
- }
-
- $a=5;
- foo($a);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- will make <VAR
- CLASS="varname"
- >$a</VAR
- > to be 6. This happens because in
- the function <VAR
- CLASS="varname"
- >foo</VAR
- > the variable
- <VAR
- CLASS="varname"
- >$var</VAR
- > refers to the same content as
- <VAR
- CLASS="varname"
- >$a</VAR
- >. See also more detailed explanations about <A
- HREF="#language.references.pass"
- >passing by reference</A
- >.
- </P
- ><P
- >
The third thing reference can do is <A
- HREF="#language.references.return"
- >return by reference</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.arent"
- >What References Are Not</A
- ></H2
- ><P
- >
As said before, references aren't pointers. That means, the
- following construct won't do what you expect:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5979"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo(&$var)
- {
- $var =& $GLOBALS["baz"];
- }
- foo($bar);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
What happens is that <VAR
- CLASS="varname"
- >$var</VAR
- > in
- <VAR
- CLASS="varname"
- >foo</VAR
- > will be bound with
- <VAR
- CLASS="varname"
- >$bar</VAR
- > in caller, but then it will be
- re-bound with <VAR
- CLASS="varname"
- >$GLOBALS["baz"]</VAR
- >. There's no way
- to bind <VAR
- CLASS="varname"
- >$bar</VAR
- > in the calling scope to something else
- using the reference mechanism, since <VAR
- CLASS="varname"
- >$bar</VAR
- > is not
- available in the function <VAR
- CLASS="varname"
- >foo</VAR
- > (it is represented by
- <VAR
- CLASS="varname"
- >$var</VAR
- >, but <VAR
- CLASS="varname"
- >$var</VAR
- > has only
- variable contents and not name-to-value binding in the calling
- symbol table).
- You can use <A
- HREF="#language.references.return"
- >returning
- references</A
- > to reference variables selected by the function.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.pass"
- >Passing by Reference</A
- ></H2
- ><P
- >
You can pass variable to function by reference, so that function could modify
- its arguments. The syntax is as follows:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN5995"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function foo(&$var)
- {
- $var++;
- }
-
- $a=5;
- foo($a);
- // $a is 6 here
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- Note that there's no reference sign on function call - only on
- function definition. Function definition alone is enough to
- correctly pass the argument by reference.
- </P
- ><P
- >
Following things can be passed by reference:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Variable, i.e. <VAR
- CLASS="literal"
- >foo($a)</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
New statement, i.e. <VAR
- CLASS="literal"
- >foo(new foobar())</VAR
- >
- </P
- ></LI
- ><LI
- ><P
- >
Reference, returned from a function, i.e.:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6007"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function &bar()
- {
- $a = 5;
- return $a;
- }
- foo(bar());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- See also explanations about <A
- HREF="#language.references.return"
- >returning by reference</A
- >.
- </P
- ></LI
- ></UL
- >
- </P
- ><P
- >
Any other expression should not be passed by reference, as the
- result is undefined. For example, the following examples of passing
- by reference are invalid:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6011"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function bar() // Note the missing &
- {
- $a = 5;
- return $a;
- }
- foo(bar());
-
- foo($a = 5); // Expression, not variable
- foo(5); // Constant, not variable
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- These requirements are for PHP 4.0.4 and later.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.return"
- >Returning References</A
- ></H2
- ><P
- >
Returning by-reference is useful when you want to use a function
- to find which variable a reference should be bound to. When
- returning references, use this syntax:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6016"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function &find_var($param)
- {
- /* ...code... */
- return $found_var;
- }
-
- $foo =& find_var($bar);
- $foo->x = 2;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- In this example, the property of the object returned by the
- <VAR
- CLASS="varname"
- >find_var</VAR
- > function would be set, not the
- copy, as it would be without using reference syntax.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Unlike parameter passing, here you have to use
- <VAR
- CLASS="literal"
- >&</VAR
- > in both places - to indicate that you
- return by-reference, not a copy as usual, and to indicate that
- reference binding, rather than usual assignment, should be done
- for <VAR
- CLASS="varname"
- >$foo</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.unset"
- >Unsetting References</A
- ></H2
- ><P
- >
When you unset the reference, you just break the binding between
- variable name and variable content. This does not mean that
- variable content will be destroyed. For example:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6026"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = 1;
- $b =& $a;
- unset($a);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- won't unset <VAR
- CLASS="varname"
- >$b</VAR
- >, just <VAR
- CLASS="varname"
- >$a</VAR
- >.
- </P
- ><P
- >
Again, it might be useful to think about this as analogous to Unix
- <B
- CLASS="command"
- >unlink</B
- > call.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="language.references.spot"
- >Spotting References</A
- ></H2
- ><P
- >
Many syntax constructs in PHP are implemented via referencing
- mechanisms, so everything told above about reference binding also
- apply to these constructs. Some constructs, like passing and
- returning by-reference, are mentioned above. Other constructs that
- use references are:
- </P
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="references.global"
- ><VAR
- CLASS="literal"
- >global</VAR
- > References</A
- ></H3
- ><P
- >
When you declare variable as <B
- CLASS="command"
- >global $var</B
- > you
- are in fact creating reference to a global variable. That means,
- this is the same as:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6040"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $var =& $GLOBALS["var"];
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
That means, for example, that unsetting <VAR
- CLASS="varname"
- >$var</VAR
- >
- won't unset global variable.
- </P
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="references.this"
- ><VAR
- CLASS="literal"
- >$this</VAR
- ></A
- ></H3
- ><P
- >
In an object method, <VAR
- CLASS="varname"
- >$this</VAR
- > is always reference
- to the caller object.
- </P
- ></DIV
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="security"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >IV. Security</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >22. <A
- HREF="#security.intro"
- >Introduction</A
- ></DT
- ><DT
- >23. <A
- HREF="#security.general"
- >General considerations</A
- ></DT
- ><DT
- >24. <A
- HREF="#security.cgi-bin"
- >Installed as CGI binary</A
- ></DT
- ><DT
- >25. <A
- HREF="#security.apache"
- >Installed as an Apache module</A
- ></DT
- ><DT
- >26. <A
- HREF="#security.filesystem"
- >Filesystem Security</A
- ></DT
- ><DT
- >27. <A
- HREF="#security.database"
- >Database Security</A
- ></DT
- ><DT
- >28. <A
- HREF="#security.errors"
- >Error Reporting</A
- ></DT
- ><DT
- >29. <A
- HREF="#security.globals"
- >Using Register Globals</A
- ></DT
- ><DT
- >30. <A
- HREF="#security.variables"
- >User Submitted Data</A
- ></DT
- ><DT
- >31. <A
- HREF="#security.magicquotes"
- >Magic Quotes</A
- ></DT
- ><DT
- >32. <A
- HREF="#security.hiding"
- >Hiding PHP</A
- ></DT
- ><DT
- >33. <A
- HREF="#security.current"
- >Keeping Current</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.intro"
- >Chapter 22. Introduction</A
- ></H1
- ><P
- >
PHP is a powerful language and the interpreter, whether included
- in a web server as a module or executed as a separate
- <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > 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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.general"
- >Chapter 23. General considerations</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.cgi-bin"
- >Chapter 24. Installed as CGI binary</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="security.cgi-bin.attacks"
- >Possible attacks</A
- ></H2
- ><P
- >
Using PHP as a <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > 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 <A
- HREF="http://www.cert.org/advisories/CA-1996-11.html"
- TARGET="_top"
- >CA-96.11</A
- > 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:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Accessing system files: <TT
- CLASS="filename"
- >http://my.host/cgi-bin/php?/etc/passwd</TT
- >
- </P
- ><P
- >
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.
- </P
- ><P
- >
When invoked as a CGI binary, PHP refuses to interpret the
- command line arguments.
- </P
- ></LI
- ><LI
- ><P
- >
Accessing any web document on server: <TT
- CLASS="filename"
- >http://my.host/cgi-bin/php/secret/doc.html</TT
- >
- </P
- ><P
- >
The path information part of the URL after the PHP binary name,
- <TT
- CLASS="filename"
- >/secret/doc.html</TT
- > is
- conventionally used to specify the name of the file to be
- opened and interpreted by the <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > program.
- Usually some web server configuration directives (Apache:
- Action) are used to redirect requests to documents like
- <TT
- CLASS="filename"
- >http://my.host/secret/script.php</TT
- > to the
- PHP interpreter. With this setup, the web server first checks
- the access permissions to the directory <TT
- CLASS="filename"
- >/secret</TT
- >, and after that creates the
- redirected request <TT
- CLASS="filename"
- >http://my.host/cgi-bin/php/secret/script.php</TT
- >.
- Unfortunately, if the request is originally given in this form,
- no access checks are made by web server for file <TT
- CLASS="filename"
- >/secret/script.php</TT
- >, but only for the
- <TT
- CLASS="filename"
- >/cgi-bin/php</TT
- > file. This way
- any user able to access <TT
- CLASS="filename"
- >/cgi-bin/php</TT
- > is able to access any
- protected document on the web server.
- </P
- ><P
- >
In PHP, compile-time configuration option <A
- HREF="#configure.enable-force-cgi-redirect"
- >--enable-force-cgi-redirect</A
- >
- and runtime configuration directives <A
- HREF="#ini.doc-root"
- >doc_root</A
- > and <A
- HREF="#ini.user-dir"
- >user_dir</A
- > 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.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.cgi-bin.default"
- >Case 1: only public files served</A
- ></H2
- ><P
- >
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 <A
- HREF="#configure.enable-force-cgi-redirect"
- >--enable-force-cgi-redirect</A
- >
- 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 <TT
- CLASS="filename"
- >http://my.host/cgi-bin/php/dir/script.php</TT
- >
- nor by redirection <TT
- CLASS="filename"
- >http://my.host/dir/script.php</TT
- >.
- </P
- ><P
- >
Redirection can be configured in Apache by using AddHandler and
- Action directives (see below).
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.cgi-bin.force-redirect"
- >Case 2: using --enable-force-cgi-redirect</A
- ></H2
- ><P
- >
This compile-time option prevents anyone from calling PHP
- directly with a URL like <TT
- CLASS="filename"
- >http://my.host/cgi-bin/php/secretdir/script.php</TT
- >.
- Instead, PHP will only parse in this mode if it has gone through
- a web server redirect rule.
- </P
- ><P
- >
Usually the redirection in the Apache configuration is done with
- the following directives:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- >Action php-script /cgi-bin/php
- AddHandler php-script .php</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This option has only been tested with the Apache web server, and
- relies on Apache to set the non-standard CGI environment variable
- <VAR
- CLASS="envar"
- >REDIRECT_STATUS</VAR
- > 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.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.cgi-bin.doc-root"
- >Case 3: setting doc_root or user_dir</A
- ></H2
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
You can set the PHP script document root by the configuration
- directive <A
- HREF="#ini.doc-root"
- >doc_root</A
- > in the
- <A
- HREF="#configuration.file"
- >configuration file</A
- >, or
- you can set the environment variable
- <VAR
- CLASS="envar"
- >PHP_DOCUMENT_ROOT</VAR
- >. If it is set, the CGI version
- of PHP will always construct the file name to open with this
- <VAR
- CLASS="parameter"
- >doc_root</VAR
- > and the path information in the
- request, so you can be sure no script is executed outside this
- directory (except for <VAR
- CLASS="parameter"
- >user_dir</VAR
- >
- below).
- </P
- ><P
- >
Another option usable here is <A
- HREF="#ini.user-dir"
- >user_dir</A
- >. When user_dir is unset,
- only thing controlling the opened file name is
- <VAR
- CLASS="parameter"
- >doc_root</VAR
- >. Opening a URL like <TT
- CLASS="filename"
- >http://my.host/~user/doc.php</TT
- > does not
- result in opening a file under users home directory, but a file
- called <TT
- CLASS="filename"
- >~user/doc.php</TT
- > under
- doc_root (yes, a directory name starting with a tilde
- [<VAR
- CLASS="literal"
- >~</VAR
- >]).
- </P
- ><P
- >
If user_dir is set to for example <TT
- CLASS="filename"
- >public_php</TT
- >, a request like <TT
- CLASS="filename"
- >http://my.host/~user/doc.php</TT
- > will open a
- file called <TT
- CLASS="filename"
- >doc.php</TT
- > under the directory
- named <TT
- CLASS="filename"
- >public_php</TT
- > under the home
- directory of the user. If the home of the user is <TT
- CLASS="filename"
- >/home/user</TT
- >, the file executed is
- <TT
- CLASS="filename"
- >/home/user/public_php/doc.php</TT
- >.
- </P
- ><P
- >
<VAR
- CLASS="parameter"
- >user_dir</VAR
- > expansion happens regardless of
- the <VAR
- CLASS="parameter"
- >doc_root</VAR
- > setting, so you can control
- the document root and user directory access
- separately.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.cgi-bin.shell"
- >Case 4: PHP parser outside of web tree</A
- ></H2
- ><P
- >
A very secure option is to put the PHP parser binary somewhere
- outside of the web tree of files. In <TT
- CLASS="filename"
- >/usr/local/bin</TT
- >, for example. The only real
- downside to this option is that you will now have to put a line
- similar to:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6139"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >#!/usr/local/bin/php</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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
- <VAR
- CLASS="literal"
- >#!</VAR
- > shell-escape mechanism for launching
- itself.
- </P
- ><P
- >
To get PHP to handle <VAR
- CLASS="envar"
- >PATH_INFO</VAR
- > and
- <VAR
- CLASS="envar"
- >PATH_TRANSLATED</VAR
- > information correctly with this
- setup, the PHP parser should be compiled with the <A
- HREF="#configure.enable-discard-path"
- >--enable-discard-path</A
- >
- configure option.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.apache"
- >Chapter 25. Installed as an Apache module</A
- ></H1
- ><P
- >
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, <TT
- CLASS="filename"
- >.htaccess</TT
- > files, etc. and include
- that code as part of your PHP scripts.
- </P
- ><P
- >
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.
- </P
- ><P
- >
A frequent security mistake made at this point is to allow apache
- root permissions, or to escalate apache's abilities in some other
- way.
- </P
- ><P
- >
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.
- </P
- ><P
- >
There are some simpler solutions. By using
- <A
- HREF="#ini.open-basedir"
- >open_basedir</A
- > 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.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.filesystem"
- >Chapter 26. Filesystem Security</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6161"
- ></A
- ><P
- ><B
- >Example 26-1. Poor variable checking leads to....</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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!";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- 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:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6164"
- ></A
- ><P
- ><B
- >Example 26-2. ... A filesystem attack</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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!";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- There are two important measures you should take to prevent these
- issues.
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Only allow limited permissions to the PHP web user binary.
- </P
- ></LI
- ><LI
- ><P
- >
Check all variables which are submitted.
- </P
- ></LI
- ></UL
- >
- Here is an improved script:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6172"
- ></A
- ><P
- ><B
- >Example 26-3. More secure file name checking</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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!";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- 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:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6175"
- ></A
- ><P
- ><B
- >Example 26-4. More secure file name checking</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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...
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.database"
- >Chapter 27. Database Security</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
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 <A
- HREF="#security.database.sql-injection"
- >tamper with an SQL query</A
- >.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.database.design"
- >Designing Databases</A
- ></H2
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.database.connection"
- >Connecting to Database</A
- ></H2
- ><P
- >
You may want to establish 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.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.database.storage"
- >Encrypted Storage Model</A
- ></H2
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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 <A
- HREF="#ref.mcrypt"
- >Mcrypt</A
- > and <A
- HREF="#ref.mhash"
- >Mhash</A
- >, 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.
- </P
- ><P
- >
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
- <A
- HREF="#function.crypt"
- ><B
- CLASS="function"
- >crypt()</B
- ></A
- > and <A
- HREF="#function.md5"
- ><B
- CLASS="function"
- >md5()</B
- ></A
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6205"
- ></A
- ><P
- ><B
- >Example 27-1. Using hashed password field</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- // storing password hash
- $query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
- addslashes($username), md5($password));
- $result = pg_query($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_query($connection, $query);
-
- if (pg_num_rows($result) > 0) {
- echo 'Welcome, $username!';
- } else {
- echo 'Authentication failed for $username.';
- }
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.database.sql-injection"
- >SQL Injection</A
- ></H2
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6213"
- ></A
- ><P
- ><B
- >Example 27-2.
- Splitting the result set into pages ... and making superusers
- (PostgreSQL and MySQL)
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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_query($conn, $query);
- // with MySQL
- $result = mysql_query($query);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Normal users click on the 'next', 'prev' links where the <VAR
- CLASS="varname"
- >$offset</VAR
- >
- is encoded into the URL. The script expects that the incoming
- <VAR
- CLASS="varname"
- >$offset</VAR
- > is a decimal number. However, what if someone tries to
- break in by appending a <A
- HREF="#function.urlencode"
- ><B
- CLASS="function"
- >urlencode()</B
- ></A
- >'d form of the
- following to the URL
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6219"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="sql"
- >// 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;</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- If it happened, then the script would present a superuser access to him.
- Note that <VAR
- CLASS="literal"
- >0;</VAR
- > is to supply a valid offset to the
- original query and to terminate it.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- It is common technique to force the SQL parser to ignore the rest of the
- query written by the developer with <VAR
- CLASS="literal"
- >--</VAR
- > which is the
- comment sign in SQL.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
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 <VAR
- CLASS="literal"
- >WHERE, ORDER BY,
- LIMIT</VAR
- > and <VAR
- CLASS="literal"
- >OFFSET</VAR
- > clauses in <VAR
- CLASS="literal"
- >SELECT</VAR
- >
- statements. If your database supports the <VAR
- CLASS="literal"
- >UNION</VAR
- > 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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6230"
- ></A
- ><P
- ><B
- >Example 27-3.
- Listing out articles ... and some passwords (any database server)
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $query = "SELECT id, name, inserted, size FROM products
- WHERE size = '$size'
- ORDER BY $order LIMIT $limit, $offset;";
- $result = odbc_exec($conn, $query);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- The static part of the query can be combined with another
- <VAR
- CLASS="literal"
- >SELECT</VAR
- > statement which reveals all passwords:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6234"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="sql"
- >'
- union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
- --</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- If this query (playing with the <VAR
- CLASS="literal"
- >'</VAR
- > and
- <VAR
- CLASS="literal"
- >--</VAR
- >) were assigned to one of the variables used in
- <VAR
- CLASS="varname"
- >$query</VAR
- >, the query beast awakened.
- </P
- ><P
- >
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 <VAR
- CLASS="literal"
- >SET</VAR
- > 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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6241"
- ></A
- ><P
- ><B
- >Example 27-4.
- From resetting a password ... to gaining more privileges (any database server)
- </B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- But a malicious user sumbits the value
- <VAR
- CLASS="literal"
- >' or uid like'%admin%'; --</VAR
- > to <VAR
- CLASS="varname"
- >$uid</VAR
- > to
- change the admin's password, or simply sets <VAR
- CLASS="varname"
- >$pwd</VAR
- > to
- <VAR
- CLASS="literal"
- >"hehehe', admin='yes', trusted=100 "</VAR
- > (with a trailing
- space) to gain more privileges. Then, the query will be twisted:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6248"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
- ...;";
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
A frightening example how operating system level commands can be accessed
- on some database hosts.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6251"
- ></A
- ><P
- ><B
- >Example 27-5. Attacking the database hosts operating system (MSSQL Server)</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
- $result = mssql_query($query);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- If attacker submits the value
- <VAR
- CLASS="literal"
- >a%' exec master..xp_cmdshell 'net user test testpass /ADD' --</VAR
- >
- to <VAR
- CLASS="varname"
- >$prod</VAR
- >, then the <VAR
- CLASS="varname"
- >$query</VAR
- > will be:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6257"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $query = "SELECT * FROM products
- WHERE id LIKE '%a%'
- exec master..xp_cmdshell 'net user test testpass /ADD'--";
- $result = mssql_query($query);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- 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 <VAR
- CLASS="literal"
- >sa</VAR
- > and the MSSQLSERVER service is
- running with sufficient privileges, the attacker would now have an
- account with which to access this machine.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="sect2"
- ><HR><H3
- CLASS="sect2"
- ><A
- NAME="security.database.avoiding"
- >Avoiding techniques</A
- ></H3
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Never connect to the database as a superuser or as the database owner.
- Use always customized users with very limited privileges.
- </P
- ></LI
- ><LI
- ><P
- >
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 <A
- HREF="#ref.var"
- >Variable Functions</A
- > and
- in <A
- HREF="#ref.ctype"
- >Character Type Functions</A
- >
- (e.g. <A
- HREF="#function.is-numeric"
- ><B
- CLASS="function"
- >is_numeric()</B
- ></A
- >, <A
- HREF="#function.ctype-digit"
- ><B
- CLASS="function"
- >ctype_digit()</B
- ></A
- >
- respectively) and onwards to the
- <A
- HREF="#ref.pcre"
- >Perl compatible Regular Expressions</A
- >
- support.
- </P
- ></LI
- ><LI
- ><P
- >
If the application waits for numerical input, consider verifying data
- with <A
- HREF="#function.is-numeric"
- ><B
- CLASS="function"
- >is_numeric()</B
- ></A
- >, or silently change its type
- using <A
- HREF="#function.settype"
- ><B
- CLASS="function"
- >settype()</B
- ></A
- >, or use its numeric representation
- by <A
- HREF="#function.sprintf"
- ><B
- CLASS="function"
- >sprintf()</B
- ></A
- >.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6281"
- ></A
- ><P
- ><B
- >Example 27-6. A more secure way to compose a query for paging</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ><LI
- ><P
- >
Quote each non numeric user supplied value that is passed to the
- database with the database-specific string escape function (e.g.
- <A
- HREF="#function.mysql-escape-string"
- ><B
- CLASS="function"
- >mysql_escape_string()</B
- ></A
- >,
- <B
- CLASS="function"
- >sql_escape_string()</B
- >, etc.). If a database-specific
- string escape mechanism is not available, the
- <A
- HREF="#function.addslashes"
- ><B
- CLASS="function"
- >addslashes()</B
- ></A
- > and <A
- HREF="#function.str-replace"
- ><B
- CLASS="function"
- >str_replace()</B
- ></A
- >
- functions may be useful (depending on database type).
- See <A
- HREF="#security.database.storage"
- >the first example</A
- >.
- As the example shows, adding quotes to the static part of the query
- is not enough, making this query easily crackable.
- </P
- ></LI
- ><LI
- ><P
- >
Do not print out any database specific information, especially
- about the schema, by fair means or foul. See also <A
- HREF="#security.errors"
- >Error Reporting</A
- > and <A
- HREF="#ref.errorfunc"
- >Error Handling and Logging Functions</A
- >.
- </P
- ></LI
- ><LI
- ><P
- >
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.
- </P
- ></LI
- ></UL
- ><P
- >
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.
- </P
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.errors"
- >Chapter 28. Error Reporting</A
- ></H1
- ><P
- >
With PHP security, there are two sides to error reporting. One is
- beneficial to increasing security, the other is detrimental.
- </P
- ><P
- >
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:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6302"
- ></A
- ><P
- ><B
- >Example 28-1. Attacking Variables with a custom HTML page</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><form method="post" action="attacktarget?username=badfoo&password=badfoo">
- <input type="hidden" name="username" value="badfoo" />
- <input type="hidden" name="password" value="badfoo" />
- </form></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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 occurred in. This is all
- information that can be exploited. It is not uncommon for a php
- developer to use <A
- HREF="#function.show-source"
- ><B
- CLASS="function"
- >show_source()</B
- ></A
- >,
- <A
- HREF="#function.highlight-string"
- ><B
- CLASS="function"
- >highlight_string()</B
- ></A
- >, or
- <A
- HREF="#function.highlight-file"
- ><B
- CLASS="function"
- >highlight_file()</B
- ></A
- > 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:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6309"
- ></A
- ><P
- ><B
- >Example 28-2. Exploiting common debugging variables</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><form method="post" action="attacktarget?errors=Y&showerrors=1&debug=1">
- <input type="hidden" name="errors" value="Y" />
- <input type="hidden" name="showerrors" value="1" />
- <input type="hidden" name="debug" value="1" />
- </form></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Regardless of the method of error handling, the ability to probe a
- system for errors leads to providing an attacker with more
- information.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ><P
- >
One way of catching this issue ahead of time is to make use of
- PHP's own <A
- HREF="#function.error-reporting"
- ><B
- CLASS="function"
- >error_reporting()</B
- ></A
- >, 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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6319"
- ></A
- ><P
- ><B
- >Example 28-3. Finding dangerous variables with E_ALL</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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");
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.globals"
- >Chapter 29. Using Register Globals</A
- ></H1
- ><P
- >
Perhaps the most controversial change in PHP is when the default value
- for the PHP directive <A
- HREF="#ini.register-globals"
- >
register_globals</A
- > went from ON to OFF in PHP
- <A
- HREF="http://www.php.net/release_4_2_0.php"
- TARGET="_top"
- >4.2.0</A
- >. 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.
- </P
- ><P
- >
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:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6329"
- ></A
- ><P
- ><B
- >Example 29-1. Example misuse with register_globals = on</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
When register_globals = on, our logic above may be compromised. When
- off, <VAR
- CLASS="varname"
- >$authorized</VAR
- > 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 <VAR
- CLASS="literal"
- >$authorized = false</VAR
- >. Doing this
- first means our above code would work with register_globals on or off as
- users by default would be unauthorized.
- </P
- ><P
- >
Another example is that of <A
- HREF="#ref.session"
- >sessions</A
- >.
- When register_globals = on, we could also use
- <VAR
- CLASS="varname"
- >$username</VAR
- > in our example below but again you must
- realize that <VAR
- CLASS="varname"
- >$username</VAR
- > could also come from other
- means, such as GET (through the URL).
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6340"
- ></A
- ><P
- ><B
- >Example 29-2. Example use of sessions with register_globals on or off</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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?";
-
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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 <VAR
- CLASS="varname"
- >$_REQUEST</VAR
- > as it contains
- a mix of GET, POST and COOKIE data. See also the manual section on
- using <A
- HREF="#language.variables.external"
- >variables from outside
- of PHP</A
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6347"
- ></A
- ><P
- ><B
- >Example 29-3. Detecting simple variable poisoning</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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
-
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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 uninitialized variables you may turn up
- <A
- HREF="#function.error-reporting"
- ><B
- CLASS="function"
- >error_reporting()</B
- ></A
- > to show
- <TT
- CLASS="constant"
- ><B
- >E_NOTICE</B
- ></TT
- > level errors.
- </P
- ><P
- >
For information about emulating register_globals being On or Off, see this <A
- HREF="#faq.misc.registerglobals"
- >FAQ</A
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Superglobals: availability note: </B
- >Since PHP 4.1.0, superglobal arrays such as <VAR
- CLASS="varname"
- >$_GET
- </VAR
- >, <VAR
- CLASS="varname"
- >$_POST</VAR
- >, and <VAR
- CLASS="varname"
- >$_SERVER</VAR
- >,
- etc. have been available. For more information, read the manual section
- on <A
- HREF="#language.variables.predefined"
- >superglobals</A
- ></P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.variables"
- >Chapter 30. User Submitted Data</A
- ></H1
- ><P
- >
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.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6365"
- ></A
- ><P
- ><B
- >Example 30-1. Dangerous Variable Usage</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- 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:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Will this script only affect the intended files?
- </P
- ></LI
- ><LI
- ><P
- >
Can unusual or undesirable data be acted upon?
- </P
- ></LI
- ><LI
- ><P
- >
Can this script be used in unintended ways?
- </P
- ></LI
- ><LI
- ><P
- >
Can this be used in conjunction with other scripts in a negative
- manner?
- </P
- ></LI
- ><LI
- ><P
- >
Will any transactions be adequately logged?
- </P
- ></LI
- ></UL
- >
- 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.
- </P
- ><P
- >
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).
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.magicquotes"
- >Chapter 31. Magic Quotes</A
- ></H1
- ><P
- >
Magic Quotes is a process that automagically escapes incoming data to the
- PHP script. It's preferred to code with magic quotes off and to instead
- escape the data at runtime, as needed.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.magicquotes.what"
- >What are Magic Quotes</A
- ></H2
- ><P
- >
When on, all <VAR
- CLASS="literal"
- >'</VAR
- > (single-quote), <VAR
- CLASS="literal"
- >"</VAR
- >
- (double quote), <VAR
- CLASS="literal"
- >\</VAR
- > (backslash) and <VAR
- CLASS="literal"
- >NULL</VAR
- >
- characters are escaped with a backslash automatically. This is identical
- to what <A
- HREF="#function.addslashes"
- ><B
- CLASS="function"
- >addslashes()</B
- ></A
- > does.
- </P
- ><P
- >
There are three magic quote directives:
- </P
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
<A
- HREF="#ini.magic-quotes-gpc"
- >magic_quotes_gpc</A
- >
- </P
- ><P
- >
Affects HTTP Request data (GET, POST, and COOKIE). Cannot be set at
- runtime, and defaults to <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >on</I
- ></SPAN
- > in PHP.
- </P
- ><P
- >
See also <A
- HREF="#function.get-magic-quotes-gpc"
- ><B
- CLASS="function"
- >get_magic_quotes_gpc()</B
- ></A
- >.
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#ini.magic-quotes-runtime"
- >magic_quotes_runtime</A
- >
- </P
- ><P
- >
If enabled, most functions that return data from an external source,
- including databases and text files, will have quotes escaped with a
- backslash. Can be set at runtime, and defaults to <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >on</I
- ></SPAN
- >
- in PHP.
- </P
- ><P
- >
See also <A
- HREF="#function.set-magic-quotes-runtime"
- ><B
- CLASS="function"
- >set_magic_quotes_runtime()</B
- ></A
- > and
- <A
- HREF="#function.get-magic-quotes-runtime"
- ><B
- CLASS="function"
- >get_magic_quotes_runtime()</B
- ></A
- >.
- </P
- ></LI
- ><LI
- ><P
- >
<A
- HREF="#ini.magic-quotes-sybase"
- >magic_quotes_sybase</A
- >
- </P
- ><P
- >
If enabled, a single-quote is escaped with a single-quote instead of a
- backslash. If on, it completely overrides
- <A
- HREF="#ini.magic-quotes-gpc"
- >magic_quotes_gpc</A
- >. Having
- both directives enabled means only single quotes are escaped as
- <VAR
- CLASS="literal"
- >''</VAR
- >. Double quotes, backslashes and NULL's will
- remain untouched and unescaped.
- </P
- ><P
- >
See also <A
- HREF="#function.ini-get"
- ><B
- CLASS="function"
- >ini_get()</B
- ></A
- > for retrieving its value.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.magicquotes.why"
- >Why use Magic Quotes</A
- ></H2
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Useful for beginners
- </P
- ><P
- >
Magic quotes are implemented in PHP to help code written by beginners
- from being dangerous. Although
- <A
- HREF="#security.database.sql-injection"
- >SQL Injection</A
- >
- is still possible with magic quotes on, the risk is reduced.
- </P
- ></LI
- ><LI
- ><P
- >
Convenience
- </P
- ><P
- >
For inserting data into a database, magic quotes essentially runs
- <A
- HREF="#function.addslashes"
- ><B
- CLASS="function"
- >addslashes()</B
- ></A
- > on all Get, Post, and Cookie data,
- and does so automagically.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.magicquotes.whynot"
- >Why not to use Magic Quotes</A
- ></H2
- ><P
- ></P
- ><UL
- ><LI
- ><P
- >
Portability
- </P
- ><P
- >
Assuming it to be on, or off, affects portability. Use
- <A
- HREF="#function.get-magic-quotes-gpc"
- ><B
- CLASS="function"
- >get_magic_quotes_gpc()</B
- ></A
- > to check for this, and code
- accordingly.
- </P
- ></LI
- ><LI
- ><P
- >
Performance
- </P
- ><P
- >
Because not every piece of escaped data is inserted into a
- database, there is a performance loss for escaping all this data.
- Simply calling on the escaping functions (like
- <A
- HREF="#function.addslashes"
- ><B
- CLASS="function"
- >addslashes()</B
- ></A
- >) at runtime is more efficient.
- </P
- ><P
- >
Although <TT
- CLASS="filename"
- >php.ini-dist</TT
- > enables these directives
- by default, <TT
- CLASS="filename"
- >php.ini-recommended</TT
- > disables it.
- This recommendation is mainly due to performance reasons.
- </P
- ></LI
- ><LI
- ><P
- >
Inconvenience
- </P
- ><P
- >
Because not all data needs escaping, it's often annoying to see escaped
- data where it shouldn't be. For example, emailing from a form, and
- seeing a bunch of \' within the email. To fix, this may require
- excessive use of <A
- HREF="#function.stripslashes"
- ><B
- CLASS="function"
- >stripslashes()</B
- ></A
- >.
- </P
- ></LI
- ></UL
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="security.magicquotes.disabling"
- >Disabling Magic Quotes</A
- ></H2
- ><P
- >
The <A
- HREF="#ini.magic-quotes-gpc"
- >magic_quotes_gpc</A
- >
- directive may only be disabled at the system level, and not at
- runtime. In otherwords, use of <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- > is not
- an option.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6451"
- ></A
- ><P
- ><B
- >Example 31-1. Disabling magic quotes server side</B
- ></P
- ><P
- >
An example that sets the value of these directives to
- <VAR
- CLASS="literal"
- >Off</VAR
- > in <TT
- CLASS="filename"
- >php.ini</TT
- >. For additional details, read the
- manual section titled <A
- HREF="#configuration.changes"
- >How to
- change configuration settings</A
- >.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >; Magic quotes
- ;
-
- ; Magic quotes for incoming GET/POST/Cookie data.
- magic_quotes_gpc = Off
-
- ; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
- magic_quotes_runtime = Off
-
- ; Use Sybase-style magic quotes (escape ' with '' instead of \').
- magic_quotes_sybase = Off</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
If access to the server configuration is unavilable, use of
- <TT
- CLASS="filename"
- >.htaccess</TT
- > is also an option. For example:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >php_flag magic_quotes_gpc Off</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In the interest of writing portable code (code that works in any
- environment), like if setting at the server level is not possible,
- here's an example to disable <A
- HREF="#ini.magic-quotes-gpc"
- >
magic_quotes_gpc</A
- > at runtime. This method is inefficient so
- it's preferred to instead set the appropriate directives elsewhere.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6464"
- ></A
- ><P
- ><B
- >Example 31-2. Disabling magic quotes at runtime</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if (get_magic_quotes_gpc()) {
- function stripslashes_deep($value)
- {
- $value = is_array($value) ?
- array_map('stripslashes_deep', $value) :
- stripslashes($value);
-
- return $value;
- }
-
- $_POST = array_map('stripslashes_deep', $_POST);
- $_GET = array_map('stripslashes_deep', $_GET);
- $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.hiding"
- >Chapter 32. Hiding PHP</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
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 <TT
- CLASS="filename"
- >php.ini</TT
- > file, you
- reduce the amount of information available to them.
- </P
- ><P
- >
Another tactic is to configure web servers such as apache to
- parse different filetypes through PHP, either with an <TT
- CLASS="filename"
- >.htaccess</TT
- >
- directive, or in the apache configuration file itself. You can
- then use misleading file extensions:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6474"
- ></A
- ><P
- ><B
- >Example 32-1. Hiding PHP as another language</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Make PHP code look like other code types
- AddType application/x-httpd-php .asp .py .pl</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Or obscure it completely:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6477"
- ></A
- ><P
- ><B
- >Example 32-2. Using unknown types for PHP extensions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Make PHP code look like unknown types
- AddType application/x-httpd-php .bop .foo .133t</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- Or hide it as HTML code, which has a slight performance hit because
- all HTML will be parsed through the PHP engine:
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6480"
- ></A
- ><P
- ><B
- >Example 32-3. Using HTML types for PHP extensions</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="apache-conf"
- ># Make all PHP code look like HTML
- AddType application/x-httpd-php .htm .html</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- 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.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="security.current"
- >Chapter 33. Keeping Current</A
- ></H1
- ><P
- >
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.
- </P
- ><P
- >
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.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="features"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >V. Features</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >34. <A
- HREF="#features.http-auth"
- >HTTP authentication with PHP</A
- ></DT
- ><DT
- >35. <A
- HREF="#features.cookies"
- >Cookies</A
- ></DT
- ><DT
- >36. <A
- HREF="#features.sessions"
- >Sessions</A
- ></DT
- ><DT
- >37. <A
- HREF="#features.xforms"
- >Dealing with XForms</A
- ></DT
- ><DT
- >38. <A
- HREF="#features.file-upload"
- >Handling file uploads</A
- ></DT
- ><DT
- >39. <A
- HREF="#features.remote-files"
- >Using remote files</A
- ></DT
- ><DT
- >40. <A
- HREF="#features.connection-handling"
- >Connection handling</A
- ></DT
- ><DT
- >41. <A
- HREF="#features.persistent-connections"
- >Persistent Database Connections</A
- ></DT
- ><DT
- >42. <A
- HREF="#features.safe-mode"
- >Safe Mode</A
- ></DT
- ><DT
- >43. <A
- HREF="#features.commandline"
- >Using PHP from the command line</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.http-auth"
- >Chapter 34. HTTP authentication with PHP</A
- ></H1
- ><P
- >
The <ACRONYM
- CLASS="acronym"
- >HTTP</ACRONYM
- > Authentication hooks in PHP are only available when it is
- running as an Apache module and is hence not available in the CGI version.
- In an Apache module PHP script, it is possible to use the
- <A
- HREF="#function.header"
- ><B
- CLASS="function"
- >header()</B
- ></A
- > function to send an "Authentication Required"
- message to the client browser causing it to pop up a Username/Password
- input window. Once the user has filled in a username and a password,
- the URL containing the PHP script will be called again with the
- <A
- HREF="#reserved.variables"
- >predefined variables</A
- >
- <VAR
- CLASS="varname"
- >PHP_AUTH_USER</VAR
- >, <VAR
- CLASS="varname"
- >PHP_AUTH_PW</VAR
- >,
- and <VAR
- CLASS="varname"
- >AUTH_TYPE</VAR
- > set to the user name, password and
- authentication type respectively. These predefined variables are found
- in the <A
- HREF="#reserved.variables.server"
- >$_SERVER</A
- > and
- <VAR
- CLASS="varname"
- >$HTTP_SERVER_VARS</VAR
- > arrays. Only "Basic" authentication
- is supported. See the <A
- HREF="#function.header"
- ><B
- CLASS="function"
- >header()</B
- ></A
- > function for more
- information.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >PHP Version Note: </B
- >
- <A
- HREF="#language.variables.superglobals"
- >Autoglobals</A
- >,
- such as <A
- HREF="#reserved.variables.server"
- >$_SERVER</A
- >, became
- available in PHP <A
- HREF="http://www.php.net/release_4_1_0.php"
- TARGET="_top"
- >4.1.0</A
- >.
- <VAR
- CLASS="varname"
- >$HTTP_SERVER_VARS</VAR
- > has been available since PHP 3.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
An example script fragment which would force client authentication
- on a page is as follows:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6510"
- ></A
- ><P
- ><B
- >Example 34-1. HTTP Authentication example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- if (!isset($_SERVER['PHP_AUTH_USER'])) {
- header('WWW-Authenticate: Basic realm="My Realm"');
- header('HTTP/1.0 401 Unauthorized');
- echo 'Text to send if user hits Cancel button';
- exit;
- } else {
- echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
- echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Compatibility Note: </B
- >
- Please be careful when coding the HTTP header lines. In order to guarantee maximum
- compatibility with all clients, the keyword "Basic" should be written with an
- uppercase "B", the realm string must be enclosed in double (not single) quotes,
- and exactly one space should precede the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >401</I
- ></SPAN
- > code in the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >HTTP/1.0 401</I
- ></SPAN
- > header line.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Instead of simply printing out <VAR
- CLASS="varname"
- >PHP_AUTH_USER</VAR
- >
- and <VAR
- CLASS="varname"
- >PHP_AUTH_PW</VAR
- >, as done in the above example,
- you may want to check the username and password for validity.
- Perhaps by sending a query to a database, or by looking up the
- user in a dbm file.
- </P
- ><P
- >
Watch out for buggy Internet Explorer browsers out there. They
- seem very picky about the order of the headers. Sending the
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >WWW-Authenticate</I
- ></SPAN
- > header before the
- <VAR
- CLASS="literal"
- >HTTP/1.0 401</VAR
- > header seems to do the trick
- for now.
- </P
- ><P
- >
As of PHP 4.3.0, in order to prevent someone from writing a script which
- reveals the password for a page that was authenticated through a
- traditional external mechanism, the PHP_AUTH variables will not be
- set if external authentication is enabled for that particular
- page and <A
- HREF="#ini.safe-mode"
- >safe mode</A
- > is enabled. Regardless,
- <VAR
- CLASS="varname"
- >REMOTE_USER</VAR
- > can be used
- to identify the externally-authenticated user. So, you can use
- <VAR
- CLASS="varname"
- >$_SERVER['REMOTE_USER']</VAR
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Configuration Note: </B
- >
- PHP uses the presence of an <VAR
- CLASS="literal"
- >AuthType</VAR
- > directive
- to determine whether external authentication is in effect.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Note, however, that the above does not prevent someone who
- controls a non-authenticated URL from stealing passwords from
- authenticated URLs on the same server.
- </P
- ><P
- >
Both Netscape Navigator and Internet Explorer will clear the local browser
- window's authentication cache for the realm upon receiving a
- server response of 401. This can effectively "log out" a user,
- forcing them to re-enter their username and password. Some people
- use this to "time out" logins, or provide a "log-out" button.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6535"
- ></A
- ><P
- ><B
- >Example 34-2. HTTP Authentication example forcing a new name/password</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function authenticate() {
- header('WWW-Authenticate: Basic realm="Test Authentication System"');
- header('HTTP/1.0 401 Unauthorized');
- echo "You must enter a valid login ID and password to access this resource\n";
- exit;
- }
-
- if (!isset($_SERVER['PHP_AUTH_USER']) ||
- ($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
- authenticate();
- }
- else {
- echo "<p>Welcome: {$_SERVER['PHP_AUTH_USER']}<br />";
- echo "Old: {$_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='Re Authenticate' />\n";
- echo "</form></p>\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This behavior is not required by the HTTP Basic authentication
- standard, so you should never depend on this. Testing with Lynx
- has shown that Lynx does not clear the authentication credentials
- with a 401 server response, so pressing back and then forward
- again will open the resource as long as the credential
- requirements haven't changed. The user can press the
- '_' key to clear their authentication information, however.
- </P
- ><P
- >
Also note that until PHP 4.3.3, HTTP Authentication did not work
- using Microsoft's IIS server with the CGI version of PHP due to a
- limitation of IIS. In order to get it to work in PHP 4.3.3+,
- you must edit your IIS configuration "Directory Security". Click
- on "Edit" and only check "Anonymous Access", all other fields
- should be left unchecked.
- </P
- ><P
- >
Another limitation is if you're using the IIS module (ISAPI) and PHP 4, you
- may not use the <VAR
- CLASS="literal"
- >PHP_AUTH_*</VAR
- > variables but instead, the
- variable <VAR
- CLASS="literal"
- >HTTP_AUTHORIZATION</VAR
- > is available. For example,
- consider the following code: <VAR
- CLASS="literal"
- >list($user, $pw) = explode(':',
- base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));</VAR
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >IIS Note:: </B
- >
- For HTTP Authentication to work with IIS, the PHP directive
- <A
- HREF="#ini.cgi.rfc2616-headers"
- >cgi.rfc2616_headers</A
- > must
- be set to <VAR
- CLASS="literal"
- >0</VAR
- > (the default value).
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If <A
- HREF="#ini.safe-mode"
- >safe mode</A
- > is enabled, the
- uid of the script is added to the <VAR
- CLASS="literal"
- >realm</VAR
- > part of
- the <VAR
- CLASS="literal"
- >WWW-Authenticate</VAR
- > header.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.cookies"
- >Chapter 35. Cookies</A
- ></H1
- ><P
- >
PHP transparently supports <ACRONYM
- CLASS="acronym"
- >HTTP</ACRONYM
- > cookies. Cookies are a mechanism for
- storing data in the remote browser and thus tracking or identifying return
- users. You can set cookies using the <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > or
- <A
- HREF="#function.setrawcookie"
- ><B
- CLASS="function"
- >setrawcookie()</B
- ></A
- >
- function. Cookies are part of the <ACRONYM
- CLASS="acronym"
- >HTTP</ACRONYM
- > header, so
- <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > must be called before any output is sent to
- the browser. This is the same limitation that <A
- HREF="#function.header"
- ><B
- CLASS="function"
- >header()</B
- ></A
- >
- has. You can use the <A
- HREF="#ref.outcontrol"
- >output buffering
- functions</A
- > to delay the script output until you have decided whether
- or not to set any cookies or send any headers.
- </P
- ><P
- >
Any cookies sent to you from the client will automatically be turned into a
- PHP variable just like <VAR
- CLASS="literal"
- >GET</VAR
- > and <VAR
- CLASS="literal"
- >POST</VAR
- >
- method data, depending on the <A
- HREF="#ini.register-globals"
- >register_globals</A
- >
- and <A
- HREF="#ini.variables-order"
- >variables_order</A
- >
- configuration variables. If you wish to assign multiple values to a single
- cookie, just add <VAR
- CLASS="literal"
- >[]</VAR
- > to the cookie name.
- </P
- ><P
- >
In PHP 4.1.0 and later, the <VAR
- CLASS="varname"
- >$_COOKIE</VAR
- > auto-global array
- will always be set with any cookies sent from the client.
- <VAR
- CLASS="varname"
- >$HTTP_COOKIE_VARS</VAR
- > is also set in earlier versions of PHP
- when the <A
- HREF="#ini.track-vars"
- >track_vars</A
- > configuration
- variable is set. (This setting is always on since PHP 4.0.3.)
- </P
- ><P
- >
For more details, including notes on browser bugs, see the
- <A
- HREF="#function.setcookie"
- ><B
- CLASS="function"
- >setcookie()</B
- ></A
- > and <A
- HREF="#function.setrawcookie"
- ><B
- CLASS="function"
- >setrawcookie()</B
- ></A
- >
- function.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.sessions"
- >Chapter 36. Sessions</A
- ></H1
- ><P
- >
Session support in PHP consists of a way to preserve certain data across
- subsequent accesses. This enables you to build more customized applications
- and increase the appeal of your web site. All informations are in
- <A
- HREF="#ref.session"
- >Session reference</A
- > sections.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.xforms"
- >Chapter 37. Dealing with XForms</A
- ></H1
- ><P
- >
<A
- HREF="http://www.w3.org/MarkUp/Forms/"
- TARGET="_top"
- >XForms</A
- > 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.
- </P
- ><P
- >
The first key difference in XForms is how the form is sent to the client.
- <A
- HREF="http://www.w3.org/MarkUp/Forms/2003/xforms-for-html-authors.html"
- TARGET="_top"
- >XForms for HTML Authors</A
- >
- contains a detailed description of how to create XForms, for the purpose
- of this tutorial we'll only be looking at a simple example.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6587"
- ></A
- ><P
- ><B
- >Example 37-1. A simple XForms search form</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The above form displays a text input box (named <VAR
- CLASS="parameter"
- >q</VAR
- >),
- and a submit button. When the submit button is clicked, the form will be
- sent to the page referred to by <VAR
- CLASS="literal"
- >action</VAR
- >.
- </P
- ><P
- >
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
- <VAR
- CLASS="literal"
- >application/x-www-form-urlencoded</VAR
- >, in the XForms world
- however, this information is sent as XML formatted data.
- </P
- ><P
- >
If you're choosing to work with XForms then you probably want that data as
- XML, in that case, look in <VAR
- CLASS="varname"
- >$HTTP_RAW_POST_DATA</VAR
- > where
- you'll find the XML document generated by the browser which you can pass
- into your favorite XSLT engine or document parser.
- </P
- ><P
- >
If you're not interested in formatting and just want your data to be loaded
- into the traditional <VAR
- CLASS="varname"
- >$_POST</VAR
- > variable, you can instruct
- the client browser to send it as <VAR
- CLASS="literal"
- >application/x-www-form-urlencoded</VAR
- >
- by changing the <VAR
- CLASS="parameter"
- >method</VAR
- > attribute to
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >urlencoded-post</I
- ></SPAN
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6602"
- ></A
- ><P
- ><B
- >Example 37-2. Using an XForm to populate <VAR
- CLASS="varname"
- >$_POST</VAR
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- As of this writing, many browsers do not support XForms.
- Check your browser version if the above examples fails.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.file-upload"
- >Chapter 38. Handling file uploads</A
- ></H1
- ><DIV
- CLASS="sect1"
- ><H2
- CLASS="sect1"
- ><A
- NAME="features.file-upload.post-method"
- >POST method uploads</A
- ></H2
- ><P
- >
This feature lets people upload both text and binary files.
- With PHP's authentication and file manipulation functions,
- you have full control over who is allowed to upload and
- what is to be done with the file once it has been uploaded.
- </P
- ><P
- >
PHP is capable of receiving file uploads from any RFC-1867
- compliant browser (which includes <SPAN
- CLASS="productname"
- >Netscape Navigator 3</SPAN
- >
- or later, <SPAN
- CLASS="productname"
- >Microsoft Internet Explorer 3</SPAN
- >
- with a patch from Microsoft, or later without a patch).
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Related Configurations Note: </B
- >
- See also the <A
- HREF="#ini.file-uploads"
- >file_uploads</A
- >,
- <A
- HREF="#ini.upload-max-filesize"
- >upload_max_filesize</A
- >,
- <A
- HREF="#ini.upload-tmp-dir"
- >upload_tmp_dir</A
- >,
- <A
- HREF="#ini.post-max-size"
- >post_max_size</A
- > and
- <A
- HREF="#ini.max-input-time"
- >max_input_time</A
- > directives
- in <TT
- CLASS="filename"
- >php.ini</TT
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
PHP also supports PUT-method file uploads as used by
- <SPAN
- CLASS="productname"
- >Netscape Composer</SPAN
- > and W3C's
- <SPAN
- CLASS="productname"
- >Amaya</SPAN
- > clients. See the <A
- HREF="#features.file-upload.put-method"
- >PUT Method
- Support</A
- > for more details.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6630"
- ></A
- ><P
- ><B
- >Example 38-1. File Upload Form</B
- ></P
- ><P
- >
A file upload screen can be built by creating a special form which
- looks something like this:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><!-- The data encoding type, enctype, MUST be specified as below -->
- <form enctype="multipart/form-data" action="__URL__" method="POST">
- <!-- MAX_FILE_SIZE must precede the file input field -->
- <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
- <!-- Name of input element determines name in $_FILES array -->
- Send this file: <input name="userfile" type="file" />
- <input type="submit" value="Send File" />
- </form></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The <VAR
- CLASS="literal"
- >__URL__</VAR
- > in the above example should be replaced,
- and point to a PHP file.
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >MAX_FILE_SIZE</VAR
- > hidden field (measured in bytes) must
- precede the file input field, and its value is the maximum filesize accepted.
- This is an advisory to the browser, PHP also checks it.
- Fooling this setting on the browser side is quite easy, so never rely
- on files with a greater size being blocked by this feature.
- The PHP settings for maximum-size, however, cannot be fooled.
- This form element should always be used as it
- saves users the trouble of waiting for a big file being transferred only
- to find that it was too big and the transfer failed.
- </P
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Be sure your file upload form has attribute <VAR
- CLASS="literal"
- >enctype="multipart/form-data"</VAR
- >
- otherwise the file upload will not work.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The global <A
- HREF="#reserved.variables.files"
- >$_FILES</A
- >
- exists as of PHP 4.1.0 (Use <VAR
- CLASS="varname"
- >$HTTP_POST_FILES</VAR
- >
- instead if using an earlier version).
- These arrays will contain all the uploaded file information.
- </P
- ><P
- >
The contents of <A
- HREF="#reserved.variables.files"
- >$_FILES</A
- >
- from the example form is as follows. Note that this assumes the use of
- the file upload name <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >userfile</I
- ></SPAN
- >, as used in the example
- script above. This can be any name.
- <P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><VAR
- CLASS="varname"
- >$_FILES['userfile']['name']</VAR
- ></DT
- ><DD
- ><P
- >
The original name of the file on the client machine.
- </P
- ></DD
- ><DT
- ><VAR
- CLASS="varname"
- >$_FILES['userfile']['type']</VAR
- ></DT
- ><DD
- ><P
- >
The mime type of the file, if the browser provided this
- information. An example would be
- <VAR
- CLASS="literal"
- >"image/gif"</VAR
- >.
- </P
- ></DD
- ><DT
- ><VAR
- CLASS="varname"
- >$_FILES['userfile']['size']</VAR
- ></DT
- ><DD
- ><P
- >
The size, in bytes, of the uploaded file.
- </P
- ></DD
- ><DT
- ><VAR
- CLASS="varname"
- >$_FILES['userfile']['tmp_name']</VAR
- ></DT
- ><DD
- ><P
- >
The temporary filename of the file in which the uploaded file
- was stored on the server.
- </P
- ></DD
- ><DT
- ><VAR
- CLASS="varname"
- >$_FILES['userfile']['error']</VAR
- ></DT
- ><DD
- ><P
- >
The <A
- HREF="#features.file-upload.errors"
- >error code</A
- >
- associated with this file upload. This element was added in PHP 4.2.0
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- >
Files will, by default be stored in the server's default temporary
- directory, unless another location has been given with the <A
- HREF="#ini.upload-tmp-dir"
- >upload_tmp_dir</A
- > directive in
- <TT
- CLASS="filename"
- >php.ini</TT
- >. The server's default directory can
- be changed by setting the environment variable
- <VAR
- CLASS="envar"
- >TMPDIR</VAR
- > in the environment in which PHP runs.
- Setting it using <A
- HREF="#function.putenv"
- ><B
- CLASS="function"
- >putenv()</B
- ></A
- > from within a PHP
- script will not work. This environment variable can also be used
- to make sure that other operations are working on uploaded files,
- as well.
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6680"
- ></A
- ><P
- ><B
- >Example 38-2. Validating file uploads</B
- ></P
- ><P
- >
See also the function entries for <A
- HREF="#function.is-uploaded-file"
- ><B
- CLASS="function"
- >is_uploaded_file()</B
- ></A
- >
- and <A
- HREF="#function.move-uploaded-file"
- ><B
- CLASS="function"
- >move_uploaded_file()</B
- ></A
- > for further information. The
- following example will process the file upload that came from a form.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
- // of $_FILES.
-
- $uploaddir = '/var/www/uploads/';
- $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
-
- echo '<pre>';
- if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
- echo "File is valid, and was successfully uploaded.\n";
- } else {
- echo "Possible file upload attack!\n";
- }
-
- echo 'Here is some more debugging info:';
- print_r($_FILES);
-
- print "</pre>";
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The PHP script which receives the uploaded file should implement
- whatever logic is necessary for determining what should be done
- with the uploaded file. You can, for example, use the
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['size']</VAR
- > variable
- to throw away any files that are either too small or too big. You
- could use the
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['type']</VAR
- > variable
- to throw away any files that didn't match a certain type criteria.
- As of PHP 4.2.0, you could use <VAR
- CLASS="varname"
- >$_FILES['userfile']['error']</VAR
- >
- and plan your logic according to the <A
- HREF="#features.file-upload.errors"
- >error codes</A
- >.
- Whatever the logic, you should either delete the file from the
- temporary directory or move it elsewhere.
- </P
- ><P
- >
If no file is selected for upload in your form, PHP will return
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['size']</VAR
- > as 0, and
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['tmp_name']</VAR
- > as none.
- </P
- ><P
- >
The file will be deleted from the temporary directory at the end
- of the request if it has not been moved away or renamed.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="features.file-upload.errors"
- >Error Messages Explained</A
- ></H2
- ><P
- >
Since PHP 4.2.0, PHP returns an appropriate error code along with the
- file array. The error code can be found in the
- <VAR
- CLASS="literal"
- >error</VAR
- > segment of the file array that is created
- during the file upload by PHP. In other words, the error might be
- found in <VAR
- CLASS="varname"
- >$_FILES['userfile']['error']</VAR
- >.
- </P
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_OK</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 0; There is no error, the file uploaded with success.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_INI_SIZE</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 1; The uploaded file exceeds the
- <A
- HREF="#ini.upload-max-filesize"
- >upload_max_filesize</A
- >
- directive in <TT
- CLASS="filename"
- >php.ini</TT
- >.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_FORM_SIZE</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 2; The uploaded file exceeds the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >MAX_FILE_SIZE</I
- ></SPAN
- >
- directive that was specified in the HTML form.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_PARTIAL</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 3; The uploaded file was only partially uploaded.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_NO_FILE</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 4; No file was uploaded.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >UPLOAD_ERR_NO_TMP_DIR</B
- ></TT
- ></DT
- ><DD
- ><P
- >
Value: 6; Missing a temporary folder. Introduced in PHP 4.3.10 and PHP
- 5.0.3.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- These became PHP constants in PHP 4.3.0.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="features.file-upload.common-pitfalls"
- >Common Pitfalls</A
- ></H2
- ><P
- >
The <VAR
- CLASS="literal"
- >MAX_FILE_SIZE</VAR
- > item cannot specify a file size
- greater than the file size that has been set in the <A
- HREF="#ini.upload-max-filesize"
- >upload_max_filesize</A
- > ini-setting.
- The default is 2 Megabytes.
- </P
- ><P
- >
If a memory limit is enabled, a larger <A
- HREF="#ini.memory-limit"
- >memory_limit</A
- > may be needed. Make
- sure you set <A
- HREF="#ini.memory-limit"
- >memory_limit</A
- >
- large enough.
- </P
- ><P
- >
If <A
- HREF="#ini.max-execution-time"
- >max_execution_time</A
- >
- is set too small, script execution may be exceeded by the value. Make
- sure you set <VAR
- CLASS="literal"
- >max_execution_time</VAR
- > large enough.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <A
- HREF="#ini.max-execution-time"
- >max_execution_time</A
- > only
- affects the execution time of the script itself. Any time spent
- on activity that happens outside the execution of the script
- such as system calls using <A
- HREF="#function.system"
- ><B
- CLASS="function"
- >system()</B
- ></A
- >, the
- <A
- HREF="#function.sleep"
- ><B
- CLASS="function"
- >sleep()</B
- ></A
- > function, database queries, time taken by
- the file upload process, etc. is not included when determining the maximum
- time that the script has been running.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
<A
- HREF="#ini.max-input-time"
- >max_input_time</A
- > sets the maximum
- time, in seconds, the script is allowed to receive input; this includes
- file uploads. For large or multiple files, or users on slower connections,
- the default of <VAR
- CLASS="literal"
- >60 seconds</VAR
- > may be exceeded.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
If <A
- HREF="#ini.post-max-size"
- >post_max_size</A
- > is set too
- small, large files cannot be uploaded. Make sure you set
- <VAR
- CLASS="literal"
- >post_max_size</VAR
- > large enough.
- </P
- ><P
- >
Not validating which file you operate on may mean that users can access
- sensitive information in other directories.
- </P
- ><P
- >
Please note that the <SPAN
- CLASS="productname"
- >CERN httpd</SPAN
- > seems to strip off everything
- starting at the first whitespace in the content-type mime header
- it gets from the client. As long as this is the case, <SPAN
- CLASS="productname"
- >CERN httpd</SPAN
- >
- will not support the file upload feature.
- </P
- ><P
- >
Due to the large amount of directory listing styles we cannot guarantee
- that files with exotic names (like containing spaces) are handled properly.
- </P
- ><P
- >
A developer may not mix normal input fields and file upload fields in the same
- form variable (by using an input name like <VAR
- CLASS="literal"
- >foo[]</VAR
- >).
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="features.file-upload.multiple"
- >Uploading multiple files</A
- ></H2
- ><P
- >
Multiple files can be uploaded using different
- <VAR
- CLASS="literal"
- >name</VAR
- > for <VAR
- CLASS="literal"
- >input</VAR
- >.
- </P
- ><P
- >
It is also possible to upload multiple files simultaneously and
- have the information organized automatically in arrays for you. To
- do so, you need to use the same array submission syntax in the
- HTML form as you do with multiple selects and checkboxes:
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Support for multiple file uploads was added in PHP 3.0.10.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6776"
- ></A
- ><P
- ><B
- >Example 38-3. Uploading multiple files</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="html"
- ><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></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
When the above form is submitted, the arrays
- <VAR
- CLASS="varname"
- >$_FILES['userfile']</VAR
- >,
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['name']</VAR
- >, and
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['size']</VAR
- > will be
- initialized (as well as in <VAR
- CLASS="varname"
- >$HTTP_POST_FILES</VAR
- > for PHP versions prior
- to 4.1.0).
- When
- <A
- HREF="#ini.register-globals"
- >register_globals</A
- > is on, globals for uploaded
- files are also initialized. Each of these will be a numerically
- indexed array of the appropriate values for the submitted files.
- </P
- ><P
- >
For instance, assume that the filenames
- <TT
- CLASS="filename"
- >/home/test/review.html</TT
- > and
- <TT
- CLASS="filename"
- >/home/test/xwp.out</TT
- > are submitted. In this
- case, <VAR
- CLASS="varname"
- >$_FILES['userfile']['name'][0]</VAR
- >
- would contain the value <TT
- CLASS="filename"
- >review.html</TT
- >, and
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['name'][1]</VAR
- > would
- contain the value <TT
- CLASS="filename"
- >xwp.out</TT
- >. Similarly,
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['size'][0]</VAR
- > would
- contain <TT
- CLASS="filename"
- >review.html</TT
- >'s file size, and so forth.
- </P
- ><P
- >
<VAR
- CLASS="varname"
- >$_FILES['userfile']['name'][0]</VAR
- >,
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['tmp_name'][0]</VAR
- >,
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['size'][0]</VAR
- >, and
- <VAR
- CLASS="varname"
- >$_FILES['userfile']['type'][0]</VAR
- > are
- also set.
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="features.file-upload.put-method"
- >PUT method support</A
- ></H2
- ><P
- >
PUT method support has changed between PHP 3 and PHP 4.
- In PHP 4, one should use the standard input stream to read
- the contents of an HTTP PUT.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6803"
- ></A
- ><P
- ><B
- >Example 38-4. Saving HTTP PUT files with PHP 4</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- /* PUT data comes in on the stdin stream */
- $putdata = fopen("php://stdin", "r");
-
- /* Open a file for writing */
- $fp = fopen("myputfile.ext", "w");
-
- /* Read the data 1 KB at a time
- and write to the file */
- while ($data = fread($putdata, 1024))
- fwrite($fp, $data);
-
- /* Close the streams */
- fclose($fp);
- fclose($putdata);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- All documentation below applies to PHP 3 only.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
PHP provides support for the HTTP PUT method used by clients such
- as <SPAN
- CLASS="productname"
- >Netscape Composer</SPAN
- > and W3C <SPAN
- CLASS="productname"
- >Amaya</SPAN
- >.
- PUT requests are much simpler
- than a file upload and they look something like this:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6811"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >PUT /path/filename.html HTTP/1.1</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This would normally mean that the remote client would like to save
- the content that follows as: <TT
- CLASS="filename"
- >/path/filename.html</TT
- > in your web tree.
- It is obviously not a good idea for Apache or PHP to automatically
- let everybody overwrite any files in your web tree. So, to handle
- such a request you have to first tell your web server that you
- want a certain PHP script to handle the request. In Apache you do
- this with the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >Script</I
- ></SPAN
- > directive. It can be
- placed almost anywhere in your Apache configuration file. A
- common place is inside a <Directory> block or perhaps inside
- a <Virtualhost> block. A line like this would do the trick:
- <DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6816"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >Script PUT /put.php</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This tells Apache to send all PUT requests for URIs that match the
- context in which you put this line to the put.php script. This
- assumes, of course, that you have PHP enabled for the .php
- extension and PHP is active.
- </P
- ><P
- >
Inside your put.php file you would then do something like this:
- </P
- ><P
- >
<DIV
- CLASS="informalexample"
- ><P
- ></P
- ><A
- NAME="AEN6821"
- ></A
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php copy($PHP_UPLOADED_FILE_NAME, $DOCUMENT_ROOT . $REQUEST_URI); ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- ></P
- ></DIV
- >
- </P
- ><P
- >
This would copy the file to the location requested by the remote
- client. You would probably want to perform some checks and/or
- authenticate the user before performing this file copy. The only
- trick here is that when PHP sees a PUT-method request it stores
- the uploaded file in a temporary file just like those handled by
- the <A
- HREF="#features.file-upload.post-method"
- >POST-method</A
- >.
- When the request ends, this temporary file is deleted. So, your
- PUT handling PHP script has to copy that file somewhere. The
- filename of this temporary file is in the <VAR
- CLASS="varname"
- >$PHP_PUT_FILENAME</VAR
- >
- variable, and you can see the suggested destination filename in
- the <VAR
- CLASS="varname"
- >$REQUEST_URI</VAR
- > (may vary on non-Apache web servers). This
- destination filename is the one that the remote client specified.
- You do not have to listen to this client. You could, for example,
- copy all uploaded files to a special uploads directory.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.remote-files"
- >Chapter 39. Using remote files</A
- ></H1
- ><P
- >
As long as <VAR
- CLASS="option"
- >allow_url_fopen</VAR
- > is enabled in
- <TT
- CLASS="filename"
- >php.ini</TT
- >, you can use <ACRONYM
- CLASS="acronym"
- >HTTP</ACRONYM
- > and <ACRONYM
- CLASS="acronym"
- >FTP</ACRONYM
- >
- URLs with most of the functions
- that take a filename as a parameter. In addition, URLs can be
- used with the <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >,
- <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >, <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > and
- <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- > statements.
- See <A
- HREF="#wrappers"
- >Appendix L</A
- > for more information about the protocols
- supported by PHP.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 4.0.3 and older, in order to use URL wrappers, you were required
- to configure PHP using the configure option
- <VAR
- CLASS="option"
- >--enable-url-fopen-wrapper</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The Windows versions of PHP earlier than PHP 4.3
- did not support remote file accessing for the following functions:
- <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- >, <A
- HREF="#function.include-once"
- ><B
- CLASS="function"
- >include_once()</B
- ></A
- >,
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- >, <A
- HREF="#function.require-once"
- ><B
- CLASS="function"
- >require_once()</B
- ></A
- >,
- and the imagecreatefromXXX functions in the <A
- HREF="#ref.image"
- >Reference XLVI, <I
- >Image Functions</I
- ></A
- >
- extension.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
For example, you can use this to open a file on a remote web server,
- parse the output for the data you want, and then use that data in a
- database query, or simply to output it in a style matching the rest
- of your website.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6852"
- ></A
- ><P
- ><B
- >Example 39-1. Getting the title of a remote page</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $file = fopen ("http://www.example.com/", "r");
- if (!$file) {
- echo "<p>Unable to open remote file.\n";
- exit;
- }
- while (!feof ($file)) {
- $line = fgets ($file, 1024);
- /* This only works if the title and its tags are on one line */
- if (eregi ("<title>(.*)</title>", $line, $out)) {
- $title = $out[1];
- break;
- }
- }
- fclose($file);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
You can also write to files on an FTP server (provided that you
- have connected as a user with the correct access rights). You
- can only create new files using this method; if you try to overwrite
- a file that already exists, the <A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- > call will
- fail.
- </P
- ><P
- >
To connect as a user other than 'anonymous', you need to specify
- the username (and possibly password) within the URL, such as
- 'ftp://user:password@ftp.example.com/path/to/file'. (You can use the
- same sort of syntax to access files via HTTP when they require Basic
- authentication.)
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN6859"
- ></A
- ><P
- ><B
- >Example 39-2. Storing data on a remote server</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $file = fopen ("ftp://ftp.example.com/incoming/outputfile", "w");
- if (!$file) {
- echo "<p>Unable to open remote file for writing.\n";
- exit;
- }
- /* Write the data here. */
- fwrite ($file, $_SERVER['HTTP_USER_AGENT'] . "\n");
- fclose ($file);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You might get the idea from the example above that you can use
- this technique to write to a remote log file. Unfortunately
- that would not work because the <A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- > call will
- fail if the remote file already exists. To do distributed logging
- like that, you should take a look at <A
- HREF="#function.syslog"
- ><B
- CLASS="function"
- >syslog()</B
- ></A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.connection-handling"
- >Chapter 40. Connection handling</A
- ></H1
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >The following applies to 3.0.7 and later.</P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
Internally in PHP a connection status is maintained. There are 3
- possible states:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >0 - NORMAL</P
- ></LI
- ><LI
- ><P
- >1 - ABORTED</P
- ></LI
- ><LI
- ><P
- >2 - TIMEOUT</P
- ></LI
- ></UL
- >
- </P
- ><P
- >
When a PHP script is running normally the NORMAL state, is active.
- If the remote client disconnects the ABORTED state flag is
- turned on. A remote client disconnect is usually caused by the
- user hitting his STOP button. If the PHP-imposed time limit (see
- <A
- HREF="#function.set-time-limit"
- ><B
- CLASS="function"
- >set_time_limit()</B
- ></A
- >) is hit, the TIMEOUT state flag
- is turned on.</P
- ><P
- >
You can decide whether or not you want a client disconnect to cause
- your script to be aborted. Sometimes it is handy to always have your
- scripts run to completion even if there is no remote browser receiving
- the output. The default behaviour is however for your script to be
- aborted when the remote client disconnects. This behaviour can be
- set via the ignore_user_abort <TT
- CLASS="filename"
- >php.ini</TT
- > directive as well as through
- the corresponding "php_value ignore_user_abort" Apache .conf directive or
- with the <A
- HREF="#function.ignore-user-abort"
- ><B
- CLASS="function"
- >ignore_user_abort()</B
- ></A
- > function. If you do
- not tell PHP to ignore a user abort and the user aborts, your script
- will terminate. The one exception is if you have registered a shutdown
- function using <A
- HREF="#function.register-shutdown-function"
- ><B
- CLASS="function"
- >register_shutdown_function()</B
- ></A
- >. With a
- shutdown function, when the remote user hits his STOP button, the
- next time your script tries to output something PHP will detect that
- the connection has been aborted and the shutdown function is called.
- This shutdown function will also get called at the end of your script
- terminating normally, so to do something different in case of a client
- disconnect you can use the <A
- HREF="#function.connection-aborted"
- ><B
- CLASS="function"
- >connection_aborted()</B
- ></A
- >
- function. This function will return <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if the connection was
- aborted.</P
- ><P
- >
Your script can also be terminated by the built-in script timer.
- The default timeout is 30 seconds. It can be changed using
- the <VAR
- CLASS="option"
- >max_execution_time</VAR
- > <TT
- CLASS="filename"
- >php.ini</TT
- > directive or the corresponding
- <VAR
- CLASS="literal"
- >php_value max_execution_time</VAR
- > Apache .conf directive as well as with
- the <A
- HREF="#function.set-time-limit"
- ><B
- CLASS="function"
- >set_time_limit()</B
- ></A
- > function. When the timer
- expires the script will be aborted and as with the above client
- disconnect case, if a shutdown function has been registered it will
- be called. Within this shutdown function you can check to see if
- a timeout caused the shutdown function to be called by calling the
- <A
- HREF="#function.connection-status"
- ><B
- CLASS="function"
- >connection_status()</B
- ></A
- > function. This function will
- return 2 if a timeout caused the shutdown function to be called.
- </P
- ><P
- >
One thing to note is that both the ABORTED and the TIMEOUT states
- can be active at the same time. This is possible if you tell
- PHP to ignore user aborts. PHP will still note the fact that
- a user may have broken the connection, but the script will keep
- running. If it then hits the time limit it will be aborted and
- your shutdown function, if any, will be called. At this point
- you will find that <A
- HREF="#function.connection-status"
- ><B
- CLASS="function"
- >connection_status()</B
- ></A
- >
- returns 3.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.persistent-connections"
- >Chapter 41. Persistent Database Connections</A
- ></H1
- ><P
- >
Persistent connections are links that do not close when the
- execution of your script ends. When a persistent connection is
- requested, PHP checks if there's already an identical persistent
- connection (that remained open from earlier) - and if it exists, it
- uses it. If it does not exist, it creates the link. An 'identical'
- connection is a connection that was opened to the same host, with
- the same username and the same password (where applicable).
- </P
- ><P
- >
People who aren't thoroughly familiar with the way web servers work
- and distribute the load may mistake persistent connects for what
- they're not. In particular, they do <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > give
- you an ability to open 'user sessions' on the same link, they
- do <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >not</I
- ></SPAN
- > give you an ability to build up a
- transaction efficiently, and they don't do a whole lot of other
- things. In fact, to be extremely clear about the subject,
- persistent connections don't give you <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >any</I
- ></SPAN
- >
- functionality that wasn't possible with their non-persistent
- brothers.
- </P
- ><P
- >
Why?
- </P
- ><P
- >
This has to do with the way web servers work. There are three ways
- in which your web server can utilize PHP to generate web pages.
- </P
- ><P
- >
The first method is to use PHP as a CGI "wrapper". When run this
- way, an instance of the PHP interpreter is created and destroyed
- for every page request (for a PHP page) to your web server.
- Because it is destroyed after every request, any resources that it
- acquires (such as a link to an SQL database server) are closed when
- it is destroyed. In this case, you do not gain anything from trying
- to use persistent connections -- they simply don't persist.
- </P
- ><P
- >
The second, and most popular, method is to run PHP as a module in a
- multiprocess web server, which currently only includes Apache. A
- multiprocess server typically has one process (the parent) which
- coordinates a set of processes (its children) who actually do the
- work of serving up web pages. When a request comes in from a
- client, it is handed off to one of the children that is not already
- serving another client. This means that when the same client makes
- a second request to the server, it may be served by a different
- child process than the first time. When opening a persistent connection,
- every following page requesting SQL services can reuse the same
- established connection to the SQL server.
- </P
- ><P
- >
The last method is to use PHP as a plug-in for a multithreaded web
- server. Currently PHP 4 has support for ISAPI, WSAPI, and NSAPI (on
- Windows), which all allow PHP to be used as a plug-in on multithreaded
- servers like Netscape FastTrack (iPlanet), Microsoft's Internet Information
- Server (IIS), and O'Reilly's WebSite Pro. The behavior is essentially
- the same as for the multiprocess model described before. Note that
- SAPI support is not available in PHP 3.
- </P
- ><P
- >
If persistent connections don't have any added functionality, what
- are they good for?
- </P
- ><P
- >
The answer here is extremely simple -- efficiency. Persistent
- connections are good if the overhead to create a link to your SQL
- server is high. Whether or not this overhead is really high depends
- on many factors. Like, what kind of database it is, whether or not
- it sits on the same computer on which your web server sits, how
- loaded the machine the SQL server sits on is and so forth. The
- bottom line is that if that connection overhead is high, persistent
- connections help you considerably. They cause the child process to
- simply connect only once for its entire lifespan, instead of every
- time it processes a page that requires connecting to the SQL
- server. This means that for every child that opened a persistent
- connection will have its own open persistent connection to the
- server. For example, if you had 20 different child processes that
- ran a script that made a persistent connection to your SQL server,
- you'd have 20 different connections to the SQL server, one from
- each child.
- </P
- ><P
- >
Note, however, that this can have some drawbacks if you are using a
- database with connection limits that are exceeded by persistent
- child connections. If your database has a limit of 16 simultaneous
- connections, and in the course of a busy server session, 17 child
- threads attempt to connect, one will not be able to. If there are
- bugs in your scripts which do not allow the connections to shut
- down (such as infinite loops), the database with only 16 connections
- may be rapidly swamped. Check your database documentation for
- information on handling abandoned or idle connections.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
There are a couple of additional caveats to keep in mind when
- using persistent connections. One is that when using table
- locking on a persistent connection, if the script for whatever
- reason cannot release the lock, then subsequent scripts using the
- same connection will block indefinitely and may require that you
- either restart the httpd server or the database server. Another is
- that when using transactions, a transaction block will also carry
- over to the next script which uses that connection if script execution
- ends before the transaction block does. In either case, you can
- use <A
- HREF="#function.register-shutdown-function"
- ><B
- CLASS="function"
- >register_shutdown_function()</B
- ></A
- > to register a
- simple cleanup function to unlock your tables or roll back your
- transactions. Better yet, avoid the problem entirely by not using
- persistent connections in scripts which use table locks or
- transactions (you can still use them elsewhere).
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
An important summary. Persistent connections were designed to have
- one-to-one mapping to regular connections. That means that you
- should <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >always</I
- ></SPAN
- > be able to replace persistent
- connections with non-persistent connections, and it won't change
- the way your script behaves. It <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >may</I
- ></SPAN
- > (and
- probably will) change the efficiency of the script, but not its
- behavior!
- </P
- ><P
- >
See also <A
- HREF="#function.fbsql-pconnect"
- ><B
- CLASS="function"
- >fbsql_pconnect()</B
- ></A
- >,
- <A
- HREF="#function.ibase-pconnect"
- ><B
- CLASS="function"
- >ibase_pconnect()</B
- ></A
- >, <A
- HREF="#function.ifx-pconnect"
- ><B
- CLASS="function"
- >ifx_pconnect()</B
- ></A
- >,
- <A
- HREF="#function.ingres-pconnect"
- ><B
- CLASS="function"
- >ingres_pconnect()</B
- ></A
- >,
- <A
- HREF="#function.msql-pconnect"
- ><B
- CLASS="function"
- >msql_pconnect()</B
- ></A
- >, <A
- HREF="#function.mssql-pconnect"
- ><B
- CLASS="function"
- >mssql_pconnect()</B
- ></A
- >,
- <A
- HREF="#function.mysql-pconnect"
- ><B
- CLASS="function"
- >mysql_pconnect()</B
- ></A
- >, <A
- HREF="#function.ociplogon"
- ><B
- CLASS="function"
- >ociplogon()</B
- ></A
- >,
- <A
- HREF="#function.odbc-pconnect"
- ><B
- CLASS="function"
- >odbc_pconnect()</B
- ></A
- >, <A
- HREF="#function.ora-plogon"
- ><B
- CLASS="function"
- >ora_plogon()</B
- ></A
- >,
- <A
- HREF="#function.pfsockopen"
- ><B
- CLASS="function"
- >pfsockopen()</B
- ></A
- >, <A
- HREF="#function.pg-pconnect"
- ><B
- CLASS="function"
- >pg_pconnect()</B
- ></A
- >, and
- <A
- HREF="#function.sybase-pconnect"
- ><B
- CLASS="function"
- >sybase_pconnect()</B
- ></A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.safe-mode"
- >Chapter 42. Safe Mode</A
- ></H1
- ><P
- >
The PHP safe mode is an attempt to solve the shared-server security
- problem. It is architecturally incorrect to try to solve this
- problem at the PHP level, but since the alternatives at the web
- server and OS levels aren't very realistic, many people,
- especially ISP's, use safe mode for now.
- </P
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="ini.sect.safe-mode"
- >Security and Safe Mode</A
- ></H2
- ><P
- >
<DIV
- CLASS="table"
- ><A
- NAME="AEN6936"
- ></A
- ><P
- ><B
- >Table 42-1. Security and Safe Mode Configuration Directives</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Name</TH
- ><TH
- >Default</TH
- ><TH
- >Changeable</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >safe_mode</TD
- ><TD
- >"0"</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >safe_mode_gid</TD
- ><TD
- >"0"</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >safe_mode_include_dir</TD
- ><TD
- >NULL</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >safe_mode_exec_dir</TD
- ><TD
- >""</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >safe_mode_allowed_env_vars</TD
- ><TD
- >PHP_</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >safe_mode_protected_env_vars</TD
- ><TD
- >LD_LIBRARY_PATH</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >open_basedir</TD
- ><TD
- >NULL</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >disable_functions</TD
- ><TD
- >""</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ><TR
- ><TD
- >disable_classes</TD
- ><TD
- >""</TD
- ><TD
- >PHP_INI_SYSTEM</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- For further details and definition of the PHP_INI_* constants see
- <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- >.
- </P
- ><P
- >Here's a short explanation of
- the configuration directives.</P
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><A
- NAME="ini.safe-mode"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Whether to enable PHP's safe mode. Read the
- <A
- HREF="#security"
- >Security</A
- > chapter for more
- information.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.safe-mode-gid"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode_gid</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
By default, Safe Mode does a UID compare check when
- opening files. If you want to relax this to a GID compare,
- then turn on safe_mode_gid.
- Whether to use <VAR
- CLASS="literal"
- >UID</VAR
- > (<TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >) or
- <VAR
- CLASS="literal"
- >GID</VAR
- > (<TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >) checking upon file
- access.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.safe-mode-include-dir"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode_include_dir</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
<VAR
- CLASS="literal"
- >UID</VAR
- >/<VAR
- CLASS="literal"
- >GID</VAR
- > checks are bypassed when
- including files from this directory and its subdirectories (directory
- must also be in <A
- HREF="#ini.include-path"
- >include_path</A
- >
- or full path must including).
- </P
- ><P
- >
As of PHP 4.2.0, this directive can take a colon (semi-colon on
- Windows) separated path in a fashion similar to the
- <A
- HREF="#ini.include-path"
- >include_path</A
- > directive,
- rather than just a single directory.
- </P
- ><P
- >
The restriction specified is actually a prefix, not a directory name.
- This means that "safe_mode_include_dir = /dir/incl" also allows
- access to "/dir/include" and "/dir/incls" if they exist. When you
- want to restrict access to only the specified directory, end with a
- slash. For example: "safe_mode_include_dir = /dir/incl/"
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.safe-mode-exec-dir"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode_exec_dir</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
If PHP is used in safe mode, <A
- HREF="#function.system"
- ><B
- CLASS="function"
- >system()</B
- ></A
- > and the other
- <A
- HREF="#ref.exec"
- >functions executing system programs</A
- >
- refuse to start programs that are not in this directory.
- You have to use <VAR
- CLASS="literal"
- >/</VAR
- > as directory separator on all
- environments including Windows.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.safe-mode-allowed-env-vars"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode_allowed_env_vars</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
Setting certain environment variables may be a potential security breach.
- This directive contains a comma-delimited list of prefixes. In Safe Mode,
- the user may only alter environment variables whose names begin with the
- prefixes supplied here. By default, users will only be able to set
- environment variables that begin with PHP_ (e.g. PHP_FOO=BAR).
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If this directive is empty, PHP will let the user modify ANY
- environment variable!
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DD
- ><DT
- ><A
- NAME="ini.safe-mode-protected-env-vars"
- ></A
- ><VAR
- CLASS="parameter"
- >safe_mode_protected_env_vars</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
This directive contains a comma-delimited list of environment
- variables that the end user won't be able to change using
- <A
- HREF="#function.putenv"
- ><B
- CLASS="function"
- >putenv()</B
- ></A
- >. These variables will be protected
- even if safe_mode_allowed_env_vars is set to allow to change them.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.open-basedir"
- ></A
- ><VAR
- CLASS="parameter"
- >open_basedir</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
Limit the files that can be opened by PHP to the specified
- directory-tree, including the file itself. This directive
- is <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >NOT</I
- ></SPAN
- > affected by whether Safe Mode is
- turned On or Off.
- </P
- ><P
- >
When a script tries to open a file with, for example,
- <A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- > or <A
- HREF="#function.gzopen"
- ><B
- CLASS="function"
- >gzopen()</B
- ></A
- >,
- the location of the file is checked. When the file is outside the
- specified directory-tree, PHP will refuse to open it. All symbolic
- links are resolved, so it's not possible to avoid this restriction
- with a symlink.
- </P
- ><P
- >
The special value <SPAN
- CLASS="systemitem"
- >.</SPAN
- >
- indicates that the working directory of the script will be used as the
- base-directory. This is, however, a little dangerous as the working directory
- of the script can easily be changed with <A
- HREF="#function.chdir"
- ><B
- CLASS="function"
- >chdir()</B
- ></A
- >.
- </P
- ><P
- >
In <TT
- CLASS="filename"
- >httpd.conf</TT
- >, open_basedir can be turned off
- (e.g. for some virtual hosts)
- <A
- HREF="#configuration.changes.apache"
- >the same way</A
- > as
- any other configuration directive with "php_admin_value open_basedir
- none".
- </P
- ><P
- >
Under Windows, separate the directories with a semicolon. On all
- other systems, separate the directories with a colon. As an Apache
- module, open_basedir paths from parent directories are now
- automatically inherited.
- </P
- ><P
- >
The restriction specified with open_basedir is actually a
- prefix, not a directory name. This means that "open_basedir =
- /dir/incl" also allows access to "/dir/include" and
- "/dir/incls" if they exist. When you want to restrict access
- to only the specified directory, end with a slash. For example:
- "open_basedir = /dir/incl/"
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Support for multiple directories was added in 3.0.7.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
The default is to allow all files to be opened.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.disable-functions"
- ></A
- ><VAR
- CLASS="parameter"
- >disable_functions</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
This directive allows you to disable certain functions for
- <A
- HREF="#security"
- >security</A
- > reasons. It takes
- on a comma-delimited list of function names. disable_functions
- is not affected by <A
- HREF="#ini.safe-mode"
- >Safe Mode</A
- >.
- </P
- ><P
- >
This directive must be set in <TT
- CLASS="filename"
- >php.ini</TT
- > For example, you
- cannot set this in <TT
- CLASS="filename"
- >httpd.conf</TT
- >.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.disable-classes"
- ></A
- ><VAR
- CLASS="parameter"
- >disable_classes</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
This directive allows you to disable certain classes for
- <A
- HREF="#security"
- >security</A
- > reasons. It takes
- on a comma-delimited list of class names. disable_classes
- is not affected by <A
- HREF="#ini.safe-mode"
- >Safe Mode</A
- >.
- </P
- ><P
- >
This directive must be set in <TT
- CLASS="filename"
- >php.ini</TT
- > For example, you
- cannot set this in <TT
- CLASS="filename"
- >httpd.conf</TT
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Availability note: </B
- >
- This directive became available in PHP 4.3.2
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- >
See also: <A
- HREF="#ini.register-globals"
- >register_globals</A
- >,
- <A
- HREF="#ini.display-errors"
- >display_errors</A
- >, and
- <A
- HREF="#ini.log-errors"
- >log_errors</A
- >
- </P
- ><P
- >
When <A
- HREF="#ini.safe-mode"
- >safe_mode</A
- > is on, PHP checks to see
- if the owner of the current script matches the owner of the file to be
- operated on by a file function or its directory. For example:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ls"
- >-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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Running this script.php
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- readfile('/etc/passwd');
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- results in this error when safe mode is enabled:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
However, there may be environments where a strict <VAR
- CLASS="literal"
- >UID</VAR
- >
- check is not appropriate and a relaxed <VAR
- CLASS="literal"
- >GID</VAR
- > check is
- sufficient. This is supported by means of the <A
- HREF="#ini.safe-mode-gid"
- >safe_mode_gid</A
- > switch. Setting it to
- <VAR
- CLASS="literal"
- >On</VAR
- > performs the relaxed <VAR
- CLASS="literal"
- >GID</VAR
- > checking,
- setting it to <VAR
- CLASS="literal"
- >Off</VAR
- > (the default) performs
- <VAR
- CLASS="literal"
- >UID</VAR
- > checking.
- </P
- ><P
- >
If instead of <A
- HREF="#ini.safe-mode"
- >safe_mode</A
- >, you set an
- <A
- HREF="#ini.open-basedir"
- >open_basedir</A
- > directory then all
- file operations will be limited to files under the specified directory
- For example (Apache <TT
- CLASS="filename"
- >httpd.conf</TT
- > example):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- ><Directory /docroot>
- php_admin_value open_basedir /docroot
- </Directory></PRE
- ></TD
- ></TR
- ></TABLE
- >
- If you run the same script.php with this
- <A
- HREF="#ini.open-basedir"
- >open_basedir</A
- > setting
- then this is the result:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Warning: open_basedir restriction in effect. File is in wrong directory in
- /docroot/script.php on line 2</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
You can also disable individual functions. Note that the
- <A
- HREF="#ini.disable-functions"
- >disable_functions</A
- >
- directive can not be used outside of the <TT
- CLASS="filename"
- >php.ini</TT
- > file which means that
- you cannot disable functions on a per-virtualhost or per-directory basis
- in your <TT
- CLASS="filename"
- >httpd.conf</TT
- > file.
- If we add this to our <TT
- CLASS="filename"
- >php.ini</TT
- > file:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="ini"
- >disable_functions readfile,system</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Then we get this output:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Warning: readfile() has been disabled for security reasons in
- /docroot/script.php on line 2</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="sect1"
- ><HR><H2
- CLASS="sect1"
- ><A
- NAME="features.safe-mode.functions"
- >Functions restricted/disabled by safe mode</A
- ></H2
- ><P
- >
This is a still probably incomplete and possibly incorrect listing
- of the functions limited by
- <A
- HREF="#features.safe-mode"
- >safe mode</A
- >.
-
- <DIV
- CLASS="table"
- ><A
- NAME="AEN7119"
- ></A
- ><P
- ><B
- >Table 42-2. Safe mode limited functions</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >Function</TH
- ><TH
- >Limitations</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- ><A
- HREF="#function.dbmopen"
- ><B
- CLASS="function"
- >dbmopen()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.dbase-open"
- ><B
- CLASS="function"
- >dbase_open()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.filepro"
- ><B
- CLASS="function"
- >filepro()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.filepro-rowcount"
- ><B
- CLASS="function"
- >filepro_rowcount()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.filepro-retrieve"
- ><B
- CLASS="function"
- >filepro_retrieve()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- >ifx_*</TD
- ><TD
- >sql_safe_mode restrictions, (!= safe mode)</TD
- ></TR
- ><TR
- ><TD
- >ingres_*</TD
- ><TD
- >sql_safe_mode restrictions, (!= safe mode)</TD
- ></TR
- ><TR
- ><TD
- >mysql_*</TD
- ><TD
- >sql_safe_mode restrictions, (!= safe mode)</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.pg-lo-import"
- ><B
- CLASS="function"
- >pg_lo_import()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.posix-mkfifo"
- ><B
- CLASS="function"
- >posix_mkfifo()</B
- ></A
- ></TD
- ><TD
- >Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.putenv"
- ><B
- CLASS="function"
- >putenv()</B
- ></A
- ></TD
- ><TD
- >Obeys the safe_mode_protected_env_vars and
- safe_mode_allowed_env_vars ini-directives. See also the documentation
- on <A
- HREF="#function.putenv"
- ><B
- CLASS="function"
- >putenv()</B
- ></A
- ></TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.move-uploaded-file"
- ><B
- CLASS="function"
- >move_uploaded_file()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. </TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.chdir"
- ><B
- CLASS="function"
- >chdir()</B
- ></A
- ></TD
- ><TD
- >Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.dl"
- ><B
- CLASS="function"
- >dl()</B
- ></A
- ></TD
- ><TD
- >This function is disabled in <A
- HREF="#features.safe-mode"
- >safe mode</A
- >.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#language.operators.execution"
- >backtick operator</A
- ></TD
- ><TD
- >This function is disabled in <A
- HREF="#features.safe-mode"
- >safe mode</A
- >.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.shell-exec"
- ><B
- CLASS="function"
- >shell_exec()</B
- ></A
- > (functional equivalent
- of backticks)</TD
- ><TD
- >This function is disabled in <A
- HREF="#features.safe-mode"
- >safe mode</A
- >.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.exec"
- ><B
- CLASS="function"
- >exec()</B
- ></A
- ></TD
- ><TD
- >You can only execute executables within the <A
- HREF="#ini.safe-mode-exec-dir"
- >safe_mode_exec_dir</A
- >.
- For practical reasons it's currently not allowed to have
- <VAR
- CLASS="literal"
- >..</VAR
- > components in the path to the executable.
- <A
- HREF="#function.escapeshellcmd"
- ><B
- CLASS="function"
- >escapeshellcmd()</B
- ></A
- > is executed on the argument of this
- function.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.system"
- ><B
- CLASS="function"
- >system()</B
- ></A
- ></TD
- ><TD
- >You can only execute executables within the <A
- HREF="#ini.safe-mode-exec-dir"
- >safe_mode_exec_dir</A
- >.
- For practical reasons it's currently not allowed to have
- <VAR
- CLASS="literal"
- >..</VAR
- > components in the path to the executable.
- <A
- HREF="#function.escapeshellcmd"
- ><B
- CLASS="function"
- >escapeshellcmd()</B
- ></A
- > is executed on the argument of this
- function.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.passthru"
- ><B
- CLASS="function"
- >passthru()</B
- ></A
- ></TD
- ><TD
- >You can only execute executables within the <A
- HREF="#ini.safe-mode-exec-dir"
- >safe_mode_exec_dir</A
- >.
- For practical reasons it's currently not allowed to have
- <VAR
- CLASS="literal"
- >..</VAR
- > components in the path to the executable.
- <A
- HREF="#function.escapeshellcmd"
- ><B
- CLASS="function"
- >escapeshellcmd()</B
- ></A
- > is executed on the argument of this
- function.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.popen"
- ><B
- CLASS="function"
- >popen()</B
- ></A
- ></TD
- ><TD
- >You can only execute executables within the <A
- HREF="#ini.safe-mode-exec-dir"
- >safe_mode_exec_dir</A
- >.
- For practical reasons it's currently not allowed to have
- <VAR
- CLASS="literal"
- >..</VAR
- > components in the path to the executable.
- <A
- HREF="#function.escapeshellcmd"
- ><B
- CLASS="function"
- >escapeshellcmd()</B
- ></A
- > is executed on the argument of this
- function.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.fopen"
- ><B
- CLASS="function"
- >fopen()</B
- ></A
- ></TD
- ><TD
- >Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.mkdir"
- ><B
- CLASS="function"
- >mkdir()</B
- ></A
- ></TD
- ><TD
- >Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.rmdir"
- ><B
- CLASS="function"
- >rmdir()</B
- ></A
- ></TD
- ><TD
- >Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.rename"
- ><B
- CLASS="function"
- >rename()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.unlink"
- ><B
- CLASS="function"
- >unlink()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.copy"
- ><B
- CLASS="function"
- >copy()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed. (on
- <VAR
- CLASS="parameter"
- >source</VAR
- > and
- <VAR
- CLASS="parameter"
- >target</VAR
- >) </TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.chgrp"
- ><B
- CLASS="function"
- >chgrp()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.chown"
- ><B
- CLASS="function"
- >chown()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.chmod"
- ><B
- CLASS="function"
- >chmod()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. In addition, you cannot
- set the SUID, SGID and sticky bits</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.touch"
- ><B
- CLASS="function"
- >touch()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.symlink"
- ><B
- CLASS="function"
- >symlink()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed. (note: only the target is
- checked)</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.link"
- ><B
- CLASS="function"
- >link()</B
- ></A
- ></TD
- ><TD
- >Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed. (note: only the target is
- checked)</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- ></TD
- ><TD
- >In safe mode, headers beginning with 'authorization'
- (case-insensitive) will not be returned.</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#function.header"
- ><B
- CLASS="function"
- >header()</B
- ></A
- ></TD
- ><TD
- >In safe mode, the uid of the script is added to the
- <VAR
- CLASS="literal"
- >realm</VAR
- > part of the
- <VAR
- CLASS="literal"
- >WWW-Authenticate</VAR
- > header if you set this
- header (used for HTTP Authentication).</TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#features.http-auth"
- >PHP_AUTH variables</A
- ></TD
- ><TD
- >
In safe mode, the variables <VAR
- CLASS="varname"
- >PHP_AUTH_USER</VAR
- >,
- <VAR
- CLASS="varname"
- >PHP_AUTH_PW</VAR
- >, and <VAR
- CLASS="varname"
- >AUTH_TYPE</VAR
- >
- are not available in <VAR
- CLASS="varname"
- >$_SERVER</VAR
- >. Regardless, you
- can still use <VAR
- CLASS="varname"
- >REMOTE_USER</VAR
- > for the USER.
- (note: only affected since PHP 4.3.0)
- </TD
- ></TR
- ><TR
- ><TD
- >
<A
- HREF="#function.highlight-file"
- ><B
- CLASS="function"
- >highlight_file()</B
- ></A
- >,
- <A
- HREF="#function.show-source"
- ><B
- CLASS="function"
- >show_source()</B
- ></A
- >
- </TD
- ><TD
- >
Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed. (note: only affected since PHP 4.2.1)
- </TD
- ></TR
- ><TR
- ><TD
- >
<A
- HREF="#function.parse-ini-file"
- ><B
- CLASS="function"
- >parse_ini_file()</B
- ></A
- >
- </TD
- ><TD
- >
Checks whether the files or directories you are
- about to operate on have the same UID (owner) as the script that is being
- executed. Checks whether the directory in which
- you are about to operate has the same UID (owner) as the script that is being
- executed. (note: only affected since PHP 4.2.1)
- </TD
- ></TR
- ><TR
- ><TD
- >
<A
- HREF="#function.set-time-limit"
- ><B
- CLASS="function"
- >set_time_limit()</B
- ></A
- >
- </TD
- ><TD
- >
Has no affect when PHP is running in <A
- HREF="#ini.safe-mode"
- >safe mode</A
- >.
- </TD
- ></TR
- ><TR
- ><TD
- >
<A
- HREF="#ini.max-execution-time"
- >max_execution_time</A
- >
- </TD
- ><TD
- >
Has no affect when PHP is running in <A
- HREF="#ini.safe-mode"
- >safe mode</A
- >.
- </TD
- ></TR
- ><TR
- ><TD
- >
<A
- HREF="#function.mail"
- ><B
- CLASS="function"
- >mail()</B
- ></A
- >
- </TD
- ><TD
- >
In safe mode, the fifth parameter is disabled. (note: only affected since PHP 4.2.3)
- </TD
- ></TR
- ><TR
- ><TD
- >Any function that uses
- <TT
- CLASS="filename"
- >php4/main/fopen_wrappers.c</TT
- >
- </TD
- ><TD
- >??</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="chapter"
- ><HR><H1
- ><A
- NAME="features.commandline"
- >Chapter 43. Using PHP from the command line</A
- ></H1
- ><P
- >
As of version 4.3.0, PHP supports a new
- <VAR
- CLASS="literal"
- >SAPI</VAR
- > type (Server Application Programming Interface)
- named <VAR
- CLASS="literal"
- >CLI</VAR
- > which means <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >Command Line
- Interface</I
- ></SPAN
- >. As the name implies, this <VAR
- CLASS="literal"
- >SAPI</VAR
- > type
- main focus is on developing shell (or desktop as well) applications with
- PHP. There are quite a few differences between the
- <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > and other <VAR
- CLASS="literal"
- >SAPI</VAR
- >s which are
- explained in this chapter. It's worth mentioning
- that <VAR
- CLASS="literal"
- >CLI</VAR
- > and <VAR
- CLASS="literal"
- >CGI</VAR
- > are different
- SAPI's although they do share many of the same behaviors.
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > was released for the first time with
- PHP 4.2.0, but was still experimental and had
- to be explicitly enabled with <VAR
- CLASS="option"
- >--enable-cli</VAR
- > when running
- <B
- CLASS="command"
- >./configure</B
- >. Since PHP 4.3.0 the
- <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > is no longer experimental and the option
- <VAR
- CLASS="option"
- >--enable-cli</VAR
- > is on by default. You may use
- <VAR
- CLASS="option"
- >--disable-cli</VAR
- > to disable it.
- </P
- ><P
- >
As of PHP 4.3.0, the name, location and existence of the CLI/CGI binaries
- will differ depending on how PHP is installed on your system. By default
- when executing <B
- CLASS="command"
- >make</B
- >, both the CGI and CLI are built and
- placed as <TT
- CLASS="filename"
- >sapi/cgi/php</TT
- > and <TT
- CLASS="filename"
- >sapi/cli/php</TT
- >
- respectively, in your PHP source directory. You will note that both are
- named php. What happens during <B
- CLASS="command"
- >make install</B
- > depends on
- your configure line. If a module SAPI is chosen during configure, such as apxs, or the
- <VAR
- CLASS="option"
- >--disable-cgi</VAR
- > option is used, the CLI is copied to
- <TT
- CLASS="filename"
- >{PREFIX}/bin/php</TT
- > during <B
- CLASS="command"
- >make install</B
- >
- otherwise the CGI is placed there. So, for example, if <VAR
- CLASS="option"
- >--with--apxs
- </VAR
- > is in your configure line then the CLI is copied to
- <TT
- CLASS="filename"
- >{PREFIX}/bin/php</TT
- > during <B
- CLASS="command"
- >make
- install</B
- >. If you want to override the installation of the CGI
- binary, use <B
- CLASS="command"
- >make install-cli</B
- > after <B
- CLASS="command"
- >make
- install</B
- >. Alternatively you can specify <VAR
- CLASS="option"
- >
--disable-cgi</VAR
- > in your configure line.
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Because both <VAR
- CLASS="option"
- >--enable-cli</VAR
- > and
- <VAR
- CLASS="option"
- >--enable-cgi</VAR
- > are enabled by default,
- simply having <VAR
- CLASS="option"
- >--enable-cli</VAR
- > in your
- configure line does not necessarily mean the CLI will be copied as
- <TT
- CLASS="filename"
- >{PREFIX}/bin/php</TT
- > during <B
- CLASS="command"
- >make install</B
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
The windows packages between PHP 4.2.0 and PHP 4.2.3 distributed the CLI as
- <TT
- CLASS="filename"
- >php-cli.exe</TT
- >, living in the same folder as the CGI
- <TT
- CLASS="filename"
- >php.exe</TT
- >. Starting with PHP 4.3.0 the windows package
- distributes the CLI as <TT
- CLASS="filename"
- >php.exe</TT
- > in a separate folder
- named <TT
- CLASS="filename"
- >cli</TT
- >, so <TT
- CLASS="filename"
- >cli/php.exe
- </TT
- >. Starting with PHP 5, the CLI is distributed in the main folder,
- named <TT
- CLASS="filename"
- >php.exe</TT
- >. The CGI version is distributed as
- <TT
- CLASS="filename"
- >php-cgi.exe</TT
- >.
- </P
- ><P
- >
As of PHP 5, a new <TT
- CLASS="filename"
- >php-win.exe</TT
- > file is distributed.
- This is equal to the CLI version, except that php-win doesn't output
- anything and thus provides no console (no "dos box" appears on the screen).
- This behavior is similar to php-gtk. You should configure with
- <VAR
- CLASS="option"
- >--enable-cli-win32</VAR
- >.
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >What SAPI do I have?: </B
- >
- From a shell, typing <B
- CLASS="command"
- >php -v</B
- > will tell you
- whether <TT
- CLASS="filename"
- >php</TT
- > is CGI or CLI. See also the function
- <A
- HREF="#function.php-sapi-name"
- ><B
- CLASS="function"
- >php_sapi_name()</B
- ></A
- > and the constant <TT
- CLASS="constant"
- ><B
- >
PHP_SAPI</B
- ></TT
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
<DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- A Unix <VAR
- CLASS="literal"
- >man</VAR
- >ual page was added in PHP 4.3.2. You may
- view this by typing <B
- CLASS="command"
- >man php</B
- > in your shell environment.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ><P
- >
Remarkable differences of the <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > compared to other
- <VAR
- CLASS="literal"
- >SAPI</VAR
- >s:
- <P
- ></P
- ><UL
- ><LI
- ><P
- >
Unlike the <VAR
- CLASS="literal"
- >CGI SAPI</VAR
- >, no headers are written to the
- output.
- </P
- ><P
- >
Though the <VAR
- CLASS="literal"
- >CGI SAPI</VAR
- > provides a way to suppress HTTP
- headers, there's no equivalent switch to enable them in the <VAR
- CLASS="literal"
- >CLI
- SAPI</VAR
- >.
- </P
- ><P
- >
CLI is started up in quiet mode by default, though the <VAR
- CLASS="option"
- >-q</VAR
- >
- and <VAR
- CLASS="option"
- >--no-header</VAR
- > switches are kept for compatibility so
- that you can use older CGI scripts.
- </P
- ><P
- >
It does not change the working directory to that of the script.
- (<VAR
- CLASS="option"
- >-C</VAR
- > and <VAR
- CLASS="option"
- >--no-chdir</VAR
- > switches kept for
- compatibility)
- </P
- ><P
- >
Plain text error messages (no HTML formatting).
- </P
- ></LI
- ><LI
- ><P
- >
There are certain <TT
- CLASS="filename"
- >php.ini</TT
- > directives which are overridden by the <VAR
- CLASS="literal"
- >CLI
- SAPI</VAR
- > because they do not make sense in shell environments:
- </P
- ><P
- >
<DIV
- CLASS="table"
- ><A
- NAME="AEN7402"
- ></A
- ><P
- ><B
- >Table 43-1. Overridden <TT
- CLASS="filename"
- >php.ini</TT
- > directives</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Directive</TH
- ><TH
- ><VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > default value</TH
- ><TH
- >Comment</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- ><A
- HREF="#ini.html-errors"
- >html_errors</A
- ></TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- ></TD
- ><TD
- >
It can be quite hard to read the error message in your shell when
- it's cluttered with all those meaningless <VAR
- CLASS="literal"
- >HTML</VAR
- >
- tags, therefore this directive defaults to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
- </TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#ini.implicit-flush"
- >implicit_flush</A
- ></TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- ></TD
- ><TD
- >
It is desired that any output coming from
- <A
- HREF="#function.print"
- ><B
- CLASS="function"
- >print()</B
- ></A
- >, <A
- HREF="#function.echo"
- ><B
- CLASS="function"
- >echo()</B
- ></A
- > and friends is
- immediately written to the output and not cached in any buffer. You
- still can use <A
- HREF="#ref.outcontrol"
- >output buffering</A
- >
- if you want to defer or manipulate standard output.
- </TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#ini.max-execution-time"
- >max_execution_time</A
- ></TD
- ><TD
- >0 (unlimited)</TD
- ><TD
- >
Due to endless possibilities of using PHP in
- shell environments, the maximum execution time has been set to
- unlimited. Whereas applications written for the web are often
- executed very quickly, shell application tend to have a much
- longer execution time.
- </TD
- ></TR
- ><TR
- ><TD
- ><A
- HREF="#ini.register-argc-argv"
- >register_argc_argv</A
- ></TD
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- ></TD
- ><TD
- >
<P
- >
Because this setting is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > you will always have access to
- <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >argc</I
- ></SPAN
- > (number of arguments passed to the
- application) and <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >argv</I
- ></SPAN
- > (array of the actual
- arguments) in the <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- >.
- </P
- >
- <P
- >
As of PHP 4.3.0, the PHP variables <VAR
- CLASS="varname"
- >$argc</VAR
- >
- and <VAR
- CLASS="varname"
- >$argv</VAR
- > are registered and filled in with the appropriate
- values when using the <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- >. Prior to this version,
- the creation of these variables behaved as they do in
- <VAR
- CLASS="literal"
- >CGI</VAR
- > and <VAR
- CLASS="literal"
- >MODULE</VAR
- > versions
- which requires the PHP directive
- <A
- HREF="#ini.register-globals"
- >register_globals</A
- > to
- be <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >on</I
- ></SPAN
- >. Regardless of version or register_globals
- setting, you can always go through either
- <A
- HREF="#reserved.variables.server"
- >$_SERVER</A
- > or
- <VAR
- CLASS="varname"
- >$HTTP_SERVER_VARS</VAR
- >. Example:
- <VAR
- CLASS="varname"
- >$_SERVER['argv']</VAR
- >
- </P
- >
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- These directives cannot be initialized with another value from the
- configuration file <TT
- CLASS="filename"
- >php.ini</TT
- > or a custom one (if specified). This is a
- limitation because those default values are applied after all
- configuration files have been parsed. However, their value can be changed
- during runtime (which does not make sense for all of those directives,
- e.g. <A
- HREF="#ini.register-argc-argv"
- >register_argc_argv</A
- >).
- </P
- ></BLOCKQUOTE
- ></DIV
- ></LI
- ><LI
- ><P
- >
To ease working in the shell environment, the following constants
- are defined:
- <DIV
- CLASS="table"
- ><A
- NAME="AEN7463"
- ></A
- ><P
- ><B
- >Table 43-2. CLI specific Constants</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >Constant</TH
- ><TH
- >Description</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >STDIN</B
- ></TT
- ></TD
- ><TD
- >
An already opened stream to <VAR
- CLASS="literal"
- >stdin</VAR
- >. This saves
- opening it with
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $stdin = fopen('php://stdin', 'r');
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- If you want to read single line from <VAR
- CLASS="literal"
- >stdin</VAR
- >, you can
- use
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $line = trim(fgets(STDIN)); // reads one line from STDIN
- fscanf(STDIN, "%d\n", $number); // reads number from STDIN
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >STDOUT</B
- ></TT
- ></TD
- ><TD
- >
An already opened stream to <VAR
- CLASS="literal"
- >stdout</VAR
- >. This saves
- opening it with
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $stdout = fopen('php://stdout', 'w');
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </TD
- ></TR
- ><TR
- ><TD
- ><TT
- CLASS="constant"
- ><B
- >STDERR</B
- ></TT
- ></TD
- ><TD
- >
An already opened stream to <VAR
- CLASS="literal"
- >stderr</VAR
- >. This saves
- opening it with
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $stderr = fopen('php://stderr', 'w');
-
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
Given the above, you don't need to open e.g. a stream for
- <VAR
- CLASS="literal"
- >stderr</VAR
- > yourself but simply use the constant instead of
- the stream resource:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >php -r 'fwrite(STDERR, "stderr\n");'</PRE
- ></TD
- ></TR
- ></TABLE
- >
- You do not need to explicitly close these streams, as they are closed
- automatically by PHP when your script ends.
- </P
- ></LI
- ><LI
- ><P
- >
The <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > does <SPAN
- CLASS="strong"
- ><B
- CLASS="emphasis"
- >not</B
- ></SPAN
- > change the current directory to the directory
- of the executed script!
- </P
- ><P
- >
Example showing the difference to the <VAR
- CLASS="literal"
- >CGI SAPI</VAR
- >:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Our simple test application named test.php
- echo getcwd(), "\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
When using the <VAR
- CLASS="literal"
- >CGI</VAR
- > version, the output is:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ pwd
- /tmp
-
- $ php -q another_directory/test.php
- /tmp/another_directory</PRE
- ></TD
- ></TR
- ></TABLE
- >
- This clearly shows that PHP changes its current
- directory to the one of the executed script.
- </P
- ><P
- >
Using the <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > yields:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ pwd
- /tmp
-
- $ php -f another_directory/test.php
- /tmp</PRE
- ></TD
- ></TR
- ></TABLE
- >
- This allows greater flexibility when writing shell tools in
- PHP.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The <VAR
- CLASS="literal"
- >CGI SAPI</VAR
- > supports this <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- >
- behaviour by means of the <VAR
- CLASS="option"
- >-C</VAR
- > switch when run from the
- command line.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></LI
- ></UL
- >
- </P
- ><P
- >
The list of command line options provided by the PHP
- binary can be queried anytime by running PHP with the
- <VAR
- CLASS="option"
- >-h</VAR
- > switch:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The <VAR
- CLASS="literal"
- >CLI SAPI</VAR
- > has three different ways of getting the
- PHP code you want to execute:
- <P
- ></P
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
Telling PHP to execute a certain file.
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >php my_script.php
-
- php -f my_script.php</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Both ways (whether using the <VAR
- CLASS="option"
- >-f</VAR
- > switch or not) execute
- the file <TT
- CLASS="filename"
- >my_script.php</TT
- >. You can choose any file to
- execute - your PHP scripts do not have to end with the
- <VAR
- CLASS="literal"
- >.php</VAR
- > extension but can have any name or extension
- you wish.
- </P
- ></LI
- ><LI
- ><P
- >
Pass the PHP code to execute directly on the command
- line.
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >php -r 'print_r(get_defined_constants());'</PRE
- ></TD
- ></TR
- ></TABLE
- >
- Special care has to be taken in regards of shell variable substitution and
- quoting usage.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Read the example carefully, there are no beginning or ending tags! The
- <VAR
- CLASS="option"
- >-r</VAR
- > switch simply does not need them. Using them will
- lead to a parser error.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></LI
- ><LI
- ><P
- >
Provide the PHP code to execute via standard input
- (<VAR
- CLASS="literal"
- >stdin</VAR
- >).
- </P
- ><P
- >
This gives the powerful ability to dynamically create
- PHP code and feed it to the binary, as shown in this
- (fictional) example:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ some_application | some_filter | php | sort -u >final_output.txt</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></LI
- ></OL
- >
- You cannot combine any of the three ways to execute code.
- </P
- ><P
- >
Like every shell application, the PHP binary
- accepts a number of arguments but your PHP script can
- also receive arguments. The number of arguments which can be passed to your script
- is not limited by PHP (the shell has a certain size limit
- in the number of characters which can be passed; usually you won't hit this
- limit). The arguments passed to your script are available in the global
- array <VAR
- CLASS="varname"
- >$argv</VAR
- >. The zero index always contains the script
- name (which is <VAR
- CLASS="literal"
- >-</VAR
- > in case the PHP code
- is coming from either standard input or from the command line switch
- <VAR
- CLASS="option"
- >-r</VAR
- >). The second registered global variable is
- <VAR
- CLASS="varname"
- >$argc</VAR
- > which contains the number of elements in the
- <VAR
- CLASS="varname"
- >$argv</VAR
- > array (<SPAN
- CLASS="strong"
- ><B
- CLASS="emphasis"
- >not</B
- ></SPAN
- > the
- number of arguments passed to the script).
- </P
- ><P
- >
As long as the arguments you want to pass to your script do not start with
- the <VAR
- CLASS="literal"
- >-</VAR
- > character, there's nothing special to watch out
- for. Passing an argument to your script which starts with a
- <VAR
- CLASS="literal"
- >-</VAR
- > will cause trouble because PHP
- itself thinks it has to handle it. To prevent this, use the argument list
- separator <VAR
- CLASS="literal"
- >--</VAR
- >. After this separator has been parsed by
- PHP, every argument following it is passed
- untouched to your script.
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- ># This will not execute the given code but will show the PHP usage
- $ php -r 'var_dump($argv);' -h
- Usage: php [options] [-f] <file> [args...]
- [...]
-
- # This will pass the '-h' argument to your script and prevent PHP from showing it's usage
- $ php -r 'var_dump($argv);' -- -h
- array(2) {
- [0]=>
- string(1) "-"
- [1]=>
- string(2) "-h"
- }</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
However, there's another way of using PHP for shell
- scripting. You can write a script where the first line starts with
- <VAR
- CLASS="literal"
- >#!/usr/bin/php</VAR
- >. Following this you can place
- normal PHP code included within the PHP
- starting and end tags. Once you have set the execution attributes of the file
- appropriately (e.g. <B
- CLASS="command"
- >chmod +x test</B
- >) your script can be
- executed like a normal shell or perl script:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >#!/usr/bin/php
- <?php
- var_dump($argv);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- Assuming this file is named <TT
- CLASS="filename"
- >test</TT
- > in the current
- directory, we can now do the following:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ chmod +x test
- $ ./test -h -- foo
- array(4) {
- [0]=>
- string(6) "./test"
- [1]=>
- string(2) "-h"
- [2]=>
- string(2) "--"
- [3]=>
- string(3) "foo"
- }</PRE
- ></TD
- ></TR
- ></TABLE
- >
- As you see, in this case no care needs to be taken when passing parameters
- which start with <VAR
- CLASS="literal"
- >-</VAR
- > to your script.
- </P
- ><P
- >
Long options are available since PHP 4.3.3.
- <DIV
- CLASS="table"
- ><A
- NAME="AEN7558"
- ></A
- ><P
- ><B
- >Table 43-3. Command line options</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><THEAD
- ><TR
- ><TH
- >Option</TH
- ><TH
- >Long Option</TH
- ><TH
- >Description</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >-s</TD
- ><TD
- >--syntax-highlight</TD
- ><TD
- >
<P
- >
Display colour syntax highlighted source.
- </P
- >
- <P
- >
This option uses the internal mechanism to parse the file and produces
- a <VAR
- CLASS="literal"
- >HTML</VAR
- > highlighted version of it and writes it to
- standard output. Note that all it does it to generate a block of
- <VAR
- CLASS="literal"
- ><code> [...] </code></VAR
- >
- <VAR
- CLASS="literal"
- >HTML</VAR
- > tags, no <VAR
- CLASS="literal"
- >HTML</VAR
- > headers.
- </P
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This option does not work together with the <VAR
- CLASS="option"
- >-r</VAR
- >
- option.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-s</TD
- ><TD
- >--syntax-highlighting</TD
- ><TD
- >
<P
- >
Alias of <VAR
- CLASS="option"
- >--syntax-highlight</VAR
- >.
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-w</TD
- ><TD
- >--strip</TD
- ><TD
- >
<P
- >
Display source with stripped comments and whitespace.
- </P
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This option does not work together with the <VAR
- CLASS="option"
- >-r</VAR
- >
- option.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-f</TD
- ><TD
- >--file</TD
- ><TD
- >
<P
- >
Parses and executed the given filename to the <VAR
- CLASS="option"
- >-f</VAR
- >
- option. This switch is optional and can be left out. Only providing
- the filename to execute is sufficient.
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-v</TD
- ><TD
- >--version</TD
- ><TD
- >
<P
- >
Writes the PHP, PHP SAPI, and Zend version to standard output, e.g.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ 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</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-c</TD
- ><TD
- >--php-ini</TD
- ><TD
- >
<P
- >
With this option one can either specify a directory where to look for
- <TT
- CLASS="filename"
- >php.ini</TT
- > or you can specify a custom <VAR
- CLASS="literal"
- >INI</VAR
- > file
- directly (which does not need to be named <TT
- CLASS="filename"
- >php.ini</TT
- >), e.g.:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ php -c /custom/directory/ my_script.php
-
- $ php -c /custom/directory/custom-file.ini my_script.php</PRE
- ></TD
- ></TR
- ></TABLE
- >
- If you don't specify this option, file is searched in
- <A
- HREF="#configuration.file"
- >default locations</A
- >.
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-n</TD
- ><TD
- >--no-php-ini</TD
- ><TD
- >
<P
- >
Ignore <TT
- CLASS="filename"
- >php.ini</TT
- > at all. This switch is available since PHP 4.3.0.
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-d</TD
- ><TD
- >--define</TD
- ><TD
- >
<P
- >
This option allows you to set a custom value for any of the configuration
- directives allowed in <TT
- CLASS="filename"
- >php.ini</TT
- >. The syntax is:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >-d configuration_directive[=value]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- >
- <P
- >
Examples (lines are wrapped for layout reasons):
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- ># Omitting the value part will set the given configuration directive to "1"
- $ php -d max_execution_time
- -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
- string(1) "1"
-
- # Passing an empty value part will set the configuration directive to ""
- php -d max_execution_time=
- -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
- string(0) ""
-
- # The configuration directive will be set to anything passed after the '=' character
- $ 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"</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-a</TD
- ><TD
- >--interactive</TD
- ><TD
- >
<P
- >
Runs PHP interactively.
-
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-e</TD
- ><TD
- >--profile-info</TD
- ><TD
- >
<P
- >
Generate extended information for debugger/profiler.
-
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-z</TD
- ><TD
- >--zend-extension</TD
- ><TD
- >
<P
- >
Load Zend extension. If only a filename is given, PHP tries to load
- this extension from the current default library path on your system
- (usually specified <TT
- CLASS="filename"
- >/etc/ld.so.conf</TT
- > on Linux
- systems). Passing a filename with an absolute path information will
- not use the systems library search path. A relative filename with a
- directory information will tell PHP only to try to
- load the extension relative to the current directory.
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-l</TD
- ><TD
- >--syntax-check</TD
- ><TD
- >
<P
- >
This option provides a convenient way to only perform a syntax check
- on the given PHP code. On success, the text
- <VAR
- CLASS="literal"
- >No syntax errors detected in <filename></VAR
- > is
- written to standard output and the shell return code is
- <VAR
- CLASS="literal"
- >0</VAR
- >. On failure, the text <VAR
- CLASS="literal"
- >Errors parsing
- <filename></VAR
- > in addition to the internal parser error
- message is written to standard output and the shell return code is set
- to <VAR
- CLASS="literal"
- >255</VAR
- >.
- </P
- >
- <P
- >
This option won't find fatal errors (like undefined functions). Use
- <VAR
- CLASS="option"
- >-f</VAR
- > if you would like to test for fatal errors too.
- </P
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This option does not work together with the <VAR
- CLASS="option"
- >-r</VAR
- >
- option.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-m</TD
- ><TD
- >--modules</TD
- ><TD
- >
<P
- >
Using this option, PHP prints out the built in (and loaded) PHP and
- Zend modules:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ php -m
- [PHP Modules]
- xml
- tokenizer
- standard
- session
- posix
- pcre
- overload
- mysql
- mbstring
- ctype
-
- [Zend Modules]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-i</TD
- ><TD
- >--info</TD
- ><TD
- >
This command line option calls <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- >, and prints
- out the results. If PHP is not working correctly, it is
- advisable to use <B
- CLASS="command"
- >php -i</B
- > and see whether any error
- messages are printed out before or in place of the information tables.
- Beware that when using the CGI mode the output is in <VAR
- CLASS="literal"
- >HTML</VAR
- >
- and therefore quite huge.
- </TD
- ></TR
- ><TR
- ><TD
- >-r</TD
- ><TD
- >--run</TD
- ><TD
- >
<P
- >
This option allows execution of PHP right from
- within the command line. The PHP start and end tags
- (<VAR
- CLASS="literal"
- ><?php</VAR
- > and <VAR
- CLASS="literal"
- >?></VAR
- >) are
- <SPAN
- CLASS="strong"
- ><B
- CLASS="emphasis"
- >not needed</B
- ></SPAN
- > and will cause a parser
- error if present.
- </P
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Care has to be taken when using this form of PHP
- to not collide with command line variable substitution done by the
- shell.
- </P
- ><P
- >
Example showing a parser error
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ php -r "$foo = get_defined_constants();"
- Command line code(1) : Parse error - parse error, unexpected '='</PRE
- ></TD
- ></TR
- ></TABLE
- >
- The problem here is that the sh/bash performs variable substitution
- even when using double quotes <VAR
- CLASS="literal"
- >"</VAR
- >. Since the
- variable <VAR
- CLASS="varname"
- >$foo</VAR
- > is unlikely to be defined, it
- expands to nothing which results in the code passed to
- PHP for execution actually reading:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ php -r " = get_defined_constants();"</PRE
- ></TD
- ></TR
- ></TABLE
- >
- The correct way would be to use single quotes <VAR
- CLASS="literal"
- >'</VAR
- >.
- Variables in single-quoted strings are not expanded
- by sh/bash.
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >$ 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"]=>
- [...]</PRE
- ></TD
- ></TR
- ></TABLE
- >
- If you are using a shell different from sh/bash, you might experience
- further issues. Feel free to open a bug report at
- <A
- HREF="http://bugs.php.net/"
- TARGET="_top"
- >http://bugs.php.net/</A
- > or send a mail to
- phpdoc@lists.php.net.
-
- One can still easily run into troubles when trying to get shell
- variables into the code or using backslashes for escaping. You've
- been warned.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- <DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <VAR
- CLASS="option"
- >-r</VAR
- > is available in the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >CLI</I
- ></SPAN
- >
- SAPI and not in the <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >CGI</I
- ></SPAN
- > SAPI.
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </TD
- ></TR
- ><TR
- ><TD
- >-h</TD
- ><TD
- >--help</TD
- ><TD
- >
With this option, you can get information about the actual list of
- command line options and some one line descriptions about what they do.
- </TD
- ></TR
- ><TR
- ><TD
- >-?</TD
- ><TD
- >--usage</TD
- ><TD
- >
Alias of <VAR
- CLASS="option"
- >--help</VAR
- >.
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
The PHP executable can be used to run PHP scripts absolutely independent
- from the web server. If you are on a Unix system, you should add a special
- first line to your PHP script, and make it executable, so the system will
- know, what program should run the script. On a Windows platform you can
- associate <TT
- CLASS="filename"
- >php.exe</TT
- > with the double click option of the
- <VAR
- CLASS="literal"
- >.php</VAR
- > files, or you can make a batch
- file to run the script through PHP. The first line added to the script to
- work on Unix won't hurt on Windows, so you can write cross platform programs
- this way. A simple example of writing a command line PHP program can be
- found below.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7710"
- ></A
- ><P
- ><B
- >Example 43-1. Script intended to be run from command line (script.php)</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >#!/usr/bin/php
- <?php
-
- if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
- ?>
-
- This is a command line PHP script with one option.
-
- Usage:
- <?php echo $argv[0]; ?> <option>
-
- <option> can be some word you would like
- to print out. With the --help, -help, -h,
- or -? options, you can get this help.
-
- <?php
- } else {
- echo $argv[1];
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In the script above, we used the special first line to indicate
- that this file should be run by PHP. We work with a CLI version
- here, so there will be no HTTP header printouts. There are two
- variables you can use while writing command line applications with
- PHP: <VAR
- CLASS="varname"
- >$argc</VAR
- > and <VAR
- CLASS="varname"
- >$argv</VAR
- >. The
- first is the number of arguments plus one (the name of the script
- running). The second is an array containing the arguments, starting
- with the script name as number zero (<VAR
- CLASS="varname"
- >$argv[0]</VAR
- >).
- </P
- ><P
- >
In the program above we checked if there are less or more than one
- arguments. Also if the argument was <VAR
- CLASS="option"
- >--help</VAR
- >,
- <VAR
- CLASS="option"
- >-help</VAR
- >, <VAR
- CLASS="option"
- >-h</VAR
- > or <VAR
- CLASS="option"
- >-?</VAR
- >,
- we printed out the help message, printing the script name dynamically.
- If we received some other argument we echoed that out.
- </P
- ><P
- >
If you would like to run the above script on Unix, you need to
- make it executable, and simply call it as
- <B
- CLASS="command"
- >script.php echothis</B
- > or
- <B
- CLASS="command"
- >script.php -h</B
- >. On Windows, you can make a
- batch file for this task:
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7726"
- ></A
- ><P
- ><B
- >Example 43-2. Batch file to run a command line PHP script (script.bat)</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >@c:\php\cli\php.exe script.php %1 %2 %3 %4</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Assuming you named the above program
- <TT
- CLASS="filename"
- >script.php</TT
- >, and you have your
- CLI <TT
- CLASS="filename"
- >php.exe</TT
- > in
- <TT
- CLASS="filename"
- >c:\php\cli\php.exe</TT
- > this batch file
- will run it for you with your added options:
- <B
- CLASS="command"
- >script.bat echothis</B
- > or
- <B
- CLASS="command"
- >script.bat -h</B
- >.
- </P
- ><P
- >
See also the <A
- HREF="#ref.readline"
- >Readline</A
- >
- extension documentation for more functions you can use
- to enhance your command line applications in PHP.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="PART"
- ><A
- NAME="funcref"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >VI. Function Reference</H1
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- >I. <A
- HREF="#ref.apache"
- >Apache-specific Functions</A
- ></DT
- ><DT
- >II. <A
- HREF="#ref.apd"
- >Advanced PHP debugger</A
- ></DT
- ><DT
- >III. <A
- HREF="#ref.array"
- >Array Functions</A
- ></DT
- ><DT
- >IV. <A
- HREF="#ref.aspell"
- >Aspell functions [deprecated]</A
- ></DT
- ><DT
- >V. <A
- HREF="#ref.bc"
- >BCMath Arbitrary Precision Mathematics Functions</A
- ></DT
- ><DT
- >VI. <A
- HREF="#ref.bcompiler"
- >PHP bytecode Compiler</A
- ></DT
- ><DT
- >VII. <A
- HREF="#ref.bzip2"
- >Bzip2 Compression Functions</A
- ></DT
- ><DT
- >VIII. <A
- HREF="#ref.calendar"
- >Calendar Functions</A
- ></DT
- ><DT
- >IX. <A
- HREF="#ref.ccvs"
- >CCVS API Functions [deprecated]</A
- ></DT
- ><DT
- >X. <A
- HREF="#ref.com"
- >COM and .Net (Windows)</A
- ></DT
- ><DT
- >XI. <A
- HREF="#ref.classkit"
- >Classkit Functions</A
- ></DT
- ><DT
- >XII. <A
- HREF="#ref.classobj"
- >Class/Object Functions</A
- ></DT
- ><DT
- >XIII. <A
- HREF="#ref.cpdf"
- >ClibPDF Functions</A
- ></DT
- ><DT
- >XIV. <A
- HREF="#ref.crack"
- >Crack Functions</A
- ></DT
- ><DT
- >XV. <A
- HREF="#ref.curl"
- >CURL, Client URL Library Functions</A
- ></DT
- ><DT
- >XVI. <A
- HREF="#ref.cybercash"
- >Cybercash Payment Functions</A
- ></DT
- ><DT
- >XVII. <A
- HREF="#ref.cyrus"
- >Cyrus IMAP administration Functions</A
- ></DT
- ><DT
- >XVIII. <A
- HREF="#ref.ctype"
- >Character Type Functions</A
- ></DT
- ><DT
- >XIX. <A
- HREF="#ref.dba"
- >Database (dbm-style) Abstraction Layer Functions</A
- ></DT
- ><DT
- >XX. <A
- HREF="#ref.datetime"
- >Date and Time Functions</A
- ></DT
- ><DT
- >XXI. <A
- HREF="#ref.dbase"
- >dBase Functions</A
- ></DT
- ><DT
- >XXII. <A
- HREF="#ref.dbm"
- >DBM Functions [deprecated]</A
- ></DT
- ><DT
- >XXIII. <A
- HREF="#ref.dbx"
- >dbx Functions</A
- ></DT
- ><DT
- >XXIV. <A
- HREF="#ref.dbplus"
- >DB++ Functions</A
- ></DT
- ><DT
- >XXV. <A
- HREF="#ref.dio"
- >Direct IO Functions</A
- ></DT
- ><DT
- >XXVI. <A
- HREF="#ref.dir"
- >Directory Functions</A
- ></DT
- ><DT
- >XXVII. <A
- HREF="#ref.dom"
- >DOM Functions</A
- ></DT
- ><DT
- >XXVIII. <A
- HREF="#ref.domxml"
- >DOM XML Functions</A
- ></DT
- ><DT
- >XXIX. <A
- HREF="#ref.dotnet"
- >.NET Functions</A
- ></DT
- ><DT
- >XXX. <A
- HREF="#ref.errorfunc"
- >Error Handling and Logging Functions</A
- ></DT
- ><DT
- >XXXI. <A
- HREF="#ref.exif"
- >Exif Functions</A
- ></DT
- ><DT
- >XXXII. <A
- HREF="#ref.fam"
- >File Alteration Monitor Functions</A
- ></DT
- ><DT
- >XXXIII. <A
- HREF="#ref.fbsql"
- >FrontBase Functions</A
- ></DT
- ><DT
- >XXXIV. <A
- HREF="#ref.filepro"
- >filePro Functions</A
- ></DT
- ><DT
- >XXXV. <A
- HREF="#ref.filesystem"
- >Filesystem Functions</A
- ></DT
- ><DT
- >XXXVI. <A
- HREF="#ref.fdf"
- >Forms Data Format Functions</A
- ></DT
- ><DT
- >XXXVII. <A
- HREF="#ref.fribidi"
- >FriBiDi Functions</A
- ></DT
- ><DT
- >XXXVIII. <A
- HREF="#ref.ftp"
- >FTP Functions</A
- ></DT
- ><DT
- >XXXIX. <A
- HREF="#ref.funchand"
- >Function Handling Functions</A
- ></DT
- ><DT
- >XL. <A
- HREF="#ref.gettext"
- >Gettext</A
- ></DT
- ><DT
- >XLI. <A
- HREF="#ref.gmp"
- >GMP Functions</A
- ></DT
- ><DT
- >XLII. <A
- HREF="#ref.http"
- >HTTP Functions</A
- ></DT
- ><DT
- >XLIII. <A
- HREF="#ref.hw"
- >Hyperwave Functions</A
- ></DT
- ><DT
- >XLIV. <A
- HREF="#ref.hwapi"
- >Hyperwave API Functions</A
- ></DT
- ><DT
- >XLV. <A
- HREF="#ref.iconv"
- >iconv Functions</A
- ></DT
- ><DT
- >XLVI. <A
- HREF="#ref.image"
- >Image Functions</A
- ></DT
- ><DT
- >XLVII. <A
- HREF="#ref.imap"
- >IMAP, POP3 and NNTP Functions</A
- ></DT
- ><DT
- >XLVIII. <A
- HREF="#ref.ifx"
- >Informix Functions</A
- ></DT
- ><DT
- >XLIX. <A
- HREF="#ref.ibase"
- >Firebird/InterBase Functions</A
- ></DT
- ><DT
- >L. <A
- HREF="#ref.id3"
- >ID3 Functions</A
- ></DT
- ><DT
- >LI. <A
- HREF="#ref.ingres"
- >Ingres II Functions</A
- ></DT
- ><DT
- >LII. <A
- HREF="#ref.ircg"
- >IRC Gateway Functions</A
- ></DT
- ><DT
- >LIII. <A
- HREF="#ref.java"
- >PHP / Java Integration</A
- ></DT
- ><DT
- >LIV. <A
- HREF="#ref.ldap"
- >LDAP Functions</A
- ></DT
- ><DT
- >LV. <A
- HREF="#ref.lzf"
- >LZF Functions</A
- ></DT
- ><DT
- >LVI. <A
- HREF="#ref.mail"
- >Mail Functions</A
- ></DT
- ><DT
- >LVII. <A
- HREF="#ref.mailparse"
- >mailparse Functions</A
- ></DT
- ><DT
- >LVIII. <A
- HREF="#ref.math"
- >Mathematical Functions</A
- ></DT
- ><DT
- >LIX. <A
- HREF="#ref.mbstring"
- >Multibyte String Functions</A
- ></DT
- ><DT
- >LX. <A
- HREF="#ref.mcal"
- >MCAL Functions</A
- ></DT
- ><DT
- >LXI. <A
- HREF="#ref.mcrypt"
- >Mcrypt Encryption Functions</A
- ></DT
- ><DT
- >LXII. <A
- HREF="#ref.mcve"
- >MCVE Payment Functions</A
- ></DT
- ><DT
- >LXIII. <A
- HREF="#ref.memcache"
- >Memcache Functions</A
- ></DT
- ><DT
- >LXIV. <A
- HREF="#ref.mhash"
- >Mhash Functions</A
- ></DT
- ><DT
- >LXV. <A
- HREF="#ref.mime-magic"
- >Mimetype Functions</A
- ></DT
- ><DT
- >LXVI. <A
- HREF="#ref.mssql"
- >Microsoft SQL Server Functions</A
- ></DT
- ><DT
- >LXVII. <A
- HREF="#ref.ming"
- >Ming functions for Flash</A
- ></DT
- ><DT
- >LXVIII. <A
- HREF="#ref.misc"
- >Miscellaneous Functions</A
- ></DT
- ><DT
- >LXIX. <A
- HREF="#ref.mnogosearch"
- >mnoGoSearch Functions</A
- ></DT
- ><DT
- >LXX. <A
- HREF="#ref.msql"
- >mSQL Functions</A
- ></DT
- ><DT
- >LXXI. <A
- HREF="#ref.mysql"
- >MySQL Functions</A
- ></DT
- ><DT
- >LXXII. <A
- HREF="#ref.mysqli"
- >Improved MySQL Extension</A
- ></DT
- ><DT
- >LXXIII. <A
- HREF="#ref.msession"
- >Mohawk Software Session Handler Functions</A
- ></DT
- ><DT
- >LXXIV. <A
- HREF="#ref.muscat"
- >muscat Functions</A
- ></DT
- ><DT
- >LXXV. <A
- HREF="#ref.network"
- >Network Functions</A
- ></DT
- ><DT
- >LXXVI. <A
- HREF="#ref.ncurses"
- >Ncurses Terminal Screen Control Functions</A
- ></DT
- ><DT
- >LXXVII. <A
- HREF="#ref.notes"
- >Lotus Notes Functions</A
- ></DT
- ><DT
- >LXXVIII. <A
- HREF="#ref.nsapi"
- >NSAPI-specific Functions</A
- ></DT
- ><DT
- >LXXIX. <A
- HREF="#ref.uodbc"
- >ODBC Functions (Unified)</A
- ></DT
- ><DT
- >LXXX. <A
- HREF="#ref.objaggregation"
- >Object Aggregation/Composition Functions</A
- ></DT
- ><DT
- >LXXXI. <A
- HREF="#ref.oci8"
- >Oracle 8 functions</A
- ></DT
- ><DT
- >LXXXII. <A
- HREF="#ref.openal"
- >OpenAL Audio Bindings</A
- ></DT
- ><DT
- >LXXXIII. <A
- HREF="#ref.openssl"
- >OpenSSL Functions</A
- ></DT
- ><DT
- >LXXXIV. <A
- HREF="#ref.oracle"
- >Oracle Functions</A
- ></DT
- ><DT
- >LXXXV. <A
- HREF="#ref.ovrimos"
- >Ovrimos SQL Functions</A
- ></DT
- ><DT
- >LXXXVI. <A
- HREF="#ref.outcontrol"
- >Output Control Functions</A
- ></DT
- ><DT
- >LXXXVII. <A
- HREF="#ref.overload"
- >Object property and method call overloading</A
- ></DT
- ><DT
- >LXXXVIII. <A
- HREF="#ref.parsekit"
- >Parsekit Functions</A
- ></DT
- ><DT
- >LXXXIX. <A
- HREF="#ref.pdf"
- >PDF functions</A
- ></DT
- ><DT
- >XC. <A
- HREF="#ref.pdo"
- >PDO Functions</A
- ></DT
- ><DT
- >XCI. <A
- HREF="#ref.pfpro"
- >Verisign Payflow Pro Functions</A
- ></DT
- ><DT
- >XCII. <A
- HREF="#ref.info"
- >PHP Options&Information</A
- ></DT
- ><DT
- >XCIII. <A
- HREF="#ref.posix"
- >POSIX Functions</A
- ></DT
- ><DT
- >XCIV. <A
- HREF="#ref.pgsql"
- >PostgreSQL Functions</A
- ></DT
- ><DT
- >XCV. <A
- HREF="#ref.pcntl"
- >Process Control Functions</A
- ></DT
- ><DT
- >XCVI. <A
- HREF="#ref.exec"
- >Program Execution Functions</A
- ></DT
- ><DT
- >XCVII. <A
- HREF="#ref.printer"
- >Printer Functions</A
- ></DT
- ><DT
- >XCVIII. <A
- HREF="#ref.pspell"
- >Pspell Functions</A
- ></DT
- ><DT
- >XCIX. <A
- HREF="#ref.readline"
- >GNU Readline</A
- ></DT
- ><DT
- >C. <A
- HREF="#ref.recode"
- >GNU Recode Functions</A
- ></DT
- ><DT
- >CI. <A
- HREF="#ref.pcre"
- >Regular Expression Functions (Perl-Compatible)</A
- ></DT
- ><DT
- >CII. <A
- HREF="#ref.qtdom"
- >qtdom Functions</A
- ></DT
- ><DT
- >CIII. <A
- HREF="#ref.rar"
- >Rar Functions</A
- ></DT
- ><DT
- >CIV. <A
- HREF="#ref.regex"
- >Regular Expression Functions (POSIX Extended)</A
- ></DT
- ><DT
- >CV. <A
- HREF="#ref.ssh2"
- >Secure Shell2 Functions</A
- ></DT
- ><DT
- >CVI. <A
- HREF="#ref.sem"
- >Semaphore, Shared Memory and IPC Functions</A
- ></DT
- ><DT
- >CVII. <A
- HREF="#ref.sesam"
- >SESAM Database Functions</A
- ></DT
- ><DT
- >CVIII. <A
- HREF="#ref.session"
- >Session Handling Functions</A
- ></DT
- ><DT
- >CIX. <A
- HREF="#ref.shmop"
- >Shared Memory Functions</A
- ></DT
- ><DT
- >CX. <A
- HREF="#ref.simplexml"
- >SimpleXML functions</A
- ></DT
- ><DT
- >CXI. <A
- HREF="#ref.soap"
- >SOAP Functions</A
- ></DT
- ><DT
- >CXII. <A
- HREF="#ref.sqlite"
- >SQLite</A
- ></DT
- ><DT
- >CXIII. <A
- HREF="#ref.swf"
- >Shockwave Flash Functions</A
- ></DT
- ><DT
- >CXIV. <A
- HREF="#ref.snmp"
- >SNMP Functions</A
- ></DT
- ><DT
- >CXV. <A
- HREF="#ref.sockets"
- >Socket Functions</A
- ></DT
- ><DT
- >CXVI. <A
- HREF="#ref.spl"
- >Standard PHP Library (SPL) Functions</A
- ></DT
- ><DT
- >CXVII. <A
- HREF="#ref.stream"
- >Stream Functions</A
- ></DT
- ><DT
- >CXVIII. <A
- HREF="#ref.strings"
- >String Functions</A
- ></DT
- ><DT
- >CXIX. <A
- HREF="#ref.sybase"
- >Sybase Functions</A
- ></DT
- ><DT
- >CXX. <A
- HREF="#ref.tcpwrap"
- >TCP Wrappers Functions</A
- ></DT
- ><DT
- >CXXI. <A
- HREF="#ref.tidy"
- >Tidy Functions</A
- ></DT
- ><DT
- >CXXII. <A
- HREF="#ref.tokenizer"
- >Tokenizer Functions</A
- ></DT
- ><DT
- >CXXIII. <A
- HREF="#ref.url"
- >URL Functions</A
- ></DT
- ><DT
- >CXXIV. <A
- HREF="#ref.var"
- >Variable Functions</A
- ></DT
- ><DT
- >CXXV. <A
- HREF="#ref.vpopmail"
- >vpopmail Functions</A
- ></DT
- ><DT
- >CXXVI. <A
- HREF="#ref.w32api"
- >W32api Functions</A
- ></DT
- ><DT
- >CXXVII. <A
- HREF="#ref.wddx"
- >WDDX Functions</A
- ></DT
- ><DT
- >CXXVIII. <A
- HREF="#ref.xattr"
- >xattr Functions</A
- ></DT
- ><DT
- >CXXIX. <A
- HREF="#ref.xml"
- >XML Parser Functions</A
- ></DT
- ><DT
- >CXXX. <A
- HREF="#ref.xmlrpc"
- >XML-RPC Functions</A
- ></DT
- ><DT
- >CXXXI. <A
- HREF="#ref.xdiff"
- >xdiff Functions</A
- ></DT
- ><DT
- >CXXXII. <A
- HREF="#ref.xsl"
- >XSL functions</A
- ></DT
- ><DT
- >CXXXIII. <A
- HREF="#ref.xslt"
- >XSLT Functions</A
- ></DT
- ><DT
- >CXXXIV. <A
- HREF="#ref.yaz"
- >YAZ Functions</A
- ></DT
- ><DT
- >CXXXV. <A
- HREF="#ref.nis"
- >YP/NIS Functions</A
- ></DT
- ><DT
- >CXXXVI. <A
- HREF="#ref.zip"
- >Zip File Functions (Read Only Access)</A
- ></DT
- ><DT
- >CXXXVII. <A
- HREF="#ref.zlib"
- >Zlib Compression Functions</A
- ></DT
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="reference"
- ><A
- NAME="ref.apache"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >I. Apache-specific Functions</H1
- ><DIV
- CLASS="PARTINTRO"
- ><A
- NAME="AEN7742"
- ></A
- ><DIV
- CLASS="section"
- ><H2
- CLASS="section"
- ><A
- NAME="apache.intro"
- >Introduction</A
- ></H2
- ><P
- >
These functions are only available when running PHP as an Apache module.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- As of PHP 4.3.2, <VAR
- CLASS="envar"
- >PATH_TRANSLATED</VAR
- > is no longer set
- implicitly under the Apache 2 <ACRONYM
- CLASS="acronym"
- >SAPI</ACRONYM
- > in contrast
- to the situation in Apache 1, where it's set to the same value as
- the <VAR
- CLASS="envar"
- >SCRIPT_FILENAME</VAR
- > server variable when it's not
- populated by Apache. This change was made to comply with the
- <ACRONYM
- CLASS="acronym"
- >CGI</ACRONYM
- > specification that
- <VAR
- CLASS="envar"
- >PATH_TRANSLATED</VAR
- > should only exist if
- <VAR
- CLASS="envar"
- >PATH_INFO</VAR
- > is defined.
- </P
- ><P
- >
Apache 2 users may use <VAR
- CLASS="literal"
- >AcceptPathInfo = On</VAR
- > inside
- <TT
- CLASS="filename"
- >httpd.conf</TT
- > to define <VAR
- CLASS="envar"
- >PATH_INFO</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apache.installation"
- >Installation</A
- ></H2
- ><P
- >
For PHP installation on Apache see the <A
- HREF="#install"
- >installation chapter</A
- >.
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apache.configuration"
- >Runtime Configuration</A
- ></H2
- ><P
- >
The behaviour of the Apache PHP module is affected by settings in <TT
- CLASS="filename"
- >php.ini</TT
- >.
- Configuration settings from <TT
- CLASS="filename"
- >php.ini</TT
- > may be overridden by
- <A
- HREF="#configuration.changes.apache"
- >php_flag</A
- > settings
- in the server configuration file or local <TT
- CLASS="filename"
- >.htaccess</TT
- > files.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7769"
- ></A
- ><P
- ><B
- >Example 1. Turning off PHP parsing for a directory using <TT
- CLASS="filename"
- >.htaccess</TT
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="programlisting"
- >php_flag engine off</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
<DIV
- CLASS="table"
- ><A
- NAME="AEN7774"
- ></A
- ><P
- ><B
- >Table 1. Apache configuration options</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><COL><THEAD
- ><TR
- ><TH
- >Name</TH
- ><TH
- >Default</TH
- ><TH
- >Changeable</TH
- ></TR
- ></THEAD
- ><TBODY
- ><TR
- ><TD
- >engine</TD
- ><TD
- >On</TD
- ><TD
- >PHP_INI_ALL</TD
- ></TR
- ><TR
- ><TD
- >child_terminate</TD
- ><TD
- >Off</TD
- ><TD
- >PHP_INI_ALL</TD
- ></TR
- ><TR
- ><TD
- >last_modified</TD
- ><TD
- >Off</TD
- ><TD
- >PHP_INI_ALL</TD
- ></TR
- ><TR
- ><TD
- >xbithack</TD
- ><TD
- >Off</TD
- ><TD
- >PHP_INI_ALL</TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- For further details and definition of the PHP_INI_* constants see
- <A
- HREF="#function.ini-set"
- ><B
- CLASS="function"
- >ini_set()</B
- ></A
- >.
- </P
- ><P
- >Here's a short explanation of
- the configuration directives.</P
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><A
- NAME="ini.engine"
- ></A
- ><VAR
- CLASS="parameter"
- >engine</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Turns PHP parsing on or off.
- This directive is really only useful in the Apache module
- version of PHP. It is used by sites that would like to turn
- PHP parsing on and off on a per-directory or per-virtual
- server basis. By putting <KBD
- CLASS="userinput"
- >engine off</KBD
- >
- in the appropriate places in the <TT
- CLASS="filename"
- >httpd.conf</TT
- > file, PHP can
- be enabled or disabled.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.child-terminate"
- ></A
- ><VAR
- CLASS="parameter"
- >child_terminate</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Specify whether PHP scripts may request child process termination on end of request,
- see also <A
- HREF="#function.apache-child-terminate"
- ><B
- CLASS="function"
- >apache_child_terminate()</B
- ></A
- >.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.last-modified"
- ></A
- ><VAR
- CLASS="parameter"
- >last_modified</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Send PHP scripts modification date as Last-Modified: header for this request.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.xbithack"
- ></A
- ><VAR
- CLASS="parameter"
- >xbithack</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Parse files with executable bit set as PHP regardless of their file ending.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apache.resources"
- >Resource Types</A
- ></H2
- ><P
- >This extension has no resource types defined.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apache.constants"
- >Predefined Constants</A
- ></H2
- ><P
- >This extension has no constants defined.</P
- ></DIV
- ></DIV
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- ><A
- HREF="#function.apache-child-terminate"
- >apache_child_terminate</A
- > -- Terminate apache process after this request</DT
- ><DT
- ><A
- HREF="#function.apache-get-modules"
- >apache_get_modules</A
- > --
- Get a list of loaded Apache modules
- </DT
- ><DT
- ><A
- HREF="#function.apache-get-version"
- >apache_get_version</A
- > --
- Fetch Apache version
- </DT
- ><DT
- ><A
- HREF="#function.apache-getenv"
- >apache_getenv</A
- > -- Get an Apache subprocess_env variable</DT
- ><DT
- ><A
- HREF="#function.apache-lookup-uri"
- >apache_lookup_uri</A
- > --
- Perform a partial request for the specified URI and return all
- info about it
- </DT
- ><DT
- ><A
- HREF="#function.apache-note"
- >apache_note</A
- > -- Get and set apache request notes</DT
- ><DT
- ><A
- HREF="#function.apache-request-headers"
- >apache_request_headers</A
- > -- Fetch all HTTP request headers</DT
- ><DT
- ><A
- HREF="#function.apache-reset-timeout"
- >apache_reset_timeout</A
- > --
- Reset the Apache write timer
- </DT
- ><DT
- ><A
- HREF="#function.apache-response-headers"
- >apache_response_headers</A
- > --
- Fetch all HTTP response headers
- </DT
- ><DT
- ><A
- HREF="#function.apache-setenv"
- >apache_setenv</A
- > -- Set an Apache subprocess_env variable</DT
- ><DT
- ><A
- HREF="#function.ascii2ebcdic"
- >ascii2ebcdic</A
- > -- Translate string from ASCII to EBCDIC</DT
- ><DT
- ><A
- HREF="#function.ebcdic2ascii"
- >ebcdic2ascii</A
- > -- Translate string from EBCDIC to ASCII</DT
- ><DT
- ><A
- HREF="#function.getallheaders"
- >getallheaders</A
- > -- Fetch all HTTP request headers</DT
- ><DT
- ><A
- HREF="#function.virtual"
- >virtual</A
- > -- Perform an Apache sub-request</DT
- ></DL
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.apache-child-terminate"
- ></A
- >apache_child_terminate</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7837"
- ></A
- ><P
- > (PHP 4 >= 4.0.5, PHP 5)</P
- >apache_child_terminate -- Terminate apache process after this request</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7840"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >apache_child_terminate</B
- > ( void )<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_child_terminate()</B
- > will register the
- Apache process executing the current PHP request for termination
- once execution of PHP code it is completed. It may be used to
- terminate a process after a script with high memory consumption has
- been run as memory will usually only be freed internally but not
- given back to the operating system.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The availability of this feature is controlled by the <TT
- CLASS="filename"
- >php.ini</TT
- > directive
- <VAR
- CLASS="option"
- >child_terminate</VAR
- >, which is set to <VAR
- CLASS="literal"
- >off</VAR
- >
- by default.
- </P
- ><P
- >
This feature is also not available on multithreaded versions of apache
- like the win32 version.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.exit"
- ><B
- CLASS="function"
- >exit()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-get-modules"
- ></A
- >apache_get_modules</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7857"
- ></A
- ><P
- > (PHP 4 >= 4.3.2, PHP 5)</P
- >apache_get_modules --
- Get a list of loaded Apache modules
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7860"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apache_get_modules</B
- > ( void )<BR
- ></BR
- ><P
- >
This function returns an array with the loaded Apache modules.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7868"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_get_modules()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- print_r(apache_get_modules());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output
- something similar to:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => core
- [1] => http_core
- [2] => mod_so
- [3] => sapi_apache2
- [4] => mod_mime
- [5] => mod_rewrite
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This function is available only in Apache 2 <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >handler</I
- ></SPAN
- >.
- As of PHP 5, it is available also in Apache 2 <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >filter</I
- ></SPAN
- >
- and Apache 1.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.apache-get-version"
- ></A
- >apache_get_version</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7879"
- ></A
- ><P
- > (PHP 4 >= 4.3.2, PHP 5)</P
- >apache_get_version --
- Fetch Apache version
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7882"
- ></A
- ><H2
- >Description</H2
- >string <B
- CLASS="methodname"
- >apache_get_version</B
- > ( void )<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_get_version()</B
- > returns the version of Apache as
- string, or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > on failure.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7891"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_get_version()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $version = apache_get_version();
- echo "$version\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output
- something similar to:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Apache/1.3.29 (Unix) PHP/4.3.4</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This function is available only in Apache 2 <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >handler</I
- ></SPAN
- >.
- As of PHP 4.3.4, it is available also in Apache 1 and as of PHP 5, it is
- available also in Apache 2 <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >filter</I
- ></SPAN
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-getenv"
- ></A
- >apache_getenv</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7904"
- ></A
- ><P
- > (PHP 4 >= 4.3.0, PHP 5)</P
- >apache_getenv -- Get an Apache subprocess_env variable</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7907"
- ></A
- ><H2
- >Description</H2
- >string <B
- CLASS="methodname"
- >apache_getenv</B
- > ( string variable [, bool walk_to_top])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_getenv()</B
- > returns the value of the Apache
- environment variable specified by <VAR
- CLASS="parameter"
- >variable</VAR
- >, or
- <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > on failure.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7922"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_getenv()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $ret = apache_getenv("SERVER_ADDR");
- echo $ret;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The example above shows how to retrieve the value of the Apache
- environment variable "SERVER_ADDR".
- </P
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
See also <A
- HREF="#function.apache-setenv"
- ><B
- CLASS="function"
- >apache_setenv()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-lookup-uri"
- ></A
- >apache_lookup_uri</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7930"
- ></A
- ><P
- > (PHP 3>= 3.0.4, PHP 4 , PHP 5)</P
- >apache_lookup_uri --
- Perform a partial request for the specified URI and return all
- info about it
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7933"
- ></A
- ><H2
- >Description</H2
- >object <B
- CLASS="methodname"
- >apache_lookup_uri</B
- > ( string filename)<BR
- ></BR
- ><P
- >
This performs a partial request for a URI. It goes just far
- enough to obtain all the important information about the given
- resource and returns this information in a class. The properties
- of the returned class are:
- <P
- ></P
- ><TABLE
- BORDER="0"
- ><TBODY
- ><TR
- ><TD
- >status</TD
- ></TR
- ><TR
- ><TD
- >the_request</TD
- ></TR
- ><TR
- ><TD
- >status_line</TD
- ></TR
- ><TR
- ><TD
- >method</TD
- ></TR
- ><TR
- ><TD
- >content_type</TD
- ></TR
- ><TR
- ><TD
- >handler</TD
- ></TR
- ><TR
- ><TD
- >uri</TD
- ></TR
- ><TR
- ><TD
- >filename</TD
- ></TR
- ><TR
- ><TD
- >path_info</TD
- ></TR
- ><TR
- ><TD
- >args</TD
- ></TR
- ><TR
- ><TD
- >boundary</TD
- ></TR
- ><TR
- ><TD
- >no_cache</TD
- ></TR
- ><TR
- ><TD
- >no_local_copy</TD
- ></TR
- ><TR
- ><TD
- >allowed</TD
- ></TR
- ><TR
- ><TD
- >send_bodyct</TD
- ></TR
- ><TR
- ><TD
- >bytes_sent</TD
- ></TR
- ><TR
- ><TD
- >byterange</TD
- ></TR
- ><TR
- ><TD
- >clength</TD
- ></TR
- ><TR
- ><TD
- >unparsed_uri</TD
- ></TR
- ><TR
- ><TD
- >mtime</TD
- ></TR
- ><TR
- ><TD
- >request_time</TD
- ></TR
- ></TBODY
- ></TABLE
- ><P
- ></P
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN7965"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_lookup_uri()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $info = apache_lookup_uri('index.php?var=value');
- print_r($info);
-
- if (file_exists($info->filename)) {
- echo 'file exists!';
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output
- something similar to:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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!</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- <B
- CLASS="function"
- >apache_lookup_uri()</B
- > only works when PHP
- is installed as an Apache module.
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.apache-note"
- ></A
- >apache_note</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7975"
- ></A
- ><P
- > (PHP 3>= 3.0.2, PHP 4 , PHP 5)</P
- >apache_note -- Get and set apache request notes</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN7978"
- ></A
- ><H2
- >Description</H2
- >string <B
- CLASS="methodname"
- >apache_note</B
- > ( string note_name [, string note_value])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_note()</B
- > is an Apache-specific function
- which gets and sets values in a request's
- <VAR
- CLASS="literal"
- >notes</VAR
- > table. If called with one argument, it
- returns the current value of note
- <VAR
- CLASS="literal"
- >note_name</VAR
- >. If called with two arguments, it
- sets the value of note <VAR
- CLASS="literal"
- >note_name</VAR
- > to
- <VAR
- CLASS="literal"
- >note_value</VAR
- > and returns the previous value of
- note <VAR
- CLASS="literal"
- >note_name</VAR
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-request-headers"
- ></A
- >apache_request_headers</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN7997"
- ></A
- ><P
- > (PHP 4 >= 4.3.0, PHP 5)</P
- >apache_request_headers -- Fetch all HTTP request headers</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8000"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apache_request_headers</B
- > ( void )<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_request_headers()</B
- > returns an associative
- array of all the HTTP headers in the current request. This is only
- supported when PHP runs as an <SPAN
- CLASS="productname"
- >Apache</SPAN
- >
- module.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8010"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_request_headers()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $headers = apache_request_headers();
-
- foreach ($headers as $header => $value) {
- echo "$header: $value <br />\n";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output
- something similar to:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Accept: */*
- Accept-Language: en-us
- Accept-Encoding: gzip, deflate
- User-Agent: Mozilla/4.0
- Host: www.example.com
- Connection: Keep-Alive</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Prior to PHP 4.3.0, <B
- CLASS="function"
- >apache_request_headers()</B
- > was
- called <A
- HREF="#function.getallheaders"
- ><B
- CLASS="function"
- >getallheaders()</B
- ></A
- >. After PHP 4.3.0,
- <A
- HREF="#function.getallheaders"
- ><B
- CLASS="function"
- >getallheaders()</B
- ></A
- > is an alias for
- <B
- CLASS="function"
- >apache_request_headers()</B
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- You can also get at the value of the common CGI variables by
- reading them from the environment, which works whether or not
- you are using PHP as an <SPAN
- CLASS="productname"
- >Apache</SPAN
- > module. Use
- <A
- HREF="#function.phpinfo"
- ><B
- CLASS="function"
- >phpinfo()</B
- ></A
- > to see a list of all of the available
- <A
- HREF="#language.variables.predefined"
- >environment variables</A
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >As of PHP 4.3.3 you can use this function with the
- <A
- HREF="#ref.nsapi"
- >NSAPI server module</A
- > in Netscape/iPlanet/SunONE
- webservers, too.</P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.apache-response-headers"
- ><B
- CLASS="function"
- >apache_response_headers()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-reset-timeout"
- ></A
- >apache_reset_timeout</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8033"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apache_reset_timeout --
- Reset the Apache write timer
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8036"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >apache_reset_timeout</B
- > ( void )<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_reset_timeout()</B
- > resets the Apache write timer,
- which defaults to 300 seconds. With <VAR
- CLASS="literal"
- >set_time_limit(0);
- ignore_user_abort(true)</VAR
- > and periodic
- <B
- CLASS="function"
- >apache_reset_timeout()</B
- > calls, Apache can theoretically
- run forever.
- </P
- ><P
- >
Returns <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > on success or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > on failure.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- This functions is just available for Apache 1.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >This function is disabled in <A
- HREF="#features.safe-mode"
- >safe mode</A
- >.</P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.apache-response-headers"
- ></A
- >apache_response_headers</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8055"
- ></A
- ><P
- > (PHP 4 >= 4.3.0, PHP 5)</P
- >apache_response_headers --
- Fetch all HTTP response headers
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8058"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apache_response_headers</B
- > ( void )<BR
- ></BR
- ><P
- >
Returns an array of all Apache response headers.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8066"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apache_response_headers()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- print_r(apache_response_headers());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output
- something similar to:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [Accept-Ranges] => bytes
- [X-Powered-By] => PHP/4.3.8
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >As of PHP 4.3.3 you can use this function with the
- <A
- HREF="#ref.nsapi"
- >NSAPI server module</A
- > in Netscape/iPlanet/SunONE
- webservers, too.</P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- >, and
- <A
- HREF="#function.headers-sent"
- ><B
- CLASS="function"
- >headers_sent()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apache-setenv"
- ></A
- >apache_setenv</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8079"
- ></A
- ><P
- > (PHP 4 >= 4.2.0, PHP 5)</P
- >apache_setenv -- Set an Apache subprocess_env variable</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8082"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >apache_setenv</B
- > ( string variable, string value [, bool walk_to_top])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >apache_setenv()</B
- > sets the value of the Apache
- environment variable specified by
- <VAR
- CLASS="parameter"
- >variable</VAR
- >.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- When setting an Apache environment variable, the corresponding $_SERVER
- variable is not changed.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8101"
- ></A
- ><P
- ><B
- >Example 1. Setting an Apache environment variable using <B
- CLASS="function"
- >apache_setenv()</B
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apache_setenv("EXAMPLE_VAR", "Example Value");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
<B
- CLASS="function"
- >apache_setenv()</B
- > can be paired up with
- <A
- HREF="#function.apache-getenv"
- ><B
- CLASS="function"
- >apache_getenv()</B
- ></A
- > across separate pages or for setting
- variables to pass to Server Side Includes (.shtml) that have been
- included in PHP scripts.
- </P
- ><P
- >
See also <A
- HREF="#function.apache-getenv"
- ><B
- CLASS="function"
- >apache_getenv()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.ascii2ebcdic"
- ></A
- >ascii2ebcdic</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8111"
- ></A
- ><P
- > (PHP 3>= 3.0.17)</P
- >ascii2ebcdic -- Translate string from ASCII to EBCDIC</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8114"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >ascii2ebcdic</B
- > ( string ascii_str)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >ascii2ebcdic()</B
- > is an Apache-specific function which
- is available only on EBCDIC based operating systems (OS/390, BS2000).
- It translates the ASCII encoded string <VAR
- CLASS="parameter"
- >ascii_str</VAR
- >
- to its equivalent EBCDIC representation (binary safe), and returns
- the result.
- </P
- ><P
- >
See also the reverse function <A
- HREF="#function.ebcdic2ascii"
- ><B
- CLASS="function"
- >ebcdic2ascii()</B
- ></A
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.ebcdic2ascii"
- ></A
- >ebcdic2ascii</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8128"
- ></A
- ><P
- > (PHP 3>= 3.0.17)</P
- >ebcdic2ascii -- Translate string from EBCDIC to ASCII</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8131"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >ebcdic2ascii</B
- > ( string ebcdic_str)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >ebcdic2ascii()</B
- > is an Apache-specific function which
- is available only on EBCDIC based operating systems (OS/390, BS2000).
- It translates the EBCDIC encoded string <VAR
- CLASS="parameter"
- >ebcdic_str</VAR
- >
- to its equivalent ASCII representation (binary safe), and returns
- the result.
- </P
- ><P
- >
See also the reverse function <A
- HREF="#function.ascii2ebcdic"
- ><B
- CLASS="function"
- >ascii2ebcdic()</B
- ></A
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.getallheaders"
- ></A
- >getallheaders</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8145"
- ></A
- ><P
- > (PHP 3, PHP 4 , PHP 5)</P
- >getallheaders -- Fetch all HTTP request headers</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8148"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >getallheaders</B
- > ( void )<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >getallheaders()</B
- > is an alias for
- <A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- >. It will return an
- associative array of all the HTTP headers in the current request.
- Please read the <A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- >
- documentation for more information on how this function works.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- In PHP 4.3.0, <B
- CLASS="function"
- >getallheaders()</B
- > became an
- alias for <A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- >.
- Essentially, it was renamed. This is because this function
- only works when PHP is compiled as an
- <SPAN
- CLASS="productname"
- >Apache</SPAN
- > Module.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >As of PHP 4.3.3 you can use this function with the
- <A
- HREF="#ref.nsapi"
- >NSAPI server module</A
- > in Netscape/iPlanet/SunONE
- webservers, too.</P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.apache-request-headers"
- ><B
- CLASS="function"
- >apache_request_headers()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.virtual"
- ></A
- >virtual</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8169"
- ></A
- ><P
- > (PHP 3, PHP 4 , PHP 5)</P
- >virtual -- Perform an Apache sub-request</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8172"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >virtual</B
- > ( string filename)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >virtual()</B
- > is an Apache-specific function which
- is equivalent to <!--#include virtual...--> in mod_include.
- It performs an Apache sub-request. It is useful for including
- CGI scripts or .shtml files, or anything else that you would
- parse through Apache. Note that for a CGI script, the script
- must generate valid CGI headers. At the minimum that means it
- must generate a Content-type header.
- </P
- ><P
- >
To run the sub-request, all buffers are terminated and flushed to the
- browser, pending headers are sent too.
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
This function works only when PHP is compiled as an Apache module,
- since it uses the Apache API for doing sub requests. Query string can be
- passed to the included file but <VAR
- CLASS="varname"
- >$_GET</VAR
- > is copied from
- the parent script and only <VAR
- CLASS="varname"
- >$_SERVER['QUERY_STRING']</VAR
- > is
- filled with the passed query string. The query string may only be passed
- when using Apache 2. The requested file will not be listed in the Apache access log.
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
As of PHP 4.0.6, you can use <B
- CLASS="function"
- >virtual()</B
- > on PHP files.
- However, it is typically better to use <A
- HREF="#function.include"
- ><B
- CLASS="function"
- >include()</B
- ></A
- > or
- <A
- HREF="#function.require"
- ><B
- CLASS="function"
- >require()</B
- ></A
- > if you need to include another PHP file.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >As of PHP 4.3.3 you can use this function with the
- <A
- HREF="#ref.nsapi"
- >NSAPI server module</A
- > in Netscape/iPlanet/SunONE
- webservers, too.</P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ></DIV
- ><DIV
- CLASS="reference"
- ><A
- NAME="ref.apd"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >II. Advanced PHP debugger</H1
- ><DIV
- CLASS="PARTINTRO"
- ><A
- NAME="AEN8197"
- ></A
- ><DIV
- CLASS="section"
- ><H2
- CLASS="section"
- ><A
- NAME="apd.intro"
- >Introduction</A
- ></H2
- ><P
- >
APD is the Advanced PHP Debugger. It was written to provide profiling and
- debugging capabilities for PHP code, as well as to provide the ability to
- print out a full stack backtrace. APD supports interactive debugging, but
- by default it writes data to trace files. It also offers event based
- logging so that varying levels of information (including function calls,
- arguments passed, timings, etc.) can be turned on or off for individual
- scripts.
- <DIV
- CLASS="caution"
- ><P
- ></P
- ><TABLE
- CLASS="caution"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Caution</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
APD is a Zend Extension, modifying the way the internals of PHP handle
- function calls, and thus may or may not be compatible with other Zend
- Extensions (for example Zend Optimizer).
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.installation"
- >Installation</A
- ></H2
- ><P
- >
APD is currently available as a PECL extension from
- <A
- HREF="http://pecl.php.net/package/apd"
- TARGET="_top"
- >http://pecl.php.net/package/apd</A
- >.
- Make sure you have installed the CGI version of PHP and it is available
- in your current path along with the phpize script.
- </P
- ><P
- >
Run the following command to download, build, and install the latest stable
- version of APD:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >pear install apd</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This automatically installs the APD Zend module into your PHP
- extensions directory. It is not mandatory to keep it there; you can
- store the module in any directory PHP can read as long as you set
- the zend_extension parameter accordingly.
- </P
- ><P
- >
Windows users can download the extension dll <TT
- CLASS="filename"
- >php_apd.dll</TT
- >
- from <A
- HREF="http://snaps.php.net/win32/PECL_STABLE/"
- TARGET="_top"
- >http://snaps.php.net/win32/PECL_STABLE/</A
- >.
- </P
- ><P
- >
In your INI file, add the following lines:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php.ini"
- >zend_extension = /absolute/path/to/apd.so
- apd.dumpdir = /absolute/path/to/trace/directory
- apd.statement_trace = 0</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Depending on your PHP build, the zend_extension directive can be one of the
- following:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="script"
- >zend_extension (non ZTS, non debug build)
- zend_extension_ts ( ZTS, non debug build)
- zend_extension_debug (non ZTS, debug build)
- zend_extension_debug_ts ( ZTS, debug build)</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.installwin32"
- >Building on Win32</A
- ></H2
- ><P
- >
To build APD under Windows you need a working PHP compilation
- environment as described on http://php.net/ -- basically, it requires
- you to have Microsoft Visual C++, win32build.zip, bison/flex, and some know how
- to get it to work. Also ensure that adp.dsp has DOS line endings; if it has unix
- line endings, Microsoft Visual C++ will complain about it.
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.configuration"
- >Runtime Configuration</A
- ></H2
- ><P
- >Here's a short explanation of
- the configuration directives.</P
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><A
- NAME="ini.apd.dumpdir"
- ></A
- ><VAR
- CLASS="parameter"
- >apd.dumpdir</VAR
- >
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- ></DT
- ><DD
- ><P
- >
Sets the directory in which APD writes profile dump files.
- You can specify an absolute path or a relative path.
- </P
- ><P
- >
You can specify a different directory as an argument
- to <A
- HREF="#function.apd-set-pprof-trace"
- ><B
- CLASS="function"
- >apd_set_pprof_trace()</B
- ></A
- >.
- </P
- ></DD
- ><DT
- ><A
- NAME="ini.apd.statement-trace"
- ></A
- ><VAR
- CLASS="parameter"
- >apd.statement_trace</VAR
- >
- <A
- HREF="#language.types.boolean"
- ><B
- CLASS="type"
- >boolean</B
- ></A
- ></DT
- ><DD
- ><P
- >
Specfies whether or not to do per-line tracings. Turning this on (1) will
- impact the performance of your application.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.resources"
- >Resource Types</A
- ></H2
- ><P
- >This extension has no resource types defined.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.constants"
- >Predefined Constants</A
- ></H2
- ><P
- >This extension has no constants defined.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.examples"
- >How to use PHP-APD in your scripts</A
- ></H2
- ><DIV
- CLASS="procedure"
- ><OL
- TYPE="1"
- ><LI
- ><P
- >
As the first line of your PHP script, call the apd_set_pprof_trace() function
- to start the trace:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >apd_set_pprof_trace();</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
You can insert the line anywhere in your script, but if you do not start
- tracing at the beginning of your script you discard profile data that might
- otherwise lead you to a performance bottleneck.
- </P
- ></LI
- ><LI
- ><P
- >
Now run your script. The dump output will be written to
- <TT
- CLASS="filename"
- >apd.dumpdir/pprof_pid.ext</TT
- >.
- <DIV
- CLASS="tip"
- ><BLOCKQUOTE
- CLASS="tip"
- ><P
- ><B
- >Tip: </B
- >
- If you're running the CGI version of PHP, you will need to add the '-e'
- flag to enable extended information for apd to work properly. For
- example:
- <KBD
- CLASS="userinput"
- >php -e -f script.php</KBD
- >
- </P
- ></BLOCKQUOTE
- ></DIV
- >
- </P
- ></LI
- ><LI
- ><P
- >
To display formatted profile data, issue the <B
- CLASS="command"
- >pprofp</B
- >
- command with the sort and display options of your choice. The formatted
- output will look something like:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >bash-2.05b$ pprofp -R /tmp/pprof.22141.0
-
- Trace for /home/dan/testapd.php
- Total Elapsed Time = 0.00
- Total System Time = 0.00
- Total User Time = 0.00
-
-
- Real User System secs/ cumm
- %Time (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name
- --------------------------------------------------------------------------------------
- 100.0 0.00 0.00 0.00 0.00 0.00 0.00 1 0.0000 0.0009 0 main
- 56.9 0.00 0.00 0.00 0.00 0.00 0.00 1 0.0005 0.0005 0 apd_set_pprof_trace
- 28.0 0.00 0.00 0.00 0.00 0.00 0.00 10 0.0000 0.0000 0 preg_replace
- 14.3 0.00 0.00 0.00 0.00 0.00 0.00 10 0.0000 0.0000 0 str_replace</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The -R option used in this example sorts the profile table by the amount
- of real time the script spent executing a given function. The "cumm call"
- column reveals how many times each function was called, and the "s/call"
- column reveals how many seconds each call to the function required, on
- average.
- </P
- ></LI
- ><LI
- ><P
- >
To generate a calltree file that you can import into the KCacheGrind
- profile analysis application, issue the <B
- CLASS="command"
- >pprof2calltree</B
- >
- comand.
- </P
- ></LI
- ></OL
- ></DIV
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="apd.contact"
- >Contact information</A
- ></H2
- ><P
- >
If you have comments, bugfixes, enhancements or want to help developing
- this beast, you can send an mail to
- <A
- HREF="mailto:apd@mail.communityconnect.com"
- TARGET="_top"
- >apd@mail.communityconnect.com</A
- >. Any help is very
- welcome.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- ><A
- HREF="#function.apd-breakpoint"
- >apd_breakpoint</A
- > -- Stops the interpreter and waits on a CR from the socket</DT
- ><DT
- ><A
- HREF="#function.apd-callstack"
- >apd_callstack</A
- > -- Returns the current call stack as an array</DT
- ><DT
- ><A
- HREF="#function.apd-clunk"
- >apd_clunk</A
- > -- Throw a warning and a callstack</DT
- ><DT
- ><A
- HREF="#function.apd-continue"
- >apd_continue</A
- > -- Restarts the interpreter</DT
- ><DT
- ><A
- HREF="#function.apd-croak"
- >apd_croak</A
- > -- Throw an error, a callstack and then exit</DT
- ><DT
- ><A
- HREF="#function.apd-dump-function-table"
- >apd_dump_function_table</A
- > -- Outputs the current function table</DT
- ><DT
- ><A
- HREF="#function.apd-dump-persistent-resources"
- >apd_dump_persistent_resources</A
- > -- Return all persistent resources as an array</DT
- ><DT
- ><A
- HREF="#function.apd-dump-regular-resources"
- >apd_dump_regular_resources</A
- > -- Return all current regular resources as an array</DT
- ><DT
- ><A
- HREF="#function.apd-echo"
- >apd_echo</A
- > -- Echo to the debugging socket</DT
- ><DT
- ><A
- HREF="#function.apd-get-active-symbols"
- >apd_get_active_symbols</A
- > -- Get an array of the current variables names in the local scope</DT
- ><DT
- ><A
- HREF="#function.apd-set-pprof-trace"
- >apd_set_pprof_trace</A
- > -- Starts the session debugging</DT
- ><DT
- ><A
- HREF="#function.apd-set-session-trace"
- >apd_set_session_trace</A
- > -- Starts the session debugging</DT
- ><DT
- ><A
- HREF="#function.apd-set-session"
- >apd_set_session</A
- > -- Changes or sets the current debugging level</DT
- ><DT
- ><A
- HREF="#function.apd-set-socket-session-trace"
- >apd_set_socket_session_trace</A
- > -- Starts the remote session debugging</DT
- ><DT
- ><A
- HREF="#function.override-function"
- >override_function</A
- > -- Overrides built-in functions</DT
- ><DT
- ><A
- HREF="#function.rename-function"
- >rename_function</A
- > -- Renames orig_name to new_name in the global function_table</DT
- ></DL
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.apd-breakpoint"
- ></A
- >apd_breakpoint</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8274"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_breakpoint -- Stops the interpreter and waits on a CR from the socket</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8277"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_breakpoint</B
- > ( int debug_level)<BR
- ></BR
- ><P
- >
This can be used to stop the running of your script, and await responses
- on the connected socket. To step the program, just send enter (a blank
- line), or enter a php command to be executed. A typical session using
- tcplisten would look like this.
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="shell"
- >bash#tcplisten localhost 7777
-
- APD - Advanced PHP Debugger Trace File
- ---------------------------------------------------------------------------
- Process Pid (6118)
- Trace Begun at Sun Mar 10 23:13:12 2002
- ---------------------------------------------------------------------------
- ( 0.000000): apd_set_session_trace called at /home/alan/Projects/project2/test.
- php:5
- ( 0.074824): apd_set_session_trace_socket() at /home/alan/Projects/project2/tes
- t.php:5 returned. Elapsed (0.074824)
- ( 0.074918): apd_breakpoint() /home/alan/Projects/project2/test.php:7
- ++ argv[0] $(??) = 9
- apd_breakpoint() at /home/alan/Projects/project2/test.php:7 returned. Elapsed (
- -2089521468.1073275368)
- >\n
- statement: /home/alan/Projects/project2/test.php:8
- >\n
- statement: /home/alan/Projects/project2/test.php:8
- >\n
- statement: /home/alan/Projects/project2/test.php:10
- >apd_echo($i);
- EXEC: apd_echo($i);
- 0
- >apd_echo(serialize(apd_get_active_symbols()));
- EXEC: apd_echo(serialize(apd_get_active_symbols()));
- a:47:{i:0;s:4:"PWD";i:1;s:10:"COLORFGBG";i:2;s:11:"XAUTHORITY";i:3;s:14:"
- COLORTERM_BCE";i:4;s:9:"WINDOWID";i:5;s:14:"ETERM_VERSION";i:6;s:16:"SE
- SSION_MANAGER";i:7;s:4:"PS1";i:8;s:11:"GDMSESSION";i:9;s:5:"USER";i:10;s:5:"
- MAIL";i:11;s:7:"OLDPWD";i:12;s:5:"LANG";i:13;s:10:"COLORTERM";i:14;s:8:"DISP
- LAY";i:15;s:8:"LOGNAME";i:16;s:6:"
- >apd_echo(system('ls /home/mydir'));
- ........
- >apd_continue(0);</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-callstack"
- ></A
- >apd_callstack</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8289"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_callstack -- Returns the current call stack as an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8292"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apd_callstack</B
- > ( void )<BR
- ></BR
- ><P
- >
Returns the current call stack as an array
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8300"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_callstack()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- print_r(apd_callstack());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-clunk"
- ></A
- >apd_clunk</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8305"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_clunk -- Throw a warning and a callstack</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8308"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_clunk</B
- > ( string warning [, string delimiter])<BR
- ></BR
- ><P
- >
Behaves like perl's Carp::cluck. Throw a warning and a callstack.
- The default line delimiter is "<BR />\n".
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8321"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_clunk()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_clunk("Some Warning","<P>");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-continue"
- ></A
- >apd_continue</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8326"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_continue -- Restarts the interpreter</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8329"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_continue</B
- > ( int debug_level)<BR
- ></BR
- ><P
- >
Usually sent via the socket to restart the interpreter.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8339"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_continue()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_continue(0);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-croak"
- ></A
- >apd_croak</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8344"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_croak -- Throw an error, a callstack and then exit</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8347"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_croak</B
- > ( string warning [, string delimiter])<BR
- ></BR
- ><P
- >
Behaves like perl's Carp::croak. Throw an error, a callstack and then
- exit. The default line delimiter is "<BR />\n".
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8360"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_croak()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_croak("Some Warning","<P>");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-dump-function-table"
- ></A
- >apd_dump_function_table</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8365"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_dump_function_table -- Outputs the current function table</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8368"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_dump_function_table</B
- > ( void )<BR
- ></BR
- ><P
- >
Outputs the current function table.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8376"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_dump_function_table()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_dump_function_table();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-dump-persistent-resources"
- ></A
- >apd_dump_persistent_resources</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8381"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_dump_persistent_resources -- Return all persistent resources as an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8384"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apd_dump_persistent_resources</B
- > ( void )<BR
- ></BR
- ><P
- >
Return all persistent resources as an array.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8392"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_dump_persistent_resources()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- print_r(apd_dump_persistent_resources());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-dump-regular-resources"
- ></A
- >apd_dump_regular_resources</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8397"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_dump_regular_resources -- Return all current regular resources as an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8400"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apd_dump_regular_resources</B
- > ( void )<BR
- ></BR
- ><P
- >
Return all current regular resources as an array.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8408"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_dump_regular_resources()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- print_r(apd_dump_regular_resources());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-echo"
- ></A
- >apd_echo</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8413"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_echo -- Echo to the debugging socket</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8416"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_echo</B
- > ( string output)<BR
- ></BR
- ><P
- >
Usually sent via the socket to request information about the running
- script.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8426"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_echo()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_echo($i);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-get-active-symbols"
- ></A
- >apd_get_active_symbols</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8431"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_get_active_symbols -- Get an array of the current variables names in the local scope</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8434"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >apd_get_active_symbols</B
- > ( )<BR
- ></BR
- ><P
- >
Returns the names of all the variables defined in the active scope, (not
- their values)
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8443"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_get_active_symbols()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_echo(apd_get_active_symbols());
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-set-pprof-trace"
- ></A
- >apd_set_pprof_trace</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8448"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_set_pprof_trace -- Starts the session debugging</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8451"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_set_pprof_trace</B
- > ( [string dump_directory])<BR
- ></BR
- ><P
- >
Starts debugging to {dump_directory}/pprof_{process_id}, if
- dump_directory is not set, then the apd.dumpdir setting from the
- <TT
- CLASS="filename"
- >php.ini</TT
- > file is used.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8462"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_set_pprof_trace()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_set_pprof_trace();
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-set-session-trace"
- ></A
- >apd_set_session_trace</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8467"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_set_session_trace -- Starts the session debugging</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8470"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_set_session_trace</B
- > ( int debug_level [, string dump_directory])<BR
- ></BR
- ><P
- >
Starts debugging to {dump_directory}/apd_dump_{process_id}, if
- dump_directory is not set, then the apd.dumpdir setting from the
- <TT
- CLASS="filename"
- >php.ini</TT
- > file is used.
- </P
- ><P
- >
debug_level is an integer which is formed by adding together the following
- values:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="script"
- >FUNCTION_TRACE 1
- ARGS_TRACE 2
- ASSIGNMENT_TRACE 4
- STATEMENT_TRACE 8
- MEMORY_TRACE 16
- TIMING_TRACE 32
- SUMMARY_TRACE 64</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
I would seriously not recommend using MEMORY_TRACE. It is very slow and
- does not appear to be accurate (great, huh?) also ASSIGNMENT_TRACE is not
- implemented. So, to turn on all functional traces (TIMING, FUNCTIONS, ARGS
- SUMMARY (like strace -c)) use the value 99
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8488"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_set_session_trace()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_set_session_trace(99);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-set-session"
- ></A
- >apd_set_session</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8493"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_set_session -- Changes or sets the current debugging level</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8496"
- ></A
- ><H2
- >Description</H2
- >void <B
- CLASS="methodname"
- >apd_set_session</B
- > ( int debug_level)<BR
- ></BR
- ><P
- >
This can be used to increase or decrease debugging in a different area of
- your application,.debug_level is an integer which is formed by adding
- together the following values:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="script"
- >FUNCTION_TRACE 1
- ARGS_TRACE 2
- ASSIGNMENT_TRACE 4
- STATEMENT_TRACE 8
- MEMORY_TRACE 16
- TIMING_TRACE 32
- SUMMARY_TRACE 64</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8508"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_set_session()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_set_session(9);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.apd-set-socket-session-trace"
- ></A
- >apd_set_socket_session_trace</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8513"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >apd_set_socket_session_trace -- Starts the remote session debugging</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8516"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >apd_set_socket_session_trace</B
- > ( string ip_address_or_unix_socket_file, int socket_type, int port, int debug_level)<BR
- ></BR
- ><P
- >
Connects to the tcp server (eg. tcplisten) specified IP or Unix Domain
- socket (like a file), and sends debugging data to the socket. You can
- use any port, but higher numbers are better as most of the lower numbers
- may be used by other system services.
- </P
- ><P
- >
the socket_type can be APD_AF_UNIX (for file based sockets) or APD_AF_INET
- (for standard tcp/ip)
- </P
- ><P
- >
debug_level is an integer which is formed by adding together the following
- values:
- </P
- ><P
- >
<TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="script"
- >FUNCTION_TRACE 1
- ARGS_TRACE 2
- ASSIGNMENT_TRACE 4
- STATEMENT_TRACE 8
- MEMORY_TRACE 16
- TIMING_TRACE 32
- SUMMARY_TRACE 64</PRE
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
I would seriously not recommend setting the value to 'zero' to start with,
- and use the breakpoint methods to start debugging at a specific place in
- the file.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8540"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >apd_set_socket_session_trace()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- apd_set_socket_session_trace("127.0.0.1",APD_AF_INET,7112,0);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.override-function"
- ></A
- >override_function</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8545"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >override_function -- Overrides built-in functions</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8548"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >override_function</B
- > ( string function_name, string function_args, string function_code)<BR
- ></BR
- ><P
- >
Syntax similar to create_function(). Overrides built-in functions
- (replaces them in the symbol table).
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8564"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >override_function()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.rename-function"
- ></A
- >rename_function</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8569"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >rename_function -- Renames orig_name to new_name in the global function_table</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8572"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >rename_function</B
- > ( string original_name, string new_name)<BR
- ></BR
- ><P
- >
Renames orig_name to new_name in the global function_table. Useful
- for temporarily overriding builtin functions.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8585"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >rename_function()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- rename_function('mysql_connect', 'debug_mysql_connect' );
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="reference"
- ><A
- NAME="ref.array"
- ></A
- ><DIV
- CLASS="TITLEPAGE"
- ><H1
- CLASS="title"
- >III. Array Functions</H1
- ><DIV
- CLASS="PARTINTRO"
- ><A
- NAME="AEN8592"
- ></A
- ><DIV
- CLASS="section"
- ><H2
- CLASS="section"
- ><A
- NAME="array.intro"
- >Introduction</A
- ></H2
- ><P
- >
These functions allow you to interact with and manipulate
- arrays in various ways. Arrays are essential for storing,
- managing, and operating on sets of variables.
- </P
- ><P
- >
Simple and multi-dimensional arrays are supported, and may be
- either user created or created by another function.
- There are specific database handling functions for populating
- arrays from database queries, and several functions return arrays.
- </P
- ><P
- >
Please see the <A
- HREF="#language.types.array"
- >Arrays</A
- >
- section of the manual for a detailed explanation of how arrays are
- implemented and used in PHP.
- See also <A
- HREF="#language.operators.array"
- >Array operators</A
- >
- for other ways how to manipulate the arrays.
- </P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.requirements"
- >Requirements</A
- ></H2
- ><P
- >No external libraries are needed to build this extension.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.installation"
- >Installation</A
- ></H2
- ><P
- >There is no installation needed to use these
- functions; they are part of the PHP core.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.configuration"
- >Runtime Configuration</A
- ></H2
- ><P
- >This extension has no configuration directives defined in <TT
- CLASS="filename"
- >php.ini</TT
- >.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.resources"
- >Resource Types</A
- ></H2
- ><P
- >This extension has no resource types defined.</P
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.constants"
- >Predefined Constants</A
- ></H2
- ><P
- >
The constants below are always available as part of the PHP core.
- </P
- ><P
- >
<P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >CASE_LOWER</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >CASE_LOWER</B
- ></TT
- > is used with
- <A
- HREF="#function.array-change-key-case"
- ><B
- CLASS="function"
- >array_change_key_case()</B
- ></A
- > and is used to convert array
- keys to lower case. This is also the default case for
- <A
- HREF="#function.array-change-key-case"
- ><B
- CLASS="function"
- >array_change_key_case()</B
- ></A
- >.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >CASE_UPPER</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >CASE_UPPER</B
- ></TT
- > is used with
- <A
- HREF="#function.array-change-key-case"
- ><B
- CLASS="function"
- >array_change_key_case()</B
- ></A
- > and is used to convert array
- keys to upper case.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- > Sorting order flags:
- <P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >SORT_ASC</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >SORT_ASC</B
- ></TT
- > is used with
- <A
- HREF="#function.array-multisort"
- ><B
- CLASS="function"
- >array_multisort()</B
- ></A
- > to sort in ascending order.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >SORT_DESC</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >SORT_DESC</B
- ></TT
- > is used with
- <A
- HREF="#function.array-multisort"
- ><B
- CLASS="function"
- >array_multisort()</B
- ></A
- > to sort in descending order.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- > Sorting type flags: used by various sort functions
- <P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >SORT_REGULAR</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >SORT_REGULAR</B
- ></TT
- > is used to compare items normally.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >SORT_NUMERIC</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >SORT_NUMERIC</B
- ></TT
- > is used to compare items numerically.
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >SORT_STRING</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
<TT
- CLASS="constant"
- ><B
- >SORT_STRING</B
- ></TT
- > is used to compare items as strings.
- </P
- ></DD
- ></DL
- ></DIV
- >
- </P
- ><P
- ></P
- ><DIV
- CLASS="variablelist"
- ><DL
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >COUNT_NORMAL</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >COUNT_RECURSIVE</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_OVERWRITE</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_SKIP</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_PREFIX_SAME</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_PREFIX_ALL</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_PREFIX_INVALID</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_PREFIX_IF_EXISTS</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_IF_EXISTS</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ><DT
- ><TT
- CLASS="constant"
- ><B
- >EXTR_REFS</B
- ></TT
- >
- (<A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- >)</DT
- ><DD
- ><P
- >
- </P
- ></DD
- ></DL
- ></DIV
- ></DIV
- ><DIV
- CLASS="section"
- ><HR><H2
- CLASS="section"
- ><A
- NAME="array.seealso"
- >See Also</A
- ></H2
- ><P
- >
See also <A
- HREF="#function.is-array"
- ><B
- CLASS="function"
- >is_array()</B
- ></A
- >, <A
- HREF="#function.explode"
- ><B
- CLASS="function"
- >explode()</B
- ></A
- >,
- <A
- HREF="#function.implode"
- ><B
- CLASS="function"
- >implode()</B
- ></A
- >, <A
- HREF="#function.split"
- ><B
- CLASS="function"
- >split()</B
- ></A
- >,
- <A
- HREF="#function.preg-split"
- ><B
- CLASS="function"
- >preg_split()</B
- ></A
- >, and <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >.
- </P
- ></DIV
- ></DIV
- ><DIV
- CLASS="TOC"
- ><DL
- ><DT
- ><B
- >Table of Contents</B
- ></DT
- ><DT
- ><A
- HREF="#function.array-change-key-case"
- >array_change_key_case</A
- > -- Returns an array with all string keys lowercased or uppercased</DT
- ><DT
- ><A
- HREF="#function.array-chunk"
- >array_chunk</A
- > -- Split an array into chunks</DT
- ><DT
- ><A
- HREF="#function.array-combine"
- >array_combine</A
- > --
- Creates an array by using one array for keys and another for its values
- </DT
- ><DT
- ><A
- HREF="#function.array-count-values"
- >array_count_values</A
- > -- Counts all the values of an array</DT
- ><DT
- ><A
- HREF="#function.array-diff-assoc"
- >array_diff_assoc</A
- > -- Computes the difference of arrays with additional index check</DT
- ><DT
- ><A
- HREF="#function.array-diff-key"
- >array_diff_key</A
- > -- Computes the difference of arrays using keys for comparison</DT
- ><DT
- ><A
- HREF="#function.array-diff-uassoc"
- >array_diff_uassoc</A
- > --
- Computes the difference of arrays with additional index check
- which is performed by a user supplied callback function
- </DT
- ><DT
- ><A
- HREF="#function.array-diff-ukey"
- >array_diff_ukey</A
- > -- Computes the difference of arrays using a callback function on the keys for comparison</DT
- ><DT
- ><A
- HREF="#function.array-diff"
- >array_diff</A
- > -- Computes the difference of arrays</DT
- ><DT
- ><A
- HREF="#function.array-fill"
- >array_fill</A
- > -- Fill an array with values</DT
- ><DT
- ><A
- HREF="#function.array-filter"
- >array_filter</A
- > --
- Filters elements of an array using a callback function
- </DT
- ><DT
- ><A
- HREF="#function.array-flip"
- >array_flip</A
- > -- Exchanges all keys with their associated values in an array</DT
- ><DT
- ><A
- HREF="#function.array-intersect-assoc"
- >array_intersect_assoc</A
- > -- Computes the intersection of arrays with additional index check</DT
- ><DT
- ><A
- HREF="#function.array-intersect-key"
- >array_intersect_key</A
- > -- Computes the intersection of arrays using keys for comparison</DT
- ><DT
- ><A
- HREF="#function.array-intersect-uassoc"
- >array_intersect_uassoc</A
- > -- Computes the intersection of arrays with additional index check, compares indexes by a callback function</DT
- ><DT
- ><A
- HREF="#function.array-intersect-ukey"
- >array_intersect_ukey</A
- > -- Computes the intersection of arrays using a callback function on the keys for comparison</DT
- ><DT
- ><A
- HREF="#function.array-intersect"
- >array_intersect</A
- > -- Computes the intersection of arrays</DT
- ><DT
- ><A
- HREF="#function.array-key-exists"
- >array_key_exists</A
- > -- Checks if the given key or index exists in the array</DT
- ><DT
- ><A
- HREF="#function.array-keys"
- >array_keys</A
- > -- Return all the keys of an array</DT
- ><DT
- ><A
- HREF="#function.array-map"
- >array_map</A
- > --
- Applies the callback to the elements of the given arrays
- </DT
- ><DT
- ><A
- HREF="#function.array-merge-recursive"
- >array_merge_recursive</A
- > -- Merge two or more arrays recursively</DT
- ><DT
- ><A
- HREF="#function.array-merge"
- >array_merge</A
- > -- Merge one or more arrays</DT
- ><DT
- ><A
- HREF="#function.array-multisort"
- >array_multisort</A
- > -- Sort multiple or multi-dimensional arrays</DT
- ><DT
- ><A
- HREF="#function.array-pad"
- >array_pad</A
- > --
- Pad array to the specified length with a value
- </DT
- ><DT
- ><A
- HREF="#function.array-pop"
- >array_pop</A
- > -- Pop the element off the end of array</DT
- ><DT
- ><A
- HREF="#function.array-push"
- >array_push</A
- > --
- Push one or more elements onto the end of array
- </DT
- ><DT
- ><A
- HREF="#function.array-rand"
- >array_rand</A
- > --
- Pick one or more random entries out of an array
- </DT
- ><DT
- ><A
- HREF="#function.array-reduce"
- >array_reduce</A
- > --
- Iteratively reduce the array to a single value using a callback
- function
- </DT
- ><DT
- ><A
- HREF="#function.array-reverse"
- >array_reverse</A
- > --
- Return an array with elements in reverse order
- </DT
- ><DT
- ><A
- HREF="#function.array-search"
- >array_search</A
- > --
- Searches the array for a given value and returns the
- corresponding key if successful
- </DT
- ><DT
- ><A
- HREF="#function.array-shift"
- >array_shift</A
- > --
- Shift an element off the beginning of array
- </DT
- ><DT
- ><A
- HREF="#function.array-slice"
- >array_slice</A
- > -- Extract a slice of the array</DT
- ><DT
- ><A
- HREF="#function.array-splice"
- >array_splice</A
- > --
- Remove a portion of the array and replace it with something
- else
- </DT
- ><DT
- ><A
- HREF="#function.array-sum"
- >array_sum</A
- > --
- Calculate the sum of values in an array
- </DT
- ><DT
- ><A
- HREF="#function.array-udiff-assoc"
- >array_udiff_assoc</A
- > -- Computes the difference of arrays with additional index check, compares data by a callback function</DT
- ><DT
- ><A
- HREF="#function.array-udiff-uassoc"
- >array_udiff_uassoc</A
- > -- Computes the difference of arrays with additional index check, compares data and indexes by a callback function</DT
- ><DT
- ><A
- HREF="#function.array-udiff"
- >array_udiff</A
- > -- Computes the difference of arrays by using a callback function for data comparison</DT
- ><DT
- ><A
- HREF="#function.array-uintersect-assoc"
- >array_uintersect_assoc</A
- > -- Computes the intersection of arrays with additional index check, compares data by a callback function</DT
- ><DT
- ><A
- HREF="#function.array-uintersect-uassoc"
- >array_uintersect_uassoc</A
- > -- Computes the intersection of arrays with additional index check, compares data and indexes by a callback functions</DT
- ><DT
- ><A
- HREF="#function.array-uintersect"
- >array_uintersect</A
- > -- Computes the intersection of arrays, compares data by a callback function</DT
- ><DT
- ><A
- HREF="#function.array-unique"
- >array_unique</A
- > -- Removes duplicate values from an array</DT
- ><DT
- ><A
- HREF="#function.array-unshift"
- >array_unshift</A
- > --
- Prepend one or more elements to the beginning of an array
- </DT
- ><DT
- ><A
- HREF="#function.array-values"
- >array_values</A
- > -- Return all the values of an array</DT
- ><DT
- ><A
- HREF="#function.array-walk-recursive"
- >array_walk_recursive</A
- > --
- Apply a user function recursively to every member of an array
- </DT
- ><DT
- ><A
- HREF="#function.array-walk"
- >array_walk</A
- > --
- Apply a user function to every member of an array
- </DT
- ><DT
- ><A
- HREF="#function.array"
- >array</A
- > --
- Create an array
- </DT
- ><DT
- ><A
- HREF="#function.arsort"
- >arsort</A
- > --
- Sort an array in reverse order and maintain index association
- </DT
- ><DT
- ><A
- HREF="#function.asort"
- >asort</A
- > -- Sort an array and maintain index association</DT
- ><DT
- ><A
- HREF="#function.compact"
- >compact</A
- > --
- Create array containing variables and their values
- </DT
- ><DT
- ><A
- HREF="#function.count"
- >count</A
- > -- Count elements in an array, or properties in an object</DT
- ><DT
- ><A
- HREF="#function.current"
- >current</A
- > -- Return the current element in an array</DT
- ><DT
- ><A
- HREF="#function.each"
- >each</A
- > --
- Return the current key and value pair from an array and advance
- the array cursor
- </DT
- ><DT
- ><A
- HREF="#function.end"
- >end</A
- > --
- Set the internal pointer of an array to its last element
- </DT
- ><DT
- ><A
- HREF="#function.extract"
- >extract</A
- > --
- Import variables into the current symbol table from an array
- </DT
- ><DT
- ><A
- HREF="#function.in-array"
- >in_array</A
- > -- Checks if a value exists in an array</DT
- ><DT
- ><A
- HREF="#function.key"
- >key</A
- > -- Fetch a key from an associative array</DT
- ><DT
- ><A
- HREF="#function.krsort"
- >krsort</A
- > -- Sort an array by key in reverse order</DT
- ><DT
- ><A
- HREF="#function.ksort"
- >ksort</A
- > -- Sort an array by key</DT
- ><DT
- ><A
- HREF="#function.list"
- >list</A
- > --
- Assign variables as if they were an array
- </DT
- ><DT
- ><A
- HREF="#function.natcasesort"
- >natcasesort</A
- > --
- Sort an array using a case insensitive "natural order" algorithm
- </DT
- ><DT
- ><A
- HREF="#function.natsort"
- >natsort</A
- > --
- Sort an array using a "natural order" algorithm
- </DT
- ><DT
- ><A
- HREF="#function.next"
- >next</A
- > --
- Advance the internal array pointer of an array
- </DT
- ><DT
- ><A
- HREF="#function.pos"
- >pos</A
- > -- Alias of <A
- HREF="#function.current"
- ><B
- CLASS="function"
- >current()</B
- ></A
- ></DT
- ><DT
- ><A
- HREF="#function.prev"
- >prev</A
- > -- Rewind the internal array pointer</DT
- ><DT
- ><A
- HREF="#function.range"
- >range</A
- > --
- Create an array containing a range of elements
- </DT
- ><DT
- ><A
- HREF="#function.reset"
- >reset</A
- > --
- Set the internal pointer of an array to its first element
- </DT
- ><DT
- ><A
- HREF="#function.rsort"
- >rsort</A
- > -- Sort an array in reverse order</DT
- ><DT
- ><A
- HREF="#function.shuffle"
- >shuffle</A
- > -- Shuffle an array</DT
- ><DT
- ><A
- HREF="#function.sizeof"
- >sizeof</A
- > -- Alias of <A
- HREF="#function.count"
- ><B
- CLASS="function"
- >count()</B
- ></A
- ></DT
- ><DT
- ><A
- HREF="#function.sort"
- >sort</A
- > -- Sort an array</DT
- ><DT
- ><A
- HREF="#function.uasort"
- >uasort</A
- > --
- Sort an array with a user-defined comparison function and
- maintain index association
- </DT
- ><DT
- ><A
- HREF="#function.uksort"
- >uksort</A
- > --
- Sort an array by keys using a user-defined comparison function
- </DT
- ><DT
- ><A
- HREF="#function.usort"
- >usort</A
- > --
- Sort an array by values using a user-defined comparison function
- </DT
- ></DL
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.array-change-key-case"
- ></A
- >array_change_key_case</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8747"
- ></A
- ><P
- > (PHP 4 >= 4.2.0, PHP 5)</P
- >array_change_key_case -- Returns an array with all string keys lowercased or uppercased</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8750"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_change_key_case</B
- > ( array input [, int case])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_change_key_case()</B
- > changes the
- keys in the <VAR
- CLASS="parameter"
- >input</VAR
- > array to
- be all lowercase or uppercase. The change depends
- on the last optional <VAR
- CLASS="parameter"
- >case</VAR
- >
- parameter. You can pass two constants there,
- <TT
- CLASS="constant"
- ><B
- >CASE_UPPER</B
- ></TT
- > and
- <TT
- CLASS="constant"
- ><B
- >CASE_LOWER</B
- ></TT
- >. The default is
- <TT
- CLASS="constant"
- ><B
- >CASE_LOWER</B
- ></TT
- >. The function will leave
- number indices as is.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8768"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_change_key_case()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input_array = array("FirSt" => 1, "SecOnd" => 4);
- print_r(array_change_key_case($input_array, CASE_UPPER));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [FIRST] => 1
- [SECOND] => 4
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
If an array has indices that will be the same once run through this
- function (e.g. "keY" and "kEY"), the value that is later in the array
- will override other indices.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-chunk"
- ></A
- >array_chunk</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8776"
- ></A
- ><P
- > (PHP 4 >= 4.2.0, PHP 5)</P
- >array_chunk -- Split an array into chunks</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8779"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_chunk</B
- > ( array input, int size [, bool preserve_keys])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_chunk()</B
- > splits the array into
- several arrays with <VAR
- CLASS="parameter"
- >size</VAR
- > values
- in them. You may also have an array with less values
- at the end. You get the arrays as members of a
- multidimensional array indexed with numbers starting
- from zero.
- </P
- ><P
- >
By setting the optional <VAR
- CLASS="parameter"
- >preserve_keys</VAR
- >
- parameter to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >, you can force PHP to preserve the original
- keys from the input array. If you specify <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > new number
- indices will be used in each resulting array with
- indices starting from zero. The default is <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
- </P
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8801"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_chunk()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input_array = array('a', 'b', 'c', 'd', 'e');
- print_r(array_chunk($input_array, 2));
- print_r(array_chunk($input_array, 2, true));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >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
- )
-
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><H1
- ><A
- NAME="function.array-combine"
- ></A
- >array_combine</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8808"
- ></A
- ><P
- > (PHP 5)</P
- >array_combine --
- Creates an array by using one array for keys and another for its values
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8811"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_combine</B
- > ( array keys, array values)<BR
- ></BR
- ><P
- >
Returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > by using the values from the
- <VAR
- CLASS="parameter"
- >keys</VAR
- > array as keys and the values from the
- <VAR
- CLASS="parameter"
- >values</VAR
- > array as the corresponding values.
- </P
- ><P
- >
Returns <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > if the number of elements for each array isn't equal or
- if the arrays are empty.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8829"
- ></A
- ><P
- ><B
- >Example 1. A simple <B
- CLASS="function"
- >array_combine()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = array('green', 'red', 'yellow');
- $b = array('avocado', 'apple', 'banana');
- $c = array_combine($a, $b);
-
- print_r($c);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [green] => avocado
- [red] => apple
- [yellow] => banana
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-merge"
- ><B
- CLASS="function"
- >array_merge()</B
- ></A
- >,
- <A
- HREF="#function.array-walk"
- ><B
- CLASS="function"
- >array_walk()</B
- ></A
- >, and
- <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-count-values"
- ></A
- >array_count_values</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8840"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_count_values -- Counts all the values of an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8843"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_count_values</B
- > ( array input)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_count_values()</B
- > returns an array using
- the values of the <VAR
- CLASS="parameter"
- >input</VAR
- > array as keys and
- their frequency in <VAR
- CLASS="parameter"
- >input</VAR
- > as values.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8856"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_count_values()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array = array(1, "hello", 1, "world", "hello");
- print_r(array_count_values($array));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [1] => 2
- [hello] => 2
- [world] => 1
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.count"
- ><B
- CLASS="function"
- >count()</B
- ></A
- >,
- <A
- HREF="#function.array-unique"
- ><B
- CLASS="function"
- >array_unique()</B
- ></A
- >,
- <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- >, and
- <A
- HREF="#function.count-chars"
- ><B
- CLASS="function"
- >count_chars()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-diff-assoc"
- ></A
- >array_diff_assoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8868"
- ></A
- ><P
- > (PHP 4 >= 4.3.0, PHP 5)</P
- >array_diff_assoc -- Computes the difference of arrays with additional index check</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8871"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_diff_assoc</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_diff_assoc()</B
- > returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >
- containing all the values from <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that the keys are used in the comparison unlike
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8891"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_diff_assoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "green", "yellow", "red");
- $result = array_diff_assoc($array1, $array2);
- print_r($result);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [b] => brown
- [c] => blue
- [0] => red
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example above you see the <VAR
- CLASS="literal"
- >"a" => "green"</VAR
- >
- pair is present in both arrays and thus it is not in the ouput from the
- function. Unlike this, the pair <VAR
- CLASS="literal"
- >0 => "red"</VAR
- >
- is in the ouput because in the second argument <VAR
- CLASS="literal"
- >"red"</VAR
- >
- has key which is <VAR
- CLASS="literal"
- >1</VAR
- >.
- </P
- ><P
- >
Two values from <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >key => value</I
- ></SPAN
- > pairs are
- considered equal only if <VAR
- CLASS="literal"
- >(string) $elem1 === (string)
- $elem2 </VAR
- >. In other words a strict check takes place so
- the string representations must be the same.
-
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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,
- <VAR
- CLASS="literal"
- >array_diff_assoc($array1[0], $array2[0]);</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- and <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-diff-key"
- ></A
- >array_diff_key</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8913"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >array_diff_key -- Computes the difference of arrays using keys for comparison</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8916"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_diff_key</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_diff_key()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that have keys that are not present in any of the other arguments.
- Note that the associativity is preserved. This function is like
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > except the comparison is done on the
- keys instead of the values.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8935"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_diff_key()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
- $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
-
- var_dump(array_diff_key($array1, $array2));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(2) {
- ["red"]=>
- int(2)
- ["purple"]=>
- int(4)
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The two keys from the <VAR
- CLASS="literal"
- >key => value</VAR
- > pairs are
- considered equal only if
- <VAR
- CLASS="literal"
- >(string) $key1 === (string) $key2 </VAR
- >. In other words
- a strict type check is executed so the string representation must be
- the same.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Please note that this function only checks one dimension of a n-dimensional
- array. Of course you can check deeper dimensions by using
- <VAR
- CLASS="literal"
- >array_diff_key($array1[0], $array2[0]);</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-ukey"
- ><B
- CLASS="function"
- >array_diff_ukey()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-key"
- ><B
- CLASS="function"
- >array_intersect_key()</B
- ></A
- > and
- <A
- HREF="#function.array-intersect-ukey"
- ><B
- CLASS="function"
- >array_intersect_ukey()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-diff-uassoc"
- ></A
- >array_diff_uassoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN8961"
- ></A
- ><P
- > (PHP 5)</P
- >array_diff_uassoc --
- Computes the difference of arrays with additional index check
- which is performed by a user supplied callback function
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN8964"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_diff_uassoc</B
- > ( array array1, array array2 [, array ..., callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_diff_uassoc()</B
- > returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >
- containing all the values from <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that the keys are used in the comparison unlike
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >. 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 <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- > where an
- internal function for comparing the indices is used.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN8988"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_diff_uassoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [b] => brown
- [c] => blue
- [0] => red
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example above you see the <VAR
- CLASS="literal"
- >"a" => "green"</VAR
- >
- pair is present in both arrays and thus it is not in the ouput from the
- function. Unlike this, the pair <VAR
- CLASS="literal"
- >0 => "red"</VAR
- >
- is in the ouput because in the second argument <VAR
- CLASS="literal"
- >"red"</VAR
- >
- has key which is <VAR
- CLASS="literal"
- >1</VAR
- >.
- </P
- ><P
- >
The equality of 2 indices is checked by the user supplied callback function.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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,
- <VAR
- CLASS="literal"
- >array_diff_uassoc($array1[0], $array2[0], "key_compare_func");</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-diff-ukey"
- ></A
- >array_diff_ukey</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9015"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >array_diff_ukey -- Computes the difference of arrays using a callback function on the keys for comparison</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9018"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_diff_ukey</B
- > ( array array1, array array2 [, array ..., callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_diff_ukey()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that have keys that are not present in any of the other arguments.
- Note that the associativity is preserved. This function is like
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > except the comparison is done on the
- keys instead of the values.
- </P
- ><P
- >
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 key is considered to be respectively less than, equal to, or
- greater than the second.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9041"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_diff_ukey()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function key_compare_func($key1, $key2)
- {
- if ($key1 == $key2)
- return 0;
- else if ($key1 > $key2)
- return 1;
- else
- return -1;
- }
-
- $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
- $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
-
- var_dump(array_diff_ukey($array1, $array2, 'key_compare_func'));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(2) {
- ["red"]=>
- int(2)
- ["purple"]=>
- int(4)
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
The two keys from the <VAR
- CLASS="literal"
- >key => value</VAR
- > pairs are
- considered equal only if
- <VAR
- CLASS="literal"
- >(string) $key1 === (string) $key2 </VAR
- >. In other words
- a strict type check is executed so the string representation must be
- the same.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Please note that this function only checks one dimension of a n-dimensional
- array. Of course you can check deeper dimensions by using
- <VAR
- CLASS="literal"
- >array_diff_ukey($array1[0], $array2[0], 'callback_func');</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-key"
- ><B
- CLASS="function"
- >array_diff_key()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-key"
- ><B
- CLASS="function"
- >array_intersect_key()</B
- ></A
- > and
- <A
- HREF="#function.array-intersect-ukey"
- ><B
- CLASS="function"
- >array_intersect_ukey()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-diff"
- ></A
- >array_diff</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9067"
- ></A
- ><P
- > (PHP 4 >= 4.0.1, PHP 5)</P
- >array_diff -- Computes the difference of arrays</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9070"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_diff</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_diff()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that keys are preserved.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9088"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_diff()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "red", "blue", "red");
- $array2 = array("b" => "green", "yellow", "red");
- $result = array_diff($array1, $array2);
-
- print_r($result);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Multiple occurrences in $array1 are all treated the same way.
- This will output :
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [1] => blue
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Two elements are considered equal if and only if
- <VAR
- CLASS="literal"
- >(string) $elem1 === (string) $elem2</VAR
- >. In words:
- when the string representation is the same.
-
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Please note that this function only checks one dimension of a n-dimensional
- array. Of course you can check deeper dimensions by using
- <VAR
- CLASS="literal"
- >array_diff($array1[0], $array2[0]);</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
This was broken in PHP 4.0.4!
-
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >, and
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-fill"
- ></A
- >array_fill</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9107"
- ></A
- ><P
- > (PHP 4 >= 4.2.0, PHP 5)</P
- >array_fill -- Fill an array with values</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9110"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_fill</B
- > ( int start_index, int num, mixed value)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_fill()</B
- > fills an array with
- <VAR
- CLASS="parameter"
- >num</VAR
- > entries of the value of the
- <VAR
- CLASS="parameter"
- >value</VAR
- > parameter, keys starting at the
- <VAR
- CLASS="parameter"
- >start_index</VAR
- > parameter. Note that <VAR
- CLASS="parameter"
- >
num</VAR
- > must be a number greater than zero, or PHP will throw
- a warning.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9131"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_fill()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = array_fill(5, 6, 'banana');
- print_r($a);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
<VAR
- CLASS="varname"
- >$a</VAR
- > now is:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [5] => banana
- [6] => banana
- [7] => banana
- [8] => banana
- [9] => banana
- [10] => banana
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.str-repeat"
- ><B
- CLASS="function"
- >str_repeat()</B
- ></A
- > and
- <A
- HREF="#function.range"
- ><B
- CLASS="function"
- >range()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-filter"
- ></A
- >array_filter</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9142"
- ></A
- ><P
- > (PHP 4 >= 4.0.6, PHP 5)</P
- >array_filter --
- Filters elements of an array using a callback function
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9145"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_filter</B
- > ( array input [, callback callback])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_filter()</B
- > iterates over each value in
- the <VAR
- CLASS="parameter"
- >input</VAR
- > array passing them to the
- <VAR
- CLASS="parameter"
- >callback</VAR
- > function. If the <VAR
- CLASS="parameter"
- >
callback</VAR
- > function returns true, the current
- value from <VAR
- CLASS="parameter"
- >input</VAR
- > is returned into the
- result array. Array keys are preserved.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9163"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_filter()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function odd($var)
- {
- return($var % 2 == 1);
- }
-
- function even($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 "Odd :\n";
- print_r(array_filter($array1, "odd"));
- echo "Even:\n";
- print_r(array_filter($array2, "even"));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Odd :
- Array
- (
- [a] => 1
- [c] => 3
- [e] => 5
- )
- Even:
- Array
- (
- [0] => 6
- [2] => 8
- [4] => 10
- [6] => 12
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Users may not change the array itself from the callback
- function. e.g. Add/delete an element, unset the array that
- <B
- CLASS="function"
- >array_filter()</B
- > is applied to. If the array
- is changed, the behavior of this function is undefined.
- </P
- ><P
- >
If the <VAR
- CLASS="parameter"
- >callback</VAR
- > function is not supplied,
- <B
- CLASS="function"
- >array_filter()</B
- > will remove all the entries of
- <VAR
- CLASS="parameter"
- >input</VAR
- > that are equal to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >. See <A
- HREF="#language.types.boolean.casting"
- >converting to boolean</A
- >
- for more information.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9178"
- ></A
- ><P
- ><B
- >Example 2. <B
- CLASS="function"
- >array_filter()</B
- > without
- <VAR
- CLASS="parameter"
- >callback</VAR
- ></B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
-
- $entry = array(
- 0 => 'foo',
- 1 => false,
- 2 => -1,
- 3 => null,
- 4 => ''
- );
-
- print_r(array_filter($entry));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => foo
- [2] => -1
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-map"
- ><B
- CLASS="function"
- >array_map()</B
- ></A
- >,
- <A
- HREF="#function.array-reduce"
- ><B
- CLASS="function"
- >array_reduce()</B
- ></A
- >, and <A
- HREF="#function.array-walk"
- ><B
- CLASS="function"
- >array_walk()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-flip"
- ></A
- >array_flip</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9190"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_flip -- Exchanges all keys with their associated values in an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9193"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_flip</B
- > ( array trans)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_flip()</B
- > returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > in flip
- order, i.e. keys from <VAR
- CLASS="parameter"
- >trans</VAR
- > become values and values
- from <VAR
- CLASS="parameter"
- >trans</VAR
- > become keys.
- </P
- ><P
- >
Note that the values of <VAR
- CLASS="parameter"
- >trans</VAR
- > need to be valid
- keys, i.e. they need to be either <A
- HREF="#language.types.integer"
- ><B
- CLASS="type"
- >integer</B
- ></A
- > or
- <A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >. A warning will be emitted if a value has the wrong
- type, and the key/value pair in question <SPAN
- CLASS="emphasis"
- ><I
- CLASS="emphasis"
- >will not be
- flipped</I
- ></SPAN
- >.
- </P
- ><P
- >
If a value has several occurrences, the latest key will be
- used as its values, and all others will be lost.
- </P
- ><P
- >
<B
- CLASS="function"
- >array_flip()</B
- > returns <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >
- if it fails.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9216"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_flip()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $trans = array_flip($trans);
- $original = strtr($str, $trans);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9221"
- ></A
- ><P
- ><B
- >Example 2. <B
- CLASS="function"
- >array_flip()</B
- > example : collision</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $trans = array("a" => 1, "b" => 1, "c" => 2);
- $trans = array_flip($trans);
- print_r($trans);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
now <VAR
- CLASS="varname"
- >$trans</VAR
- > is:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [1] => b
- [2] => c
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- >,
- <A
- HREF="#function.array-keys"
- ><B
- CLASS="function"
- >array_keys()</B
- ></A
- >, and
- <A
- HREF="#function.array-reverse"
- ><B
- CLASS="function"
- >array_reverse()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-intersect-assoc"
- ></A
- >array_intersect_assoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9233"
- ></A
- ><P
- > (PHP 4 >= 4.3.0, PHP 5)</P
- >array_intersect_assoc -- Computes the intersection of arrays with additional index check</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9236"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_intersect_assoc</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_intersect_assoc()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments. Note that the keys are used in
- the comparison unlike in <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9255"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_intersect_assoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "green", "yellow", "red");
- $result_array = array_intersect_assoc($array1, $array2);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
$result_array will look like:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [a] => green
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example you see that only the pair <VAR
- CLASS="literal"
- >"a" =>
- "green"</VAR
- > is present in both arrays and thus is returned.
- The value <VAR
- CLASS="literal"
- >"red"</VAR
- > is not returned because in
- <VAR
- CLASS="varname"
- >$array1</VAR
- > its key is <VAR
- CLASS="literal"
- >0</VAR
- > while
- the key of "red" in <VAR
- CLASS="varname"
- >$array2</VAR
- > is
- <VAR
- CLASS="literal"
- >1</VAR
- >.
- </P
- ><P
- >
The two values from the <VAR
- CLASS="literal"
- >key => value</VAR
- > pairs are
- considered equal only if
- <VAR
- CLASS="literal"
- >(string) $elem1 === (string) $elem2 </VAR
- >. In other words
- a strict type check is executed so the string representation must be
- the same.
-
- </P
- ><P
- >
See also <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > and
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-intersect-key"
- ></A
- >array_intersect_key</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9279"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >array_intersect_key -- Computes the intersection of arrays using keys for comparison</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9282"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_intersect_key</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_intersect_key()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- which have matching keys that are present in all the arguments.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9300"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_intersect_key()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
- $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
-
- var_dump(array_intersect_key($array1, $array2));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(2) {
- ["blue"]=>
- int(1)
- ["green"]=>
- int(3)
- })</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example you see that only the keys <VAR
- CLASS="literal"
- >'blue'</VAR
- >
- and <VAR
- CLASS="literal"
- >'green'</VAR
- > are present in both arrays and thus
- returned. Also notice that the values for the keys
- <VAR
- CLASS="literal"
- >'blue'</VAR
- > and <VAR
- CLASS="literal"
- >'green'</VAR
- > differ between
- the two arrays. A match still occurs because only the keys are checked.
- The values returned are those of <VAR
- CLASS="parameter"
- >array1</VAR
- >.
- </P
- ><P
- >
The two keys from the <VAR
- CLASS="literal"
- >key => value</VAR
- > pairs are
- considered equal only if
- <VAR
- CLASS="literal"
- >(string) $key1 === (string) $key2 </VAR
- >. In other words
- a strict type check is executed so the string representation must be
- the same.
- </P
- ><P
- >
See also <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-key"
- ><B
- CLASS="function"
- >array_diff_key()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-ukey"
- ><B
- CLASS="function"
- >array_diff_ukey()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- > and
- <A
- HREF="#function.array-intersect-ukey"
- ><B
- CLASS="function"
- >array_intersect_ukey()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-intersect-uassoc"
- ></A
- >array_intersect_uassoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9329"
- ></A
- ><P
- > (PHP 5)</P
- >array_intersect_uassoc -- Computes the intersection of arrays with additional index check, compares indexes by a callback function</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9332"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_intersect_uassoc</B
- > ( array array1, array array2 [, array ..., callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_intersect_uassoc()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments. Note that the keys are used in
- the comparison unlike in <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >.
- </P
- ><P
- >
The index 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.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9355"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_intersect_uassoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");
-
- print_r(array_intersect_uassoc($array1, $array2, "strcasecmp"));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [b] => brown
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-key"
- ><B
- CLASS="function"
- >array_intersect_key()</B
- ></A
- > and
- <A
- HREF="#function.array-intersect-ukey"
- ><B
- CLASS="function"
- >array_intersect_ukey()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-intersect-ukey"
- ></A
- >array_intersect_ukey</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9369"
- ></A
- ><P
- > (no version information, might be only in CVS)</P
- >array_intersect_ukey -- Computes the intersection of arrays using a callback function on the keys for comparison</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9372"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_intersect_ukey</B
- > ( array array1, array array2 [, array ..., callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_intersect_ukey()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- which have matching keys that are present in all the arguments.
- </P
- ><P
- >
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 key is considered to be respectively less than, equal to, or
- greater than the second.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9394"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_intersect_ukey()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function key_compare_func($key1, $key2)
- {
- if ($key1 == $key2)
- return 0;
- else if ($key1 > $key2)
- return 1;
- else
- return -1;
- }
-
- $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
- $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
-
- var_dump(array_intersect_ukey($array1, $array2, 'key_compare_func'));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(2) {
- ["blue"]=>
- int(1)
- ["green"]=>
- int(3)
- })</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example you see that only the keys <VAR
- CLASS="literal"
- >'blue'</VAR
- >
- and <VAR
- CLASS="literal"
- >'green'</VAR
- > are present in both arrays and thus
- returned. Also notice that the values for the keys
- <VAR
- CLASS="literal"
- >'blue'</VAR
- > and <VAR
- CLASS="literal"
- >'green'</VAR
- > differ between
- the two arrays. A match still occurs because only the keys are checked.
- The values returned are those of <VAR
- CLASS="parameter"
- >array1</VAR
- >.
- </P
- ><P
- >
The two keys from the <VAR
- CLASS="literal"
- >key => value</VAR
- > pairs are
- considered equal only if
- <VAR
- CLASS="literal"
- >(string) $key1 === (string) $key2 </VAR
- >. In other words
- a strict type check is executed so the string representation must be
- the same.
- </P
- ><P
- >
See also <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-key"
- ><B
- CLASS="function"
- >array_diff_key()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-ukey"
- ><B
- CLASS="function"
- >array_diff_ukey()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- > and
- <A
- HREF="#function.array-intersect-key"
- ><B
- CLASS="function"
- >array_intersect_key()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-intersect"
- ></A
- >array_intersect</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9423"
- ></A
- ><P
- > (PHP 4 >= 4.0.1, PHP 5)</P
- >array_intersect -- Computes the intersection of arrays</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9426"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_intersect</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_intersect()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments.
- Note that keys are preserved.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9444"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_intersect()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "red", "blue");
- $array2 = array("b" => "green", "yellow", "red");
- $result = array_intersect($array1, $array2);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This makes <VAR
- CLASS="varname"
- >$result</VAR
- > have
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [a] => green
- [0] => red
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Two elements are considered equal if and only if
- <VAR
- CLASS="literal"
- >(string) $elem1 === (string) $elem2</VAR
- >. In words:
- when the string representation is the same.
-
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >, and
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-key-exists"
- ></A
- >array_key_exists</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9459"
- ></A
- ><P
- > (PHP 4 >= 4.1.0, PHP 5)</P
- >array_key_exists -- Checks if the given key or index exists in the array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9462"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >array_key_exists</B
- > ( mixed key, array search)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_key_exists()</B
- > returns <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > if the
- given <VAR
- CLASS="parameter"
- >key</VAR
- > is set in the array.
- <VAR
- CLASS="parameter"
- >key</VAR
- > can be any value possible
- for an array index. <B
- CLASS="function"
- >array_key_exists()</B
- > also works
- on objects.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9480"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_key_exists()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $search_array = array('first' => 1, 'second' => 4);
- if (array_key_exists('first', $search_array)) {
- echo "The 'first' element is in the array";
- }
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The name of this function is <B
- CLASS="function"
- >key_exists()</B
- >
- in PHP 4.0.6.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9487"
- ></A
- ><P
- ><B
- >Example 2. <B
- CLASS="function"
- >array_key_exists()</B
- > vs <A
- HREF="#function.isset"
- ><B
- CLASS="function"
- >isset()</B
- ></A
- ></B
- ></P
- ><P
- >
<A
- HREF="#function.isset"
- ><B
- CLASS="function"
- >isset()</B
- ></A
- > does not return <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > for array keys
- that correspond to a <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > value, while
- <B
- CLASS="function"
- >array_key_exists()</B
- > does.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $search_array = array('first' => null, 'second' => 4);
-
- // returns false
- isset($search_array['first']);
-
- // returns true
- array_key_exists('first', $search_array);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
See also <A
- HREF="#function.isset"
- ><B
- CLASS="function"
- >isset()</B
- ></A
- >,
- <A
- HREF="#function.array-keys"
- ><B
- CLASS="function"
- >array_keys()</B
- ></A
- >, and
- <A
- HREF="#function.in-array"
- ><B
- CLASS="function"
- >in_array()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-keys"
- ></A
- >array_keys</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9502"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_keys -- Return all the keys of an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9505"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_keys</B
- > ( array input [, mixed search_value [, bool strict]])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_keys()</B
- > returns the keys, numeric and
- string, from the <VAR
- CLASS="parameter"
- >input</VAR
- > array.
- </P
- ><P
- >
If the optional <VAR
- CLASS="parameter"
- >search_value</VAR
- > is specified,
- then only the keys for that value are returned. Otherwise, all
- the keys from the <VAR
- CLASS="parameter"
- >input</VAR
- > are returned.
- As of PHP 5, you can use <VAR
- CLASS="parameter"
- >strict</VAR
- > parameter for
- comparison including type (===).
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9527"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_keys()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array = array(0 => 100, "color" => "red");
- print_r(array_keys($array));
-
- $array = array("blue", "red", "green", "blue", "blue");
- print_r(array_keys($array, "blue"));
-
- $array = array("color" => array("blue", "red", "green"),
- "size" => array("small", "medium", "large"));
- print_r(array_keys($array));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => 0
- [1] => color
- )
- Array
- (
- [0] => 0
- [1] => 3
- [2] => 4
- )
- Array
- (
- [0] => color
- [1] => size
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- > and
- <A
- HREF="#function.array-key-exists"
- ><B
- CLASS="function"
- >array_key_exists()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-map"
- ></A
- >array_map</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9537"
- ></A
- ><P
- > (PHP 4 >= 4.0.6, PHP 5)</P
- >array_map --
- Applies the callback to the elements of the given arrays
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9540"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_map</B
- > ( callback callback, array arr1 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_map()</B
- > returns an array containing all
- the elements of <VAR
- CLASS="parameter"
- >arr1</VAR
- > after applying the
- <VAR
- CLASS="parameter"
- >callback</VAR
- > function to each one.
- The number of parameters that the <VAR
- CLASS="parameter"
- >callback</VAR
- >
- function accepts
- should match the number of arrays
- passed to the <B
- CLASS="function"
- >array_map()</B
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9561"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_map()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function cube($n)
- {
- return($n * $n * $n);
- }
-
- $a = array(1, 2, 3, 4, 5);
- $b = array_map("cube", $a);
- print_r($b);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This makes <VAR
- CLASS="varname"
- >$b</VAR
- > have:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => 1
- [1] => 8
- [2] => 27
- [3] => 64
- [4] => 125
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9569"
- ></A
- ><P
- ><B
- >Example 2. <B
- CLASS="function"
- >array_map()</B
- > - using more arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- function show_Spanish($n, $m)
- {
- return("The number $n is called $m in Spanish");
- }
-
- function map_Spanish($n, $m)
- {
- return(array($n => $m));
- }
-
- $a = array(1, 2, 3, 4, 5);
- $b = array("uno", "dos", "tres", "cuatro", "cinco");
-
- $c = array_map("show_Spanish", $a, $b);
- print_r($c);
-
- $d = array_map("map_Spanish", $a , $b);
- print_r($d);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >// printout of $c
- Array
- (
- [0] => The number 1 is called uno in Spanish
- [1] => The number 2 is called dos in Spanish
- [2] => The number 3 is called tres in Spanish
- [3] => The number 4 is called cuatro in Spanish
- [4] => The number 5 is called cinco in Spanish
- )
-
- // printout of $d
- Array
- (
- [0] => Array
- (
- [1] => uno
- )
-
- [1] => Array
- (
- [2] => dos
- )
-
- [2] => Array
- (
- [3] => tres
- )
-
- [3] => Array
- (
- [4] => cuatro
- )
-
- [4] => Array
- (
- [5] => cinco
- )
-
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
Usually when using two or more arrays, they should be of equal length
- because the callback function is applied in parallel to the corresponding
- elements.
- If the arrays are of unequal length, the shortest one will be extended
- with empty elements.
- </P
- ><P
- >
An interesting use of this function is to construct an array of arrays,
- which can be easily performed by using <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- >
- as the name of the callback function
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9579"
- ></A
- ><P
- ><B
- >Example 3. Creating an array of arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $a = array(1, 2, 3, 4, 5);
- $b = array("one", "two", "three", "four", "five");
- $c = array("uno", "dos", "tres", "cuatro", "cinco");
-
- $d = array_map(null, $a, $b, $c);
- print_r($d);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => Array
- (
- [0] => 1
- [1] => one
- [2] => uno
- )
-
- [1] => Array
- (
- [0] => 2
- [1] => two
- [2] => dos
- )
-
- [2] => Array
- (
- [0] => 3
- [1] => three
- [2] => tres
- )
-
- [3] => Array
- (
- [0] => 4
- [1] => four
- [2] => cuatro
- )
-
- [4] => Array
- (
- [0] => 5
- [1] => five
- [2] => cinco
- )
-
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-filter"
- ><B
- CLASS="function"
- >array_filter()</B
- ></A
- >,
- <A
- HREF="#function.array-reduce"
- ><B
- CLASS="function"
- >array_reduce()</B
- ></A
- >, and
- <A
- HREF="#function.array-walk"
- ><B
- CLASS="function"
- >array_walk()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-merge-recursive"
- ></A
- >array_merge_recursive</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9589"
- ></A
- ><P
- > (PHP 4 >= 4.0.1, PHP 5)</P
- >array_merge_recursive -- Merge two or more arrays recursively</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9592"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_merge_recursive</B
- > ( array array1, array array2 [, array ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_merge_recursive()</B
- > merges the elements of
- two or more arrays together so that the values of one are appended
- to the end of the previous one. It returns the resulting array.
- </P
- ><P
- >
If the input arrays have the same string keys, then the values for
- these keys are merged together into an array, and this is done
- recursively, so that if one of the values is an array itself, the
- function will merge it with a corresponding entry in another array
- too. If, however, the arrays have the same numeric key, the later
- value will not overwrite the original value, but will be appended.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9610"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_merge_recursive()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $ar1 = array("color" => array("favorite" => "red"), 5);
- $ar2 = array(10, "color" => array("favorite" => "green", "blue"));
- $result = array_merge_recursive($ar1, $ar2);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The <VAR
- CLASS="literal"
- >$result</VAR
- > will be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [color] => Array
- (
- [favorite] => Array
- (
- [0] => red
- [1] => green
- )
-
- [0] => blue
- )
-
- [0] => 5
- [1] => 10
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-merge"
- ><B
- CLASS="function"
- >array_merge()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-merge"
- ></A
- >array_merge</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9620"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_merge -- Merge one or more arrays</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9623"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_merge</B
- > ( array array1 [, array array2 [, array ...]])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_merge()</B
- > merges the elements of one or
- more arrays together so that the values of one are appended to
- the end of the previous one. It returns the resulting array.
- </P
- ><P
- >
If the input arrays have the same string keys, then the later value for
- that key will overwrite the previous one. If, however, the arrays
- contain numeric keys, the later value will <SPAN
- CLASS="strong"
- ><B
- CLASS="emphasis"
- >not</B
- ></SPAN
- > overwrite the original value, but will be
- appended.
- </P
- ><P
- >
If only one array is given and the array is numerically indexed, the
- keys get reindexed in a continuous way. For associative arrays, duplicate
- entries will be merged into the last one. See example three for details.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9643"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_merge()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("color" => "red", 2, 4);
- $array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
- $result = array_merge($array1, $array2);
- print_r($result);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The <VAR
- CLASS="varname"
- >$result</VAR
- > is:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [color] => green
- [0] => 2
- [1] => 4
- [2] => a
- [3] => b
- [shape] => trapezoid
- [4] => 4
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9651"
- ></A
- ><P
- ><B
- >Example 2. Simple <B
- CLASS="function"
- >array_merge()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array();
- $array2 = array(1 => "data");
- $result = array_merge($array1, $array2);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
Don't forget that numeric keys will be renumbered!
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => data
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
If you want to completely preserve the arrays and just want to append
- them to each other, use the <VAR
- CLASS="literal"
- >+</VAR
- > operator:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array();
- $array2 = array(1 => "data");
- $result = $array1 + $array2;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The numeric key will be preserved and thus the association remains.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [1] => data
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- <TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9662"
- ></A
- ><P
- ><B
- >Example 3. <B
- CLASS="function"
- >array_merge()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array_one = array(0 => "jay", 1 => "bob", 2 => "randal", 3 => "dante");
- $array_two = array("jay" => "bob", "randal" => "dante", "jay" => "jason");
-
- unset($array_one[2]);
-
- $result_one = array_merge($array_one);
- $result_two = array_merge($array_two);
-
- print_r($result_one);
- print_r($result_two);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => jay
- [1] => bob
- [2] => dante
- )
- Array
- (
- [jay] => jason
- [randal] => dante
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Shared keys will be overwritten on a first-come first-served basis.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >
The behavior of <B
- CLASS="function"
- >array_merge()</B
- > was modified in PHP 5. Unlike PHP 4, <B
- CLASS="function"
- >array_merge()</B
- >
- now only accepts parameters of type <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >. However, you can use typecasting
- to merge other types. See the example below for details.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9676"
- ></A
- ><P
- ><B
- >Example 4. <B
- CLASS="function"
- >array_merge()</B
- > PHP 5 example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $beginning = 'foo';
- $end = array(1 => 'bar');
- $result = array_merge((array)$beginning, (array)$end);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => foo
- [1] => bar
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-merge-recursive"
- ><B
- CLASS="function"
- >array_merge_recursive()</B
- ></A
- >,
- <A
- HREF="#function.array-combine"
- ><B
- CLASS="function"
- >array_combine()</B
- ></A
- > and
- <A
- HREF="#language.operators.array"
- >array operators</A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-multisort"
- ></A
- >array_multisort</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9687"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_multisort -- Sort multiple or multi-dimensional arrays</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9690"
- ></A
- ><H2
- >Description</H2
- >bool <B
- CLASS="methodname"
- >array_multisort</B
- > ( array ar1 [, mixed arg [, mixed ... [, array ...]]])<BR
- ></BR
- ><P
- >
Returns <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > on success or <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > on failure.
- </P
- ><P
- >
<B
- CLASS="function"
- >array_multisort()</B
- > can be used to sort several
- arrays at once, or a multi-dimensional array by one or more
- dimensions.
- </P
- ><P
- >
Associative (<A
- HREF="#language.types.string"
- ><B
- CLASS="type"
- >string</B
- ></A
- >) keys will be maintained, but numeric
- keys will be re-indexed.
- </P
- ><P
- >
The input arrays are treated as columns of a table to be sorted
- by rows - this resembles the functionality of SQL ORDER BY
- clause. The first array is the primary one to sort by. The rows
- (values) in that array that compare the same are sorted by the
- next input array, and so on.
- </P
- ><P
- >
The argument structure of this function is a bit unusual, but
- flexible. The first argument has to be an array. Subsequently,
- each argument can be either an array or a sorting flag from the
- following lists.
- </P
- ><P
- >
Sorting order flags:
- <P
- ></P
- ><UL
- ><LI
- ><P
- ><TT
- CLASS="constant"
- ><B
- >SORT_ASC</B
- ></TT
- > - Sort in ascending order</P
- ></LI
- ><LI
- ><P
- ><TT
- CLASS="constant"
- ><B
- >SORT_DESC</B
- ></TT
- > - Sort in descending order</P
- ></LI
- ></UL
- >
- </P
- ><P
- >
Sorting type flags:
- <P
- ></P
- ><UL
- ><LI
- ><P
- ><TT
- CLASS="constant"
- ><B
- >SORT_REGULAR</B
- ></TT
- > - Compare items normally</P
- ></LI
- ><LI
- ><P
- ><TT
- CLASS="constant"
- ><B
- >SORT_NUMERIC</B
- ></TT
- > - Compare items numerically</P
- ></LI
- ><LI
- ><P
- ><TT
- CLASS="constant"
- ><B
- >SORT_STRING</B
- ></TT
- > - Compare items as strings</P
- ></LI
- ></UL
- >
- </P
- ><P
- >
No two sorting flags of the same type can be specified after each
- array. The sorting flags specified after an array argument apply
- only to that array - they are reset to default <TT
- CLASS="constant"
- ><B
- >SORT_ASC</B
- ></TT
- > and
- <TT
- CLASS="constant"
- ><B
- >SORT_REGULAR</B
- ></TT
- > before each new array argument.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9739"
- ></A
- ><P
- ><B
- >Example 1. Sorting multiple arrays</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $ar1 = array("10", 100, 100, "a");
- $ar2 = array(1, 3, "2", 1);
- array_multisort($ar1, $ar2);
-
- var_dump($ar1);
- var_dump($ar2);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
In this example, after sorting, the first array will contain "10",
- "a", 100, 100. The second array will contain 1, 1, "2", 3. The
- entries in the second array corresponding to the identical
- entries in the first array (100 and 100) were sorted as well.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(4) {
- [0]=> string(2) "10"
- [1]=> string(1) "a"
- [2]=> int(100)
- [3]=> int(100)
- }
- array(4) {
- [0]=> int(1)
- [1]=> int(1)
- [2]=> string(1) "2"
- [3]=> int(3)
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9745"
- ></A
- ><P
- ><B
- >Example 2. Sorting multi-dimensional array</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
In this example, after sorting, the first array will contain "10",
- 100, 100, "a" (it was sorted as strings in ascending order). The
- second will contain 1, 3, "2", 1 (sorted as numbers, in
- descending order).
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >array(2) {
- [0]=> array(4) {
- [0]=> string(2) "10"
- [1]=> int(100)
- [2]=> int(100)
- [3]=> string(1) "a"
- }
- [1]=> array(4) {
- [0]=> int(1)
- [1]=> int(3)
- [2]=> string(1) "2"
- [3]=> int(1)
- }
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9751"
- ></A
- ><P
- ><B
- >Example 3. Sorting database results</B
- ></P
- ><P
- >
For this example, each element in the <VAR
- CLASS="varname"
- >data</VAR
- >
- array represents one row in a table. This type of dataset is typical
- of database records.
- </P
- ><P
- >
Example data:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >volume | edition
- -------+--------
- 67 | 2
- 86 | 1
- 85 | 6
- 98 | 2
- 86 | 6
- 67 | 7</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The data as an array, called <VAR
- CLASS="varname"
- >data</VAR
- >. This would usually,
- for example, be obtained by looping with <A
- HREF="#function.mysql-fetch-assoc"
- ><B
- CLASS="function"
- >mysql_fetch_assoc()</B
- ></A
- >.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $data[] = array('volume' => 67, 'edition' => 2);
- $data[] = array('volume' => 86, 'edition' => 1);
- $data[] = array('volume' => 85, 'edition' => 6);
- $data[] = array('volume' => 98, 'edition' => 2);
- $data[] = array('volume' => 86, 'edition' => 6);
- $data[] = array('volume' => 67, 'edition' => 7);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
In this example, we will order by <VAR
- CLASS="varname"
- >volume</VAR
- > descending,
- <VAR
- CLASS="varname"
- >edition</VAR
- > ascending.
- </P
- ><P
- >
We have an array of rows, but <B
- CLASS="function"
- >array_multisort()</B
- >
- requires an array of columns, so we use the the below code to obtain the
- columns, then perform the sorting.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- // Obtain a list of columns
- foreach ($data as $key => $row) {
- $volume[$key] = $row['volume'];
- $edition[$key] = $row['edition'];
- }
-
- // Sort the data with volume descending, edition ascending
- // Add $data as the last parameter, to sort by the common key
- array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
The dataset is now sorted, and will look like this:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >volume | edition
- -------+--------
- 98 | 2
- 86 | 1
- 86 | 6
- 85 | 6
- 67 | 2
- 67 | 7</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9770"
- ></A
- ><P
- ><B
- >Example 4. Case insensitive sorting</B
- ></P
- ><P
- >
Both <TT
- CLASS="constant"
- ><B
- >SORT_STRING</B
- ></TT
- > and
- <TT
- CLASS="constant"
- ><B
- >SORT_REGULAR</B
- ></TT
- > are case sensitive, strings
- starting with a capital letter will come before strings starting
- with a lowercase letter.
- </P
- ><P
- >
To perform a case insensitve search, force the sorting order to be
- determined by a lowercase copy of the original array.
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array = array('Alpha', 'atomic', 'Beta', 'bank');
- $array_lowercase = array_map('strtolower', $array);
-
- array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $array);
-
- print_r($array);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => Alpha
- [1] => atomic
- [2] => bank
- [3] => Beta
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-pad"
- ></A
- >array_pad</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9780"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_pad --
- Pad array to the specified length with a value
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9783"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_pad</B
- > ( array input, int pad_size, mixed pad_value)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_pad()</B
- > returns a copy of the
- <VAR
- CLASS="parameter"
- >input</VAR
- > padded to size specified by
- <VAR
- CLASS="parameter"
- >pad_size</VAR
- > with value
- <VAR
- CLASS="parameter"
- >pad_value</VAR
- >. If
- <VAR
- CLASS="parameter"
- >pad_size</VAR
- > is positive then the array is
- padded on the right, if it's negative then on the left. If the
- absolute value of <VAR
- CLASS="parameter"
- >pad_size</VAR
- > is less than or
- equal to the length of the <VAR
- CLASS="parameter"
- >input</VAR
- > then no
- padding takes place.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9806"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_pad()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array(12, 10, 9);
-
- $result = array_pad($input, 5, 0);
- // result is array(12, 10, 9, 0, 0)
-
- $result = array_pad($input, -7, -1);
- // result is array(-1, -1, -1, -1, 12, 10, 9)
-
- $result = array_pad($input, 2, "noop");
- // not padded
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-fill"
- ><B
- CLASS="function"
- >array_fill()</B
- ></A
- > and
- <A
- HREF="#function.range"
- ><B
- CLASS="function"
- >range()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-pop"
- ></A
- >array_pop</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9814"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_pop -- Pop the element off the end of array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9817"
- ></A
- ><H2
- >Description</H2
- >mixed <B
- CLASS="methodname"
- >array_pop</B
- > ( array &array)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_pop()</B
- > pops and returns the last value of
- the <VAR
- CLASS="parameter"
- >array</VAR
- >, shortening the
- <VAR
- CLASS="parameter"
- >array</VAR
- > by one element.
- If <VAR
- CLASS="parameter"
- >array</VAR
- > is empty (or is not an array),
- <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > will be returned.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >This function will
- <A
- HREF="#function.reset"
- ><B
- CLASS="function"
- >reset()</B
- ></A
- > the <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > pointer after
- use.</P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9836"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_pop()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $stack = array("orange", "banana", "apple", "raspberry");
- $fruit = array_pop($stack);
- print_r($stack);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
After this, <VAR
- CLASS="varname"
- >$stack</VAR
- > will have only 3 elements:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => orange
- [1] => banana
- [2] => apple
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
and <VAR
- CLASS="literal"
- >raspberry</VAR
- > will be assigned to
- <VAR
- CLASS="varname"
- >$fruit</VAR
- >.
- </P
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-push"
- ><B
- CLASS="function"
- >array_push()</B
- ></A
- >,
- <A
- HREF="#function.array-shift"
- ><B
- CLASS="function"
- >array_shift()</B
- ></A
- >, and
- <A
- HREF="#function.array-unshift"
- ><B
- CLASS="function"
- >array_unshift()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-push"
- ></A
- >array_push</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9851"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_push --
- Push one or more elements onto the end of array
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9854"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >array_push</B
- > ( array &array, mixed var [, mixed ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_push()</B
- > treats
- <VAR
- CLASS="parameter"
- >array</VAR
- > as a stack, and pushes the passed
- variables onto the end of <VAR
- CLASS="parameter"
- >array</VAR
- >. The
- length of <VAR
- CLASS="parameter"
- >array</VAR
- > increases by the number of
- variables pushed. Has the same effect as:
- <TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array[] = $var;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- >
- repeated for each <VAR
- CLASS="parameter"
- >var</VAR
- >.
- </P
- ><P
- >
Returns the new number of elements in the array.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9877"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_push()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $stack = array("orange", "banana");
- array_push($stack, "apple", "raspberry");
- print_r($stack);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This example would result in <VAR
- CLASS="varname"
- >$stack</VAR
- > having
- the following elements:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => orange
- [1] => banana
- [2] => apple
- [3] => raspberry
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If you use <B
- CLASS="function"
- >array_push()</B
- > to add one element to the
- array it's better to use <VAR
- CLASS="literal"
- >$array[] = </VAR
- > because in that
- way there is no overhead of calling a function.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-pop"
- ><B
- CLASS="function"
- >array_pop()</B
- ></A
- >,
- <A
- HREF="#function.array-shift"
- ><B
- CLASS="function"
- >array_shift()</B
- ></A
- >, and
- <A
- HREF="#function.array-unshift"
- ><B
- CLASS="function"
- >array_unshift()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-rand"
- ></A
- >array_rand</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9893"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_rand --
- Pick one or more random entries out of an array
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9896"
- ></A
- ><H2
- >Description</H2
- >mixed <B
- CLASS="methodname"
- >array_rand</B
- > ( array input [, int num_req])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_rand()</B
- > is rather useful when you want to
- pick one or more random entries out of an array. It takes an
- <VAR
- CLASS="parameter"
- >input</VAR
- > array and an optional argument
- <VAR
- CLASS="parameter"
- >num_req</VAR
- > which specifies how many entries you
- want to pick - if not specified, it defaults to 1.
- </P
- ><P
- >
If you are picking only one entry, <B
- CLASS="function"
- >array_rand()</B
- >
- returns the key for a random entry. Otherwise, it returns an array
- of keys for the random entries. This is done so that you can pick
- random keys as well as values out of the array.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >As of PHP 4.2.0, there is no need
- to seed the random number generator with <A
- HREF="#function.srand"
- ><B
- CLASS="function"
- >srand()</B
- ></A
- > or
- <A
- HREF="#function.mt-srand"
- ><B
- CLASS="function"
- >mt_srand()</B
- ></A
- > as this is now done automatically.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9918"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_rand()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- srand((float) microtime() * 10000000);
- $input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
- $rand_keys = array_rand($input, 2);
- echo $input[$rand_keys[0]] . "\n";
- echo $input[$rand_keys[1]] . "\n";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.shuffle"
- ><B
- CLASS="function"
- >shuffle()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-reduce"
- ></A
- >array_reduce</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9925"
- ></A
- ><P
- > (PHP 4 >= 4.0.5, PHP 5)</P
- >array_reduce --
- Iteratively reduce the array to a single value using a callback
- function
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9928"
- ></A
- ><H2
- >Description</H2
- >mixed <B
- CLASS="methodname"
- >array_reduce</B
- > ( array input, callback function [, int initial])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_reduce()</B
- > applies iteratively the
- <VAR
- CLASS="parameter"
- >function</VAR
- > function to the elements of the
- array <VAR
- CLASS="parameter"
- >input</VAR
- >, so as to reduce the array to
- a single value. If the optional <VAR
- CLASS="parameter"
- >initial</VAR
- > is
- available, it will be used at the beginning of the process, or as
- a final result in case the array is empty.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9948"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_reduce()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
This will result in <VAR
- CLASS="varname"
- >$b</VAR
- > containing
- <VAR
- CLASS="literal"
- >15</VAR
- >, <VAR
- CLASS="varname"
- >$c</VAR
- > containing
- <VAR
- CLASS="literal"
- >1200</VAR
- > (= 1*2*3*4*5*10), and
- <VAR
- CLASS="varname"
- >$d</VAR
- > containing <VAR
- CLASS="literal"
- >1</VAR
- >.
- </P
- ><P
- >
See also <A
- HREF="#function.array-filter"
- ><B
- CLASS="function"
- >array_filter()</B
- ></A
- >,
- <A
- HREF="#function.array-map"
- ><B
- CLASS="function"
- >array_map()</B
- ></A
- >,
- <A
- HREF="#function.array-unique"
- ><B
- CLASS="function"
- >array_unique()</B
- ></A
- >, and
- <A
- HREF="#function.array-count-values"
- ><B
- CLASS="function"
- >array_count_values()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-reverse"
- ></A
- >array_reverse</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN9965"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_reverse --
- Return an array with elements in reverse order
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN9968"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_reverse</B
- > ( array array [, bool preserve_keys])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_reverse()</B
- > takes input
- <VAR
- CLASS="parameter"
- >array</VAR
- > and returns a new array with the
- order of the elements reversed, preserving the keys if
- <VAR
- CLASS="parameter"
- >preserve_keys</VAR
- > is <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN9985"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_reverse()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array("php", 4.0, array("green", "red"));
- $result = array_reverse($input);
- $result_keyed = array_reverse($input, true);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This makes both <VAR
- CLASS="varname"
- >$result</VAR
- > and
- <VAR
- CLASS="varname"
- >$result_keyed</VAR
- > have the same elements, but
- note the difference between the keys. The printout of
- <VAR
- CLASS="varname"
- >$result</VAR
- > and
- <VAR
- CLASS="varname"
- >$result_keyed</VAR
- > will be:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => Array
- (
- [0] => green
- [1] => red
- )
-
- [1] => 4
- [2] => php
- )
- Array
- (
- [2] => Array
- (
- [0] => green
- [1] => red
- )
-
- [1] => 4
- [0] => php
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- The second parameter was added in PHP 4.0.3.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-flip"
- ><B
- CLASS="function"
- >array_flip()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-search"
- ></A
- >array_search</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10000"
- ></A
- ><P
- > (PHP 4 >= 4.0.5, PHP 5)</P
- >array_search --
- Searches the array for a given value and returns the
- corresponding key if successful
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10003"
- ></A
- ><H2
- >Description</H2
- >mixed <B
- CLASS="methodname"
- >array_search</B
- > ( mixed needle, array haystack [, bool strict])<BR
- ></BR
- ><P
- >
Searches <VAR
- CLASS="parameter"
- >haystack</VAR
- > for
- <VAR
- CLASS="parameter"
- >needle</VAR
- > and returns the key if it is found in
- the array, <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- > otherwise.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- If <VAR
- CLASS="parameter"
- >needle</VAR
- > is a string, the comparison is done
- in a case-sensitive manner.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Prior to PHP 4.2.0, <B
- CLASS="function"
- >array_search()</B
- > returns
- <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > on failure instead of <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
If the optional third parameter <VAR
- CLASS="parameter"
- >strict</VAR
- > is set to
- <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- > then the <B
- CLASS="function"
- >array_search()</B
- >
- will also check the types of the <VAR
- CLASS="parameter"
- >needle</VAR
- >
- in the <VAR
- CLASS="parameter"
- >haystack</VAR
- >.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >needle</VAR
- > is found in
- <VAR
- CLASS="parameter"
- >haystack</VAR
- > more than once, the first matching key
- is returned. To return the keys for all matching values, use
- <A
- HREF="#function.array-keys"
- ><B
- CLASS="function"
- >array_keys()</B
- ></A
- > with the optional
- <VAR
- CLASS="parameter"
- >search_value</VAR
- > parameter instead.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10041"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_search()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
-
- $key = array_search('green', $array); // $key = 2;
- $key = array_search('red', $array); // $key = 1;
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="warning"
- ><P
- ></P
- ><TABLE
- CLASS="warning"
- BORDER="1"
- WIDTH="100%"
- ><TR
- ><TD
- ALIGN="CENTER"
- ><B
- >Warning</B
- ></TD
- ></TR
- ><TR
- ><TD
- ALIGN="LEFT"
- ><P
- >This function may
- return Boolean <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, but may also return a non-Boolean value which
- evaluates to <TT
- CLASS="constant"
- ><B
- >FALSE</B
- ></TT
- >, such as <VAR
- CLASS="literal"
- >0</VAR
- > or
- "". Please read the section on <A
- HREF="#language.types.boolean"
- >Booleans</A
- > for more
- information. Use <A
- HREF="#language.operators.comparison"
- >the ===
- operator</A
- > for testing the return value of this
- function.</P
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ><P
- >
See also <A
- HREF="#function.array-keys"
- ><B
- CLASS="function"
- >array_keys()</B
- ></A
- >,
- <A
- HREF="#function.array-values"
- ><B
- CLASS="function"
- >array_values()</B
- ></A
- >,
- <A
- HREF="#function.array-key-exists"
- ><B
- CLASS="function"
- >array_key_exists()</B
- ></A
- >, and
- <A
- HREF="#function.in-array"
- ><B
- CLASS="function"
- >in_array()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-shift"
- ></A
- >array_shift</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10058"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_shift --
- Shift an element off the beginning of array
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10061"
- ></A
- ><H2
- >Description</H2
- >mixed <B
- CLASS="methodname"
- >array_shift</B
- > ( array &array)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_shift()</B
- > shifts the first value of the
- <VAR
- CLASS="parameter"
- >array</VAR
- > off and returns it, shortening the
- <VAR
- CLASS="parameter"
- >array</VAR
- > by one element and moving everything
- down. All numerical array keys will be modified to start counting from zero
- while literal keys won't be touched. If <VAR
- CLASS="parameter"
- >array</VAR
- > is empty
- (or is not an array), <TT
- CLASS="constant"
- ><B
- >NULL</B
- ></TT
- > will be returned.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >This function will
- <A
- HREF="#function.reset"
- ><B
- CLASS="function"
- >reset()</B
- ></A
- > the <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- > pointer after
- use.</P
- ></BLOCKQUOTE
- ></DIV
- ><TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10079"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_shift()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $stack = array("orange", "banana", "apple", "raspberry");
- $fruit = array_shift($stack);
- print_r($stack);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This would result in <VAR
- CLASS="varname"
- >$stack</VAR
- > having 3 elements left:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => banana
- [1] => apple
- [2] => raspberry
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
and <VAR
- CLASS="literal"
- >orange</VAR
- > will be assigned to
- <VAR
- CLASS="varname"
- >$fruit</VAR
- >.
- </P
- ></DIV
- ></TD
- ></TR
- ></TABLE
- ><P
- >
See also <A
- HREF="#function.array-unshift"
- ><B
- CLASS="function"
- >array_unshift()</B
- ></A
- >,
- <A
- HREF="#function.array-push"
- ><B
- CLASS="function"
- >array_push()</B
- ></A
- >, and
- <A
- HREF="#function.array-pop"
- ><B
- CLASS="function"
- >array_pop()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-slice"
- ></A
- >array_slice</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10094"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_slice -- Extract a slice of the array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10097"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_slice</B
- > ( array array, int offset [, int length [, bool preserve_keys]])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_slice()</B
- > returns the sequence of elements
- from the array <VAR
- CLASS="parameter"
- >array</VAR
- > as specified by the
- <VAR
- CLASS="parameter"
- >offset</VAR
- > and <VAR
- CLASS="parameter"
- >length</VAR
- >
- parameters.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >offset</VAR
- > is positive, the sequence will
- start at that offset in the <VAR
- CLASS="parameter"
- >array</VAR
- >. If
- <VAR
- CLASS="parameter"
- >offset</VAR
- > is negative, the sequence will
- start that far from the end of the <VAR
- CLASS="parameter"
- >array</VAR
- >.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >length</VAR
- > is given and is positive, then
- the sequence will have that many elements in it. If
- <VAR
- CLASS="parameter"
- >length</VAR
- > is given and is negative then the
- sequence will stop that many elements from the end of the
- array. If it is omitted, then the sequence will have everything
- from <VAR
- CLASS="parameter"
- >offset</VAR
- > up until the end of the
- <VAR
- CLASS="parameter"
- >array</VAR
- >.
- </P
- ><P
- >
Note that <B
- CLASS="function"
- >array_slice()</B
- > will reset the array keys by
- default. Since PHP 5.0.2, you can change this behaviour by setting
- <VAR
- CLASS="parameter"
- >preserve_keys</VAR
- > to <TT
- CLASS="constant"
- ><B
- >TRUE</B
- ></TT
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10134"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_slice()</B
- > examples</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array("a", "b", "c", "d", "e");
-
- $output = array_slice($input, 2); // returns "c", "d", and "e"
- $output = array_slice($input, -2, 1); // returns "d"
- $output = array_slice($input, 0, 3); // returns "a", "b", and "c"
-
- // note the differences in the array keys
- print_r(array_slice($input, 2, -1));
- print_r(array_slice($input, 2, -1, true));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0] => c
- [1] => d
- )
- Array
- (
- [2] => c
- [3] => d
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-splice"
- ><B
- CLASS="function"
- >array_splice()</B
- ></A
- > and
- <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-splice"
- ></A
- >array_splice</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10144"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_splice --
- Remove a portion of the array and replace it with something
- else
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10147"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_splice</B
- > ( array &input, int offset [, int length [, array replacement]])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_splice()</B
- > removes the elements designated
- by <VAR
- CLASS="parameter"
- >offset</VAR
- > and
- <VAR
- CLASS="parameter"
- >length</VAR
- > from the
- <VAR
- CLASS="parameter"
- >input</VAR
- > array, and replaces them with the
- elements of the <VAR
- CLASS="parameter"
- >replacement</VAR
- > array, if
- supplied. It returns an array containing the extracted elements.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >offset</VAR
- > is positive then the start of
- removed portion is at that offset from the beginning of the
- <VAR
- CLASS="parameter"
- >input</VAR
- > array. If
- <VAR
- CLASS="parameter"
- >offset</VAR
- > is negative then it starts that far
- from the end of the <VAR
- CLASS="parameter"
- >input</VAR
- > array.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >length</VAR
- > is omitted, removes everything
- from <VAR
- CLASS="parameter"
- >offset</VAR
- > to the end of the array. If
- <VAR
- CLASS="parameter"
- >length</VAR
- > is specified and is positive, then
- that many elements will be removed. If
- <VAR
- CLASS="parameter"
- >length</VAR
- > is specified and is negative then
- the end of the removed portion will be that many elements from
- the end of the array. Tip: to remove everything from
- <VAR
- CLASS="parameter"
- >offset</VAR
- > to the end of the array when
- <VAR
- CLASS="parameter"
- >replacement</VAR
- > is also specified, use
- <VAR
- CLASS="literal"
- >count($input)</VAR
- > for
- <VAR
- CLASS="parameter"
- >length</VAR
- >.
- </P
- ><P
- >
If <VAR
- CLASS="parameter"
- >replacement</VAR
- > array is specified, then
- the removed elements are replaced with elements from this array.
- If <VAR
- CLASS="parameter"
- >offset</VAR
- > and
- <VAR
- CLASS="parameter"
- >length</VAR
- > are such that nothing is removed,
- then the elements from the <VAR
- CLASS="parameter"
- >replacement</VAR
- >
- array are inserted in the place specified by the
- <VAR
- CLASS="parameter"
- >offset</VAR
- >. Tip: if the replacement is just
- one element it is not necessary to put <VAR
- CLASS="literal"
- >array()</VAR
- >
- around it, unless the element is an array itself.
- </P
- ><P
- >
The following statements change the values of <VAR
- CLASS="varname"
- >$input</VAR
- >
- the same way:
- <DIV
- CLASS="table"
- ><A
- NAME="AEN10193"
- ></A
- ><P
- ><B
- >Table 1. <B
- CLASS="function"
- >array_splice()</B
- > equivalents</B
- ></P
- ><TABLE
- BORDER="1"
- CLASS="CALSTABLE"
- ><COL><COL><TBODY
- ><TR
- ><TD
- >
array_push($input, $x, $y)
- </TD
- ><TD
- >
array_splice($input, count($input), 0, array($x, $y))
- </TD
- ></TR
- ><TR
- ><TD
- >
array_pop($input)
- </TD
- ><TD
- >
array_splice($input, -1)
- </TD
- ></TR
- ><TR
- ><TD
- >
array_shift($input)
- </TD
- ><TD
- >
array_splice($input, 0, 1)
- </TD
- ></TR
- ><TR
- ><TD
- >
array_unshift($input, $x, $y)
- </TD
- ><TD
- >
array_splice($input, 0, 0, array($x, $y))
- </TD
- ></TR
- ><TR
- ><TD
- >
$input[$x] = $y // for arrays where key equals offset
- </TD
- ><TD
- >
array_splice($input, $x, 1, $y)
- </TD
- ></TR
- ></TBODY
- ></TABLE
- ></DIV
- >
- </P
- ><P
- >
Returns the array consisting of removed elements.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10215"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_splice()</B
- > examples</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array("red", "green", "blue", "yellow");
- array_splice($input, 2);
- // $input is now array("red", "green")
-
- $input = array("red", "green", "blue", "yellow");
- array_splice($input, 1, -1);
- // $input is now array("red", "yellow")
-
- $input = array("red", "green", "blue", "yellow");
- array_splice($input, 1, count($input), "orange");
- // $input is now array("red", "orange")
-
- $input = array("red", "green", "blue", "yellow");
- array_splice($input, -1, 1, array("black", "maroon"));
- // $input is now array("red", "green",
- // "blue", "black", "maroon")
-
- $input = array("red", "green", "blue", "yellow");
- array_splice($input, 3, 0, "purple");
- // $input is now array("red", "green",
- // "blue", "purple", "yellow");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-slice"
- ><B
- CLASS="function"
- >array_slice()</B
- ></A
- >,
- <A
- HREF="#function.unset"
- ><B
- CLASS="function"
- >unset()</B
- ></A
- >, and
- <A
- HREF="#function.array-merge"
- ><B
- CLASS="function"
- >array_merge()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-sum"
- ></A
- >array_sum</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10224"
- ></A
- ><P
- > (PHP 4 >= 4.0.4, PHP 5)</P
- >array_sum --
- Calculate the sum of values in an array
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10227"
- ></A
- ><H2
- >Description</H2
- >number <B
- CLASS="methodname"
- >array_sum</B
- > ( array array)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_sum()</B
- > returns the sum of values
- in an array as an integer or float.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10238"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_sum()</B
- > examples</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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";
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >sum(a) = 20
- sum(b) = 6.9</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- PHP versions prior to 4.2.1 modified the passed array
- itself and converted strings to numbers (which most
- of the time converted them to zero, depending on
- their value).
- </P
- ></BLOCKQUOTE
- ></DIV
- ></DIV
- ><H1
- ><A
- NAME="function.array-udiff-assoc"
- ></A
- >array_udiff_assoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10247"
- ></A
- ><P
- > (PHP 5)</P
- >array_udiff_assoc -- Computes the difference of arrays with additional index check, compares data by a callback function</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10250"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_udiff_assoc</B
- > ( array array1, array array2 [, array ..., callback data_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_udiff_assoc()</B
- > returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >
- containing all the values from <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that the keys are used in the comparison unlike
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > and <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >.
- The comparison of arrays' data is performed by using an user-supplied
- callback. In this aspect the behaviour is opposite to the behaviour of
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- > which uses internal function for
- comparison.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10275"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_udiff_assoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0.1] => cr Object
- (
- [priv_member:private] => 9
- )
-
- [0.5] => cr Object
- (
- [priv_member:private] => 12
- )
-
- [0] => cr Object
- (
- [priv_member:private] => 23
- )
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example above you see the <VAR
- CLASS="literal"
- >"1" => new cr(4)</VAR
- >
- pair is present in both arrays and thus it is not in the ouput from the
- function.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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,
- <VAR
- CLASS="literal"
- >array_udiff_assoc($array1[0], $array2[0], "some_comparison_func");</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-udiff-uassoc"
- ></A
- >array_udiff_uassoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10299"
- ></A
- ><P
- > (PHP 5)</P
- >array_udiff_uassoc -- Computes the difference of arrays with additional index check, compares data and indexes by a callback function</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10302"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_udiff_uassoc</B
- > ( array array1, array array2 [, array ..., callback data_compare_func, callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_udiff_uassoc()</B
- > returns an <A
- HREF="#language.types.array"
- ><B
- CLASS="type"
- >array</B
- ></A
- >
- containing all the values from <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that the keys are used in the comparison unlike
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > and <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >.
- The comparison of arrays' data is performed by using an user-supplied
- callback : <VAR
- CLASS="parameter"
- >data_compare_func</VAR
- >. In this aspect
- the behaviour is opposite to the behaviour of
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- > which uses internal function for
- comparison. The comparison of keys (indices) is done also by the
- callback function <VAR
- CLASS="parameter"
- >key_compare_func</VAR
- >. This
- behaviour is unlike what <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- > does, since
- the latter compares the indices by using an internal function.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10333"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_udiff_uassoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0.1] => cr Object
- (
- [priv_member:private] => 9
- )
-
- [0.5] => cr Object
- (
- [priv_member:private] => 12
- )
-
- [0] => cr Object
- (
- [priv_member:private] => 23
- )
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
In our example above you see the <VAR
- CLASS="literal"
- >"1" => new cr(4)</VAR
- >
- 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.
- </P
- ><P
- >
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.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- 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,
- <VAR
- CLASS="literal"
- >array_udiff_uassoc($array1[0], $array2[0], "data_compare_func",
- "key_compare_func");</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff"
- ><B
- CLASS="function"
- >array_udiff()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-udiff"
- ></A
- >array_udiff</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10357"
- ></A
- ><P
- > (PHP 5)</P
- >array_udiff -- Computes the difference of arrays by using a callback function for data comparison</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10360"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_udiff</B
- > ( array array1, array array2 [, array ..., callback data_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_udiff()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are not present in any of the other arguments.
- Note that keys are preserved. For the comparison of the data
- <VAR
- CLASS="parameter"
- >data_compare_func</VAR
- > 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 <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- > which uses an
- internal function for comparing the data.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10383"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_udiff()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?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);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [0.5] => cr Object
- (
- [priv_member:private] => 12
- )
-
- [0] => cr Object
- (
- [priv_member:private] => 23
- )
-
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Two elements are considered equal if and only if
- <VAR
- CLASS="literal"
- >(string) $elem1 === (string) $elem2</VAR
- >. In words:
- when the string representation is the same.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Please note that this function only checks one dimension of a n-dimensional
- array. Of course you can check deeper dimensions by using
- <VAR
- CLASS="literal"
- >array_udiff($array1[0], $array2[0], "data_compare_func");</VAR
- >.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
See also
- <A
- HREF="#function.array-diff"
- ><B
- CLASS="function"
- >array_diff()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-assoc"
- ><B
- CLASS="function"
- >array_diff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-diff-uassoc"
- ><B
- CLASS="function"
- >array_diff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-assoc"
- ><B
- CLASS="function"
- >array_udiff_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-udiff-uassoc"
- ><B
- CLASS="function"
- >array_udiff_uassoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-uintersect-assoc"
- ></A
- >array_uintersect_assoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10407"
- ></A
- ><P
- > (PHP 5)</P
- >array_uintersect_assoc -- Computes the intersection of arrays with additional index check, compares data by a callback function</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10410"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_uintersect_assoc</B
- > ( array array1, array array2 [, array ..., callback data_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_uintersect_assoc()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments. Note that the keys are used in
- the comparison unlike in <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >.
- The data is compared by using a callback function.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10432"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_uintersect_assoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");
-
- print_r(array_uintersect_assoc($array1, $array2, "strcasecmp"));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [a] => green
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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.
- </P
- ><P
- >
See also <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-uintersect-uassoc"
- ></A
- >array_uintersect_uassoc</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10445"
- ></A
- ><P
- > (PHP 5)</P
- >array_uintersect_uassoc -- Computes the intersection of arrays with additional index check, compares data and indexes by a callback functions</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10448"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_uintersect_uassoc</B
- > ( array array1, array array2 [, array ..., callback data_compare_func, callback key_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_uintersect_uassoc()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments. Note that the keys are used in
- the comparison unlike in <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >.
- Both the data and the indexes are compared by using a callback functions.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10473"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_uintersect_uassoc()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");
-
- print_r(array_uintersect_uassoc($array1, $array2, "strcasecmp", "strcasecmp"));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [a] => green
- [b] => brown
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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.
- </P
- ><P
- >
See also <A
- HREF="#function.array-uintersect"
- ><B
- CLASS="function"
- >array_uintersect()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-assoc"
- ><B
- CLASS="function"
- >array_intersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-uintersect"
- ></A
- >array_uintersect</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10486"
- ></A
- ><P
- > (PHP 5)</P
- >array_uintersect -- Computes the intersection of arrays, compares data by a callback function</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10489"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_uintersect</B
- > ( array array1, array array2 [, array ..., callback data_compare_func])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_uintersect()</B
- > returns an array
- containing all the values of <VAR
- CLASS="parameter"
- >array1</VAR
- >
- that are present in all the arguments.
- The data is compared by using a callback function.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10510"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_uintersect()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
- $array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");
-
- print_r(array_uintersect($array1, $array2, "strcasecmp"));
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="screen"
- >Array
- (
- [a] => green
- [b] => brown
- [0] => red
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
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.
- </P
- ><P
- >
See also <A
- HREF="#function.array-intersect"
- ><B
- CLASS="function"
- >array_intersect()</B
- ></A
- >,
- <A
- HREF="#function.array-uintersect-assoc"
- ><B
- CLASS="function"
- >array_uintersect_assoc()</B
- ></A
- >,
- <A
- HREF="#function.array-intersect-uassoc"
- ><B
- CLASS="function"
- >array_intersect_uassoc()</B
- ></A
- > and
- <A
- HREF="#function.array-uintersect-uassoc"
- ><B
- CLASS="function"
- >array_uintersect_uassoc()</B
- ></A
- >.
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-unique"
- ></A
- >array_unique</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10523"
- ></A
- ><P
- > (PHP 4 >= 4.0.1, PHP 5)</P
- >array_unique -- Removes duplicate values from an array</DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10526"
- ></A
- ><H2
- >Description</H2
- >array <B
- CLASS="methodname"
- >array_unique</B
- > ( array array)<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_unique()</B
- > takes input
- <VAR
- CLASS="parameter"
- >array</VAR
- > and returns a new array
- without duplicate values.
- </P
- ><P
- >
Note that keys are preserved. <B
- CLASS="function"
- >array_unique()</B
- > sorts
- the values treated as string at first, then will keep the first key
- encountered for every value, and ignore all following keys. It does not
- mean that the key of the first related value from the unsorted
- <VAR
- CLASS="parameter"
- >array</VAR
- > will be kept.
- </P
- ><DIV
- CLASS="note"
- ><BLOCKQUOTE
- CLASS="note"
- ><P
- ><B
- >Note: </B
- >
- Two elements are considered equal if and only if
- <VAR
- CLASS="literal"
- >(string) $elem1 === (string) $elem2</VAR
- >. In words:
- when the string representation is the same.
- </P
- ><P
- >
The first element will be used.
- </P
- ></BLOCKQUOTE
- ></DIV
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10545"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_unique()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array("a" => "green", "red", "b" => "green", "blue", "red");
- $result = array_unique($input);
- print_r($result);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [a] => green
- [0] => red
- [1] => blue
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10552"
- ></A
- ><P
- ><B
- >Example 2. <B
- CLASS="function"
- >array_unique()</B
- > and types</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $input = array(4, "4", "3", 4, 3, "3");
- $result = array_unique($input);
- var_dump($result);
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >The above example will output:</P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >array(2) {
- [0] => int(4)
- [2] => string(1) "3"
- }</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ></DIV
- ><H1
- ><A
- NAME="function.array-unshift"
- ></A
- >array_unshift</H1
- ><DIV
- CLASS="refnamediv"
- ><A
- NAME="AEN10559"
- ></A
- ><P
- > (PHP 4 , PHP 5)</P
- >array_unshift --
- Prepend one or more elements to the beginning of an array
- </DIV
- ><DIV
- CLASS="refsect1"
- ><A
- NAME="AEN10562"
- ></A
- ><H2
- >Description</H2
- >int <B
- CLASS="methodname"
- >array_unshift</B
- > ( array &array, mixed var [, mixed ...])<BR
- ></BR
- ><P
- >
<B
- CLASS="function"
- >array_unshift()</B
- > prepends passed elements to
- the front of the <VAR
- CLASS="parameter"
- >array</VAR
- >. Note that the list
- of elements is prepended as a whole, so that the prepended
- elements stay in the same order. All numerical array keys will be
- modified to start counting from zero while literal keys won't be touched.
- </P
- ><P
- >
Returns the new number of elements in the
- <VAR
- CLASS="parameter"
- >array</VAR
- >.
- </P
- ><P
- >
<TABLE
- WIDTH="100%"
- BORDER="0"
- CELLPADDING="0"
- CELLSPACING="0"
- CLASS="EXAMPLE"
- ><TR
- ><TD
- ><DIV
- CLASS="example"
- ><A
- NAME="AEN10582"
- ></A
- ><P
- ><B
- >Example 1. <B
- CLASS="function"
- >array_unshift()</B
- > example</B
- ></P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- ><?php
- $queue = array("orange", "banana");
- array_unshift($queue, "apple", "raspberry");
- ?></PRE
- ></TD
- ></TR
- ></TABLE
- ><P
- >
This would result in <VAR
- CLASS="varname"
- >$queue</VAR
- > having the
- following elements:
- </P
- ><TABLE
- BORDER="0"
- BGCOLOR="#E0E0E0"
- CELLPADDING="5"
- ><TR
- ><TD
- ><PRE
- CLASS="php"
- >Array
- (
- [0] => apple
- [1] => raspberry
- [2] => orange
- [3] => banana
- )</PRE
- ></TD
- ></TR
- ></TABLE
- ></DIV
- ></TD
- ></TR
- ></TABLE
- >
- </P
- ><P
- >
See also <A
- HREF="#function.array-shift"
- ><B
- CLASS="function"
- >array_shift()</B
- ></A
- >,
- <A
- HREF="#function.array