mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-11 19:20:50 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1002acbac0 |
No files matched your search
@@ -165,7 +165,7 @@ define ____print_const_table
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
printf "\"%s\" => ", $p->key.u.string
|
||||
printf "\"%s\" => ", $p->arKey
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
@@ -196,7 +196,7 @@ define ____print_ht
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
printf "\"%s\" => ", (char*)$p->key.u.string
|
||||
printf "\"%s\" => ", $p->arKey
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
@@ -217,41 +217,6 @@ document print_ht
|
||||
dumps elements of HashTable made of zval
|
||||
end
|
||||
|
||||
define ____print_ft
|
||||
set $ht = $arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $func = (zend_function*)$p->pData
|
||||
|
||||
set $i = $ind
|
||||
while $i > 0
|
||||
printf " "
|
||||
set $i = $i - 1
|
||||
end
|
||||
|
||||
if $p->nKeyLength > 0
|
||||
printf "\"%s\" => ", (char*)$p->key.u.string
|
||||
else
|
||||
printf "%d => ", $p->h
|
||||
end
|
||||
|
||||
printf "\"%s\"\n", $func->common.function_name
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_ft
|
||||
set $ind = 1
|
||||
printf "[0x%08x] {\n", $arg0
|
||||
____print_ft $arg0
|
||||
printf "}\n"
|
||||
end
|
||||
|
||||
document print_ft
|
||||
dumps a function table (HashTable)
|
||||
end
|
||||
|
||||
define printzn
|
||||
____executor_globals
|
||||
set $ind = 0
|
||||
@@ -308,18 +273,6 @@ document printzops
|
||||
dump operands of the current opline
|
||||
end
|
||||
|
||||
define zbacktrace
|
||||
____executor_globals
|
||||
dump_bt $eg.current_execute_data
|
||||
end
|
||||
|
||||
document zbacktrace
|
||||
prints backtrace.
|
||||
This command is almost a short cut for
|
||||
> (gdb) ____executor_globals
|
||||
> (gdb) dump_bt $eg.current_execute_data
|
||||
end
|
||||
|
||||
define zmemcheck
|
||||
set $p = alloc_globals.head
|
||||
set $stat = "?"
|
||||
@@ -392,3 +345,4 @@ document zmemcheck
|
||||
usage: zmemcheck [ptr].
|
||||
if ptr is 0, all blocks will be listed.
|
||||
end
|
||||
|
||||
+8
-17
@@ -148,19 +148,20 @@ Naming Conventions
|
||||
'buildsomewidget'
|
||||
'getI()'
|
||||
|
||||
[7] Classes should be given descriptive names. Avoid using abbreviations where
|
||||
possible. Each word in the class name should start with a capital letter,
|
||||
without underscore delimiters (CampelCaps starting with a capital letter).
|
||||
The class name should be prefixed with the name of the 'parent set' (e.g.
|
||||
the name of the extension).
|
||||
[7] Classes should be given descriptive names. Avoid using abbreviations
|
||||
where possible. Each word in the class name should start with a capital
|
||||
letter, with words underscore delimited. The class name should be prefixed
|
||||
with the name of the 'parent set'.
|
||||
|
||||
Good:
|
||||
'Curl'
|
||||
'FooBar'
|
||||
'Foo_Bar'
|
||||
|
||||
Bad:
|
||||
'foobar'
|
||||
'foo_bar'
|
||||
'FooBar'
|
||||
|
||||
|
||||
Syntax and indentation
|
||||
----------------------
|
||||
@@ -182,7 +183,7 @@ Syntax and indentation
|
||||
indentation and comment styles and up to function declaration
|
||||
syntax.
|
||||
|
||||
(see also http://www.catb.org/~esr/jargon/html/I/indent-style.html)
|
||||
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
|
||||
|
||||
[3] Be generous with whitespace and braces. Always prefer:
|
||||
|
||||
@@ -203,16 +204,6 @@ Syntax and indentation
|
||||
four spaces. It is important to maintain consistency in indenture so
|
||||
that definitions, comments, and control structures line up correctly.
|
||||
|
||||
[5] Preprocessor statements (#if and such) MUST start at column one. To
|
||||
indent preprocessor directives you should put the # at the beginning
|
||||
of a line, followed by any number of whitespace.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
[1] Extensions should be well tested using *.phpt tests. Read about that
|
||||
in README.TESTING.
|
||||
|
||||
Documentation and Folding Hooks
|
||||
-------------------------------
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+153
-153
@@ -31,29 +31,21 @@ EXTENSION: aolserver
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: activescript
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache_hooks
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2filter
|
||||
EXTENSION: apache2
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2handler
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: caudium
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cgi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
@@ -61,31 +53,15 @@ STATUS: Working
|
||||
EXTENSION: cli
|
||||
MAINTENANCE: Marcus Boerger <helly@php.net>, Edin Kadribasic <edink@php.net>
|
||||
STATUS: Working
|
||||
SINCE: 4.3.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: continuity
|
||||
PRIMARY MAINTAINER: Alex Leigh <aleigh@php.net>
|
||||
EXTENSION: fhttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: date
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: embed
|
||||
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: isapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: milter
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: nsapi
|
||||
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -103,12 +79,12 @@ EXTENSION: roxen
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: thttpd
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Odd fixes
|
||||
EXTENSION: servlet
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tux
|
||||
EXTENSION: thttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -129,7 +105,8 @@ STATUS: Working
|
||||
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dbase
|
||||
MAINTENANCE: Orphaned
|
||||
PRIMARY MAINTAINER: Jim Winstead <jimw@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dbx
|
||||
@@ -139,11 +116,15 @@ STATUS: Working
|
||||
SINCE: 4.0.6
|
||||
COMMENT: DB abstraction for odbc, mysql, pgsql, mssql, fbsql and more, see documentation
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fbsql
|
||||
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
|
||||
EXTENSION: filepro
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: hyperwave
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: informix
|
||||
PRIMARY MAINTAINER: Danny Heijl <Danny.Heijl@cevi.be>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -156,14 +137,20 @@ STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: interbase
|
||||
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu>, Jouni Ahto <jouni.ahto@exdec.fi>
|
||||
MAINTENANCE: Maintained
|
||||
PRIMARY MAINTAINER: Jouni Ahto <jouni.ahto@exdec.fi>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msql
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msession
|
||||
PRIMARY MAINTAINER Mark L. Woodward mlwmohawk@mohawksoft.com
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working/Experimental
|
||||
COMMENT: Tested on Linux, should work on other UNIX platforms. Backend server code can compile under Windows.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mssql
|
||||
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -179,27 +166,6 @@ EXTENSION: mysqli
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oracle
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
COMMENT: Using the new OCI8 driver is encouraged where possible.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ovrimos
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pgsql
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Yasuo Ohgaki <yohgaki@php.net>
|
||||
@@ -211,8 +177,6 @@ EXTENSION: sqlite
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0 (Since 4.3.2 in PECL)
|
||||
COMMENT: Integrates SQLite embeddable SQL database engine.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sybase
|
||||
MAINTENANCE: Unknown
|
||||
@@ -222,6 +186,23 @@ EXTENSION: sybase_ct
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oracle
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Using the new OCI8 driver is encouraged where possible.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== XML extensions ==
|
||||
@@ -230,18 +211,11 @@ STATUS: Working
|
||||
EXTENSION: dom
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>, Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: simplexml
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: soap
|
||||
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: wddx
|
||||
@@ -262,13 +236,17 @@ STATUS: Experimental
|
||||
EXTENSION: xsl
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== Other extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: aspell
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
COMMENT: For aspell .27 and greater, check out the pspell extension
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bcmath
|
||||
MAINTENANCE: Unknown
|
||||
@@ -280,53 +258,70 @@ MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dio
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
SINCE: 4.0.6
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cyrus
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
SINCE: 4.0.6
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: calendar
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: com_dotnet
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
EXTENSION: com
|
||||
PRIMARY MAINTAINER: Harald Radi <h.radi@nme.at>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Windows
|
||||
SINCE: 5.0
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cpdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: crack
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ctype
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: curl
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>,Ilia Alshanetsky <iliaa@php.net>
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cybercash
|
||||
PRIMARY MAINTAINER: Evan Klinger <evan715@sirius.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dotnet
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: exif
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fam
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: filepro
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ftp
|
||||
PRIMARY MAINTAINER: Stefan Esser (sesser@php.net)
|
||||
MAINTENANCE: Maintained
|
||||
@@ -346,10 +341,9 @@ MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: hwapi
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
EXTENSION: icap
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
STATUS: Obsolete
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: iconv
|
||||
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
|
||||
@@ -357,14 +351,14 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: imap
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ircg
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
EXTENSION: java
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>
|
||||
@@ -376,52 +370,27 @@ PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcrypt
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
|
||||
MAINTENANCE: Maintained
|
||||
EXTENSION: mcal
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcve
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
EXTENSION: mcrypt
|
||||
PRIMARY MAINTAINER: Derick Rethans <d.rethans@jdimedia.nl>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mhash
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mime_magic
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Deprecated
|
||||
STATUS: Experimental
|
||||
COMMENT: Use PECL's fileinfo extension instead
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ming
|
||||
PRIMARY MAINTAINER: Frank M. Kromann
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mnogosearch
|
||||
PRIMARY MAINTAINER: Sergey Kartashoff <gluke@mail.ru>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mono
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msession
|
||||
PRIMARY MAINTAINER Mark L. Woodward <mlwmohawk@mohawksoft.com>
|
||||
EXTENSION: muscat
|
||||
PRIMARY MAINTAINER: Sam Liddicott <sam@ananova.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working/Experimental
|
||||
COMMENT: Tested on Linux, should work on other UNIX platforms. Backend server code can compile under Windows.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ncurses
|
||||
PRIMARY MAINTAINER Ilia Alshanetsky <iliaa@php.net>, Wez Furlong <wez@php.net>, Hartmut Holzgraefe <hholzgra@php.net>, Georg Richter <georg@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
STATUS: Working
|
||||
SINCE: 4.0.5
|
||||
COMMENT: Not tested against windows, only core API completed, rest under development
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
@@ -429,8 +398,9 @@ MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcntl
|
||||
MAINTENANCE: Unknown
|
||||
EXTENSION: overload
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcre
|
||||
@@ -438,6 +408,11 @@ PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pfpro
|
||||
PRIMARY MAINTAINER: David Croft <david@infotrek.co.uk>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -449,12 +424,24 @@ PRIMARY MAINTAINER: Kristian K
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: printer
|
||||
PRIMARY MAINTAINER: Daniel Beulshausen <daniel@php4win.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
COMMENT: Only for Win32
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pspell
|
||||
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: qtdom
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: readline
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
@@ -464,8 +451,20 @@ PRIMARY MAINTAINER: Kristian K
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sablot
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Obsolete
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: satellite
|
||||
PRIMARY MAINTAINER: David Eriksson <eriksson@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: session
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>, Ilia Alshanetsky <iliaa@php.net>
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -486,15 +485,11 @@ MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: spl
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvmsg
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
EXTENSION: swf
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Deprecated (Use the ming swf extension instead)
|
||||
COMMENT: Only for Unix (won't change)
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvsem
|
||||
MAINTENANCE: Unknown
|
||||
@@ -504,15 +499,10 @@ EXTENSION: sysvshm
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tidy
|
||||
PRIMARY MAINTAINER: John Coggeshall <john@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tokenizer
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
EXTENSION: vpopmail
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: yaz
|
||||
PRIMARY MAINTAINER: Adam Dickmeiss <adam@indexdata.dk>
|
||||
@@ -520,8 +510,18 @@ MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: yp
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zlib
|
||||
PRIMARY MAINTAINER: Stefan Roehrich <sr@linux.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zziplib
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2006 The PHP Group. All rights reserved.
|
||||
The PHP License, Version 3.0
|
||||
Copyright (c) 1999 - 2003 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -38,8 +38,8 @@ are met:
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
"This product includes PHP, freely available from
|
||||
<http://www.php.net/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
@@ -64,5 +64,5 @@ The PHP Group can be contacted via Email at group@php.net.
|
||||
For more information on the PHP Group and the PHP project,
|
||||
please see <http://www.php.net>.
|
||||
|
||||
PHP includes the Zend Engine, freely available at
|
||||
This product includes the Zend Engine, freely available at
|
||||
<http://www.zend.com>.
|
||||
+4
-4
@@ -7,17 +7,17 @@ $(builddir)/zend_language_scanner.lo: $(builddir)/zend_language_parser.h
|
||||
$(builddir)/zend_ini_scanner.lo: $(builddir)/zend_ini_parser.h
|
||||
|
||||
$(builddir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
|
||||
@$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
|
||||
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
|
||||
|
||||
$(builddir)/zend_language_parser.h: $(builddir)/zend_language_parser.c
|
||||
$(builddir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
@$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
|
||||
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
|
||||
|
||||
$(builddir)/zend_ini_parser.h: $(builddir)/zend_ini_parser.c
|
||||
$(builddir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
@$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
|
||||
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
|
||||
|
||||
$(builddir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
@$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
|
||||
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
|
||||
|
||||
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(builddir)/zend_language_parser.h
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
#
|
||||
# LCOV
|
||||
#
|
||||
|
||||
lcov: lcov-html
|
||||
|
||||
lcov-test: all
|
||||
@echo "Running test suite"
|
||||
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
|
||||
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
|
||||
NO_INTERACTION=1 \
|
||||
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(PHP_EXECUTABLE) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -d 'extension_dir=modules/' -d `( . $(PHP_MODULES) ; echo extension=$$dlname)` tests/; \
|
||||
elif test ! -z "$(SAPI_CLI_PATH)" && test -x "$(SAPI_CLI_PATH)"; then \
|
||||
NO_INTERACTION=1 \
|
||||
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php $(TESTS); \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
|
||||
php_lcov.info: lcov-test
|
||||
@echo "Generating data for $@"
|
||||
@rm -rf lcov_data/
|
||||
@$(mkinstalldirs) lcov_data/
|
||||
@echo
|
||||
-@find . -name \*.gcda -o -name \*.gcno -o -name \*.da | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | uniq | while read x; do \
|
||||
echo -n . ;\
|
||||
y=`echo $$x | sed -e 's!\.libs/!!'`; \
|
||||
dir=lcov_data/`dirname $$x`; \
|
||||
test -d "$$dir" || $(mkinstalldirs) "$$dir"; \
|
||||
if test -f "$(top_srcdir)/$$y.c"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.c lcov_data/$$y.c; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.re"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.re lcov_data/$$y.re; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.y"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.y lcov_data/$$y.y; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$y.l"; then \
|
||||
ln -f -s $(top_srcdir)/$$y.l lcov_data/$$y.l; \
|
||||
fi; \
|
||||
if test -f "$(top_builddir)/$$y.c"; then \
|
||||
ln -f -s $(top_builddir)/$$y.c lcov_data/$$y.c; \
|
||||
fi; \
|
||||
test -f "$$x.gcno" && cp $$x.gcno lcov_data/$$y.gcno ; \
|
||||
test -f "$$x.gcda" && cp $$x.gcda lcov_data/$$y.gcda ; \
|
||||
test -f "$$x.da" && cp $$x.da lcov_data/$$y.da ; \
|
||||
test -f "$$x.bb" && cp $$x.bb lcov_data/$$y.bb ; \
|
||||
test -f "$$x.bbg" && cp $$x.bbg lcov_data/$$y.bbg ; \
|
||||
done
|
||||
@echo
|
||||
@echo "Generating $@"
|
||||
@$(LTP) --directory lcov_data/ --capture --base-directory=lcov_data --output-file $@
|
||||
|
||||
lcov-html: php_lcov.info
|
||||
@echo "Generating lcov HTML"
|
||||
@$(LTP_GENHTML) --legend --no-prefix --output-directory lcov_html/ --title "PHP Code Coverage" --show-details php_lcov.info
|
||||
|
||||
lcov-clean:
|
||||
rm -f php_lcov.info
|
||||
rm -rf lcov_data/
|
||||
rm -rf lcov_html/
|
||||
|
||||
+13
-56
@@ -5,6 +5,7 @@ INSTALL_DATA = $(INSTALL) -m 644
|
||||
DEFS = -DPHP_ATOM_INC -I$(top_builddir)/include -I$(top_builddir)/main -I$(top_srcdir)
|
||||
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
|
||||
|
||||
|
||||
all: $(all_targets)
|
||||
@echo
|
||||
@echo "Build complete."
|
||||
@@ -37,73 +38,29 @@ install-sapi: $(OVERALL_TARGET)
|
||||
|
||||
install-modules: build-modules
|
||||
@test -d modules && \
|
||||
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
|
||||
@echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/"
|
||||
@rm -f modules/*.la >/dev/null 2>&1
|
||||
@$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR)
|
||||
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR) && \
|
||||
echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/" && \
|
||||
rm -f modules/*.la && \
|
||||
$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR) >/dev/null 2>&1 || true
|
||||
|
||||
install-headers:
|
||||
-@if test "$(INSTALL_HEADERS)"; then \
|
||||
for i in $(INSTALL_HEADERS); do \
|
||||
i=`$(top_srcdir)/build/shtool path -d $$i`; \
|
||||
paths="$$paths $(INSTALL_ROOT)$(phpincludedir)/$$i"; \
|
||||
done; \
|
||||
$(mkinstalldirs) $$paths && \
|
||||
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
|
||||
for i in $(INSTALL_HEADERS); do \
|
||||
if test "$(PHP_PECL_EXTENSION)"; then \
|
||||
src=`echo $$i | $(SED) -e "s#ext/$(PHP_PECL_EXTENSION)/##g"`; \
|
||||
else \
|
||||
src=$$i; \
|
||||
fi; \
|
||||
if test -f "$(top_srcdir)/$$src"; then \
|
||||
$(INSTALL_DATA) $(top_srcdir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
elif test -f "$(top_builddir)/$$src"; then \
|
||||
$(INSTALL_DATA) $(top_builddir)/$$src $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
else \
|
||||
(cd $(top_srcdir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i; \
|
||||
cd $(top_builddir)/$$src && $(INSTALL_DATA) *.h $(INSTALL_ROOT)$(phpincludedir)/$$i) 2>/dev/null || true; \
|
||||
fi \
|
||||
done; \
|
||||
fi
|
||||
install-tester:
|
||||
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
|
||||
@$(mkinstalldirs) $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
|
||||
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
|
||||
|
||||
test: all
|
||||
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
|
||||
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(PHP_EXECUTABLE) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -d 'extension_dir=modules/' -d `( . $(PHP_MODULES) ; echo extension=$$dlname)` tests/; \
|
||||
elif test ! -z "$(SAPI_CLI_PATH)" && test -x "$(SAPI_CLI_PATH)"; then \
|
||||
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -U $(TESTS); \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
install-su: install-pear install-tester
|
||||
|
||||
utest: all
|
||||
test:
|
||||
-@if test -x $(SAPI_CLI_PATH) && test ! -z $(SAPI_CLI_PATH); then \
|
||||
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -u $(TESTS); \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
|
||||
ntest: all
|
||||
-@if test -x $(SAPI_CLI_PATH) && test ! -z $(SAPI_CLI_PATH); then \
|
||||
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
|
||||
TEST_PHP_SRCDIR=$(top_srcdir) \
|
||||
CC="$(CC)" \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -N $(TESTS); \
|
||||
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' $(top_srcdir)/run-tests.php $(TESTS); \
|
||||
else \
|
||||
echo "ERROR: Cannot run tests without CLI sapi."; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
|
||||
find . -name \*.lo -o -name \*.o | xargs rm -f
|
||||
find . -name \*.la -o -name \*.a | xargs rm -f
|
||||
find . -name \*.so | xargs rm -f
|
||||
@@ -112,7 +69,7 @@ clean:
|
||||
|
||||
distclean: clean
|
||||
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php5.spec sapi/apache/libphp5.module buildmk.stamp
|
||||
$(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f
|
||||
egrep define'.*include/php' configure|sed 's/.*>//'|xargs rm -f
|
||||
find . -name Makefile | xargs rm -f
|
||||
|
||||
.PHONY: all clean install distclean test
|
||||
|
||||
@@ -1,29 +1,134 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 6.0
|
||||
- Unicode support. (Andrei, Dmitry, et al)
|
||||
- Cleaned CGI code. Now FastCGI can not be disabled. See sapi/cgi/CHANGES
|
||||
for more details. (Dmitry)
|
||||
- Removed support for "continue" and "break" operators with non-constant
|
||||
operands. (Dmitry)
|
||||
- Changed __toString() behavior to call it in all necessary places
|
||||
(Marcus, Dmitry)
|
||||
- Changed "instanceof" and "catch" operators, is_a() and is_subclass_of()
|
||||
functions to not call __autoload(). (Dmitry)
|
||||
- Removed global reflection constants. (Johannes)
|
||||
- Added "allow_url_include" ini directive to be able to turn off remote url
|
||||
code execution separately from the "allow_url_fopen" setting. (Rasmus)
|
||||
- Added to cURL extension: (Ilia)
|
||||
. curl_setopt_array() which allows setting of multiple cURL options.
|
||||
. CURLINFO_HEADER_OUT constant to facilitate request retrieval.
|
||||
- Added --rclass and --rextension CLI parameters to reflect internal classes
|
||||
and loaded extensions. (Johannes)
|
||||
- Added optional parameter to http_build_query() to allow specification of
|
||||
string separator. (Ilia)
|
||||
- Added an optional parameter to parse_url() to allow retrieval of distinct URL
|
||||
components. (Ilia)
|
||||
- Added an optional parameter to strstr() and stristr() for retrieval of either
|
||||
the part of haystack before or after first occurence of needle. (Johannes)
|
||||
- Added possibility to check in which extension an internal function was
|
||||
defined using reflection API. (Johannes)
|
||||
- Fixed bug #34286 (__toString() behavior is inconsistent). (Marcus)
|
||||
?? ??? 200?, Version 5.0.0
|
||||
|
||||
?? ??? 2003, PHP 5 Beta 2
|
||||
- Added misc. new functions:
|
||||
. pg_version(). (Marcus)
|
||||
. dbase_get_header_info(). (Zak)
|
||||
. snmp_read_mib(). (Jani)
|
||||
- Added optional parameter to OCIWriteTemporaryLob() to specify the type of LOB
|
||||
(Patch by Novicky Marek <novicky@aarongroup.cz>). (Thies)
|
||||
- Added SQLite support to DBX. (Marc)
|
||||
- Added reflection API. (Andrei, George, Timm)
|
||||
- Fixed support for <![CDATA[]]> fields within XML documents in ext/xml.
|
||||
(Sterling)
|
||||
- Fixed visibility of __construct and __clone. (Marcus)
|
||||
- Fixed bug #24729 ($obj = new $className; causes crash when $className is not
|
||||
set). (Marcus)
|
||||
- Fixed bug #24565 (cannot read array elements recived via $_REQUEST). (Zeev)
|
||||
- Fixed bug #24445 (get_parent_class() returns different values).
|
||||
(Sterling, Stanislav)
|
||||
- Fixed bug #24403 (preg_replace() problem: Using $this when not in object
|
||||
context). (Zeev)
|
||||
- Fixed bug #24399 (PEAR DB isError crash [instanceof_function fault?]).
|
||||
(Sterling, Marcus)
|
||||
- Fixed bug #24396 (foreach ($k=>$v), the key $k is missing). (Zeev)
|
||||
- Fixed bug #24279 (__get() crash when no value is returned). (Ilia)
|
||||
- Fixed bug #22367 (undefined variable has a value). (Zeev)
|
||||
- Fixed bug #19859 (allow fast_call_user_function to support __call).
|
||||
(Stanislav)
|
||||
|
||||
29 Jun 2003, PHP 5 Beta 1
|
||||
- Removed the bundled MySQL client library. (Sterling)
|
||||
- Switched to Zend Engine 2, which includes numerous engine level improvements.
|
||||
A full list is available at http://www.php.net/zend-engine-2.php.
|
||||
- Added SQLite (http://www.hwaci.com/sw/sqlite/) extension: (Wez, Marcus, Tal)
|
||||
. Includes bundled SQLite library
|
||||
. Enabled by default
|
||||
- Completely Overhauled XML support:
|
||||
. New simplexml extension. (Sterling)
|
||||
. New DOM extension. (Rob, Chregu, Marcus)
|
||||
. New XSL extension. (Chregu, Rob)
|
||||
. Moved the old DOM-XML and XSLT extensions to PECL. (James, Sterling)
|
||||
. ext/xml can now use either libxml2 or expat to parse XML. (Sterling)
|
||||
. Removed bundled expat library. (Jani)
|
||||
- New php.ini options:
|
||||
. "session.hash_function" and "session.hash_bits_per_character". (Sascha)
|
||||
. "mail.force_extra_paramaters". (Derick)
|
||||
. "register_long_arrays". (Zeev)
|
||||
- Improved the speed of internal functions that use callbacks by 40% due to a
|
||||
new internal fast_call_user_function() function. (Sterling)
|
||||
- Improved the streams support: (Wez)
|
||||
. Improved performance of readfile(), fpassthru() and some internal streams
|
||||
operations under Win32.
|
||||
. stream_socket_client() - similar to fsockopen(), but more powerful.
|
||||
. stream_socket_server() - Creates a server socket.
|
||||
. stream_socket_accept() - Accept a client connection.
|
||||
. stream_socket_get_name() - Get local or remote name of socket.
|
||||
. stream_copy_to_stream()
|
||||
. stream_get_line() - Reads either the specified number of bytes or until
|
||||
the ending string is found. (Ilia)
|
||||
. Added context property to userspace streams object. (Sara)
|
||||
. Added generic crypto interface for streams.
|
||||
(supports dynamic loading of OpenSSL)
|
||||
. Added lightweight streaming input abstraction to the Zend Engine scanners
|
||||
to provide uniform support for include()'ing data from PHP streams across
|
||||
all platforms.
|
||||
. Added 'string.base64' stream filter. (Moriyoshi)
|
||||
. Renamed stream_register_wrapper() to stream_wrapper_register(). (Derick)
|
||||
- Improved the GD extension: (Pierre-Alain Joye, Ilia)
|
||||
. imagefilter() - Apply different filters to image.
|
||||
(Only available with bundled GD library)
|
||||
. Antialiased drawing support:
|
||||
o imageantialias() - (de)active antialias
|
||||
o imageline() and imagepolygon() antialias support
|
||||
- Changed the length parameter in fgetss() to be optional. (Moriyoshi)
|
||||
- Changed ini parser to allow for handling of quoted multi-line values. (Ilia)
|
||||
- Changed get_extension_funcs() to return list of the built-in Zend Engine
|
||||
functions if "zend" is specified as the module name. (Ilia)
|
||||
- Changed array_search() to accept also objects as a needle. (Moriyoshi)
|
||||
- Changed ext/mcrypt to require libmcrypt version 2.5.6 or greater. (Derick)
|
||||
- Changed uniqid() parameters to be optional and allow any prefix length.
|
||||
(Marcus)
|
||||
- Added new iconv functions. (Moriyoshi)
|
||||
. iconv_strlen()
|
||||
. iconv_substr()
|
||||
. iconv_strpos()
|
||||
. iconv_strrpos()
|
||||
. iconv_mime_decode()
|
||||
. iconv_mime_encode()
|
||||
- Added misc. new functions:
|
||||
. ldap_sasl_bind(). (peter_c60@hotmail.com, Jani)
|
||||
. imap_getacl(). (Dan, Holger Burbach)
|
||||
. file_put_contents(). (Sterling)
|
||||
. proc_nice() - Changes priority of the current process. (Ilia)
|
||||
. pcntl_getpriority() and pcntl_setpriority(). (Ilia)
|
||||
. idate(), date_sunrise() and date_sunset(). (Moshe Doron)
|
||||
. strpbrk() - Searches a string for a list of characters. (Ilia)
|
||||
. get_headers() - Returns headers sent by the server of the specified URL.
|
||||
(Ilia)
|
||||
. str_split() - Breaks down a string into an array of elements based on
|
||||
length. (Ilia)
|
||||
. array_walk_recursive(). (Ilia)
|
||||
. array_combine(). (Andrey)
|
||||
- Added optional parameter to get_browser() to make it return an array. (Jay)
|
||||
- Added optional parameter to openssl_sign() to specify the hashing algorithm.
|
||||
(scott@planetscott.ca, Derick)
|
||||
- Added optional parameter to sha1(), sha1_file(), md5() and md5_file() which
|
||||
makes them return the digest as binary data. (Michael Bretterklieber, Derick)
|
||||
- Added optional parameter to mkdir() to make directory creation recursive.
|
||||
(Ilia)
|
||||
- Added optional parameter to file() which makes the result array not contain
|
||||
the line endings and to skip empty lines. (Ilia)
|
||||
- Added new range() functionality:
|
||||
. Support for float modifier. (Ilia)
|
||||
. Detection of numeric values inside strings passed as high & low. (Ilia)
|
||||
. Proper handle the situations where high == low. (Ilia)
|
||||
. Added an optional step parameter. (Jon)
|
||||
- Added encoding detection feature for expat XML parser.
|
||||
(Adam Dickmeiss, Moriyoshi)
|
||||
- Added missing multibyte (unicode) support and numeric entity support to
|
||||
html_entity_decode(). (Moriyoshi)
|
||||
- Added IPv6 support to ext/sockets. (Sara)
|
||||
- Added "ftp://" wrapper support to opendir(), stat() and unlink(). (Sara)
|
||||
- Added context options 'method', 'header' and 'content' for "http://" fopen
|
||||
wrapper. (Sara)
|
||||
- Added input filter support. See README.input_filter for more info. (Rasmus)
|
||||
- Added a replace count for str_[i]replace(), see bug #8218. (Sara)
|
||||
- Fixed is_executable() to be available also on Windows. (Shane)
|
||||
- Fixed dirname() and strip_tags() to be binary-safe. (Moriyoshi)
|
||||
- Fixed bug #24098 (crash in pathinfo()). (Ilia)
|
||||
- Fixed bug #21985 and #22064 (various mb_send_mail() issues). (Moriyoshi)
|
||||
- Fixed bug #21600 (Assign by reference function call changes variable
|
||||
contents). (Zeev)
|
||||
+28
-31
@@ -29,17 +29,7 @@ Having said that, here are the organizational rules:
|
||||
5. If you don't know how to do something, ask first!
|
||||
|
||||
6. Test your changes before committing them. We mean it. Really.
|
||||
|
||||
7. For development use the --enable-maintainer-zts switch to ensure your
|
||||
code handles TSRM correctly and doesn't break for thos who need that.
|
||||
|
||||
Currently we have the following branches in use:
|
||||
HEAD Will become PHP 5.1. This CVS branch is for active development.
|
||||
PHP_5_0 Is used to release the PHP 5.0.x series. Only minor feature
|
||||
enhancements may go in here, but please keep that as infrequent as
|
||||
possible.
|
||||
PHP_4_3 Is used to release the PHP 4.3.x series. Only bugfixes are permitted
|
||||
on this branch.
|
||||
|
||||
|
||||
The next few rules are more of a technical nature.
|
||||
|
||||
@@ -47,11 +37,8 @@ The next few rules are more of a technical nature.
|
||||
messages every day. Woe be to those who attempt to mess with it.
|
||||
|
||||
2. All news updates intended for public viewing, such as new features,
|
||||
bug fixes, improvements, etc., should go into the NEWS file.
|
||||
|
||||
NB! Lines, starting with @ will go automagically into NEWS file, but
|
||||
this is NOT recommended, though. Please, add news entries directly to
|
||||
NEWS file and don't forget to keep them adjusted and sorted.
|
||||
bug fixes, improvements, etc., should go into the NEWS file. Also see
|
||||
the note below about automatically updating NEWS in your commit message.
|
||||
|
||||
3. Do not commit multiple file and dump all messages in one commit. If you
|
||||
modified several unrelated files, commit each group separately and
|
||||
@@ -71,29 +58,37 @@ The next few rules are more of a technical nature.
|
||||
|
||||
The format of the commit messages is pretty simple.
|
||||
|
||||
Use a - to start a new item in your commit message.
|
||||
|
||||
If a line begins with #, it is taken to be a comment and will not appear
|
||||
in the ChangeLog. Everything else goes into the ChangeLog.
|
||||
in the ChangeLog. If the line begins with @, it will be redirected to the
|
||||
NEWS file. Everything else goes into the ChangeLog.
|
||||
|
||||
It is important to note that if your comment or news logline spans multiple
|
||||
lines, you have to put # at the beginning of _every_ such line.
|
||||
lines, you have to put # or @ at the beginning of _every_ such line. Every
|
||||
entry in NEWS has to have a name after it, so if you did it with someone's
|
||||
help, put both your names there. Your name WILL NOT be automatically put
|
||||
at the end of the NEWS entry - so, please provide it yourself.
|
||||
|
||||
Example. Say you modified two files, datetime.c and string.c. In datetime.c you
|
||||
added a new format option for the date() function, and in string.c you fixed a
|
||||
memory leak in php_trim(). Don't commit both of these at once. Commit them
|
||||
Example. Say you modified two files, datetime.c and string.c. In datetime.c
|
||||
you added a new format option for date() function, and in string.c you fixed
|
||||
a memory leak in php_trim(). Don't commit both of these at once. Commit them
|
||||
separately and try to make sure your commit messages look something like the
|
||||
following.
|
||||
|
||||
For datetime.c:
|
||||
- Added new 'K' format modifier to date() for printing out number of days until
|
||||
New Year's Eve.
|
||||
|
||||
(PHP date) Added new 'K' format modifier for printing out number of
|
||||
days until New Year's Eve.
|
||||
@- Added new 'K' format modifier that will output the number of days
|
||||
@ until New Year's Eve. (Bob)
|
||||
|
||||
For string.c:
|
||||
- Fixed a memory leak in php_trim() resulting from improper use of zval_dtor().
|
||||
#- Man, that thing was leaking all over the place!
|
||||
(php_trim) Fixed a memory leak resulting from improper use of zval_dtor().
|
||||
# Man, that thing was leaking all over the place!
|
||||
@- Fixed memory leak in trim(). (Bob)
|
||||
|
||||
The # lines will be omitted from the ChangeLog automagically.
|
||||
The lines above marked with @ will go into NEWS file automagically, and the
|
||||
# lines will be omitted from the ChangeLog. Alternatively, you might want
|
||||
to modify NEWS file directly and not use the @ lines.
|
||||
|
||||
If you fix some bugs, you should note the bug ID numbers in your
|
||||
commit message. Bug ID should be prefixed by "#" for easier access to
|
||||
@@ -101,11 +96,13 @@ bug report when developers are browsing CVS via. LXR or Bonsai.
|
||||
|
||||
Example:
|
||||
|
||||
Fixed bug #14016 (pgsql notice handler double free crash bug.)
|
||||
Fixed pgsql notice handler double free crash bug. Bug #14016
|
||||
@ Fixed pgsql notice handler double free crash bug. Bug #14016
|
||||
|
||||
If you don't see your messages in ChangeLog right away, don't worry!
|
||||
If you don't see your messages in ChangeLog and NEWS right away, don't worry!
|
||||
These files are updated once a day, so your stuff will not show up until
|
||||
somewhat later.
|
||||
somewhat later. Don't go adding stuff to NEWS by hand if you already put @
|
||||
lines in the commit message.
|
||||
|
||||
You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
|
||||
to look at PHP CVS repository in various ways.
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
To install the PEAR installer, please use go-pear.
|
||||
|
||||
On linux:
|
||||
$ lynx -source http://go-pear.org/ | php
|
||||
|
||||
or save the setup script under go-pear.php and run:
|
||||
|
||||
php go-pear.php
|
||||
|
||||
For more informations see the PEAR manual:
|
||||
http://pear.php.net/manual/en/installation.getting.php
|
||||
@@ -1,155 +0,0 @@
|
||||
1. strrpos() and strripos() now use the entire string as a needle. Be aware
|
||||
that the existing scripts may no longer work as you expect.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
var_dump(strrpos("ABCDEF","DEF"));
|
||||
var_dump(strrpos("ABCDEF","DAF"));
|
||||
?>
|
||||
|
||||
Will give you different results. The former returns 3 while the latter
|
||||
returns false rather than the position of the last occurrence of 'D'.
|
||||
The same applies to strripos().
|
||||
|
||||
2. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
$a = "foo";
|
||||
unset($a[0][1][2]);
|
||||
?>
|
||||
|
||||
Fatal error: Cannot use string offset as an array in ... on line 1
|
||||
|
||||
3. array_merge() was changed to accept only arrays. If a non-array variable is
|
||||
passed, a E_WARNING will be thrown for every such parameter. Be careful
|
||||
because your code may start emitting E_WARNING out of the blue.
|
||||
|
||||
4. Be careful when porting from ext/mysql to ext/mysqli. The following
|
||||
functions return NULL when no more data is available in the result set
|
||||
(ext/mysql's functions return FALSE).
|
||||
|
||||
- mysqli_fetch_row()
|
||||
- mysqli_fetch_array()
|
||||
- mysqli_fetch_assoc()
|
||||
|
||||
5. PATH_TRANSLATED server variable is no longer set implicitly under
|
||||
Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
|
||||
same value as the SCRIPT_FILENAME server variable when it is not populated
|
||||
by Apache. This change was made to comply with the CGI specification.
|
||||
Please refer to bug #23610 for further information.
|
||||
|
||||
6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
|
||||
ext/tokenizer extension. If error_reporting is set to E_ALL notices will
|
||||
be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant
|
||||
is used, thus both // and /* */ are resolved as the T_COMMENT constant.
|
||||
However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
|
||||
by PHP, are recongnized as T_DOC_COMMENT.
|
||||
|
||||
7. $_SERVER should be populated with argc and argv if variables_order
|
||||
includes "S". If you have specifically configured your system to not
|
||||
create $_SERVER, then of course it shouldn't be there. The change was to
|
||||
always make argc and argv available in the CLI version regardless of the
|
||||
variables_order setting. As in, the CLI version will now always populate
|
||||
the global $argc and $argv variables.
|
||||
|
||||
8. In some cases classes must be declared before used. It only happens only
|
||||
if some of the new features of PHP 5 are used. Otherwise the behaviour is
|
||||
the old.
|
||||
Example 1 (works with no errors):
|
||||
<?php
|
||||
$a = new a();
|
||||
class a {
|
||||
}
|
||||
?>
|
||||
|
||||
Example 2 (throws an error):
|
||||
<?php
|
||||
$a = new a();
|
||||
interface b{
|
||||
}
|
||||
class a implements b {
|
||||
}
|
||||
?>
|
||||
|
||||
Output (example 2) :
|
||||
Fatal error: Class 'a' not found in /tmp/cl.php on line 2
|
||||
|
||||
9. get_class() starting PHP 5 returns the name of the class as it was
|
||||
declared which may lead to problems in older scripts that rely on
|
||||
the previous behaviour - the class name is lowercased. Expect the
|
||||
same behaviour from get_parent_class() when applicable.
|
||||
Example :
|
||||
<?php
|
||||
class FooBar {
|
||||
}
|
||||
class ExtFooBar extends FooBar{}
|
||||
$a = new FooBar();
|
||||
var_dump(get_class($a), get_parent_class($a));
|
||||
?>
|
||||
|
||||
Output (PHP 4):
|
||||
string(6) "foobar"
|
||||
string(9) "extfoobar"
|
||||
|
||||
Output (PHP 5):
|
||||
string(6) "FooBar"
|
||||
string(9) "ExtFooBar"
|
||||
----------------------------------------------------------------------
|
||||
Example code that will break :
|
||||
//....
|
||||
function someMethod($p) {
|
||||
if (get_class($p) != 'helpingclass') {
|
||||
return FALSE;
|
||||
}
|
||||
//...
|
||||
}
|
||||
//...
|
||||
Possible solution is to search for get_class() and get_parent_class() in
|
||||
all your scripts and use strtolower().
|
||||
|
||||
10. get_class_methods() returns the names of the methods of a class as they
|
||||
declared. In PHP4 the names are all lowercased.
|
||||
Example code :
|
||||
<?php
|
||||
class Foo{
|
||||
function doFoo(){}
|
||||
function hasFoo(){}
|
||||
}
|
||||
var_dump(get_class_methods("Foo"));
|
||||
?>
|
||||
Output (PHP4):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "dofoo"
|
||||
[1]=>
|
||||
string(6) "hasfoo"
|
||||
}
|
||||
Output (PHP5):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "doFoo"
|
||||
[1]=>
|
||||
string(6) "hasFoo"
|
||||
}
|
||||
|
||||
11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
|
||||
meaning in class methods and is recognized by the PHP parser. The latter
|
||||
will generate a parse error when assignment to $this is found
|
||||
Example code :
|
||||
<?php
|
||||
class Foo {
|
||||
function assignNew($obj) {
|
||||
$this = $obj;
|
||||
}
|
||||
}
|
||||
$a = new Foo();
|
||||
$b = new Foo();
|
||||
$a->assignNew($b);
|
||||
echo "I was executed\n";
|
||||
?>
|
||||
Output (PHP 4):
|
||||
I was executed
|
||||
Output (PHP 5):
|
||||
PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4
|
||||
|
||||
@@ -90,7 +90,7 @@ Please add the prefix "[PATCH]" to your email subject and make sure
|
||||
to include the patch as a MIME attachment even if it is short.
|
||||
|
||||
NOTE: only MIME attachments of type 'text/*' are accepted. The
|
||||
easiest way to accomplish this, is to make the extension
|
||||
easiest way to acclomplish this, is to make the extension
|
||||
'.txt'.
|
||||
|
||||
Test scripts should be included in the same email.
|
||||
@@ -100,7 +100,7 @@ Finally, add the bug Id(s) which can be closed by your patch, if any.
|
||||
|
||||
|
||||
What happens after you submit your patch
|
||||
----------------------------------------
|
||||
--------------------------------------
|
||||
If your patch is easy to review and has obviously no side-effects,
|
||||
it might take up to a few hours until someone commits it.
|
||||
|
||||
|
||||
+2
-11
@@ -1,20 +1,11 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
Failed tests usualy indicate a problem with your local system setup
|
||||
and not within PHP itself (at least for official PHP release versions).
|
||||
You may decide to automaticaly submit a test summary to our QA workflow
|
||||
at the end of a test run.
|
||||
Please do *not* submit a failed test as a bug or ask for help on why
|
||||
it failed on your system without providing substantial backup information
|
||||
on *why* the test failed on your special setup. Thank you :-)
|
||||
Please do not ask developers why some or all tests are failing in
|
||||
your environment! Let us know if you find why it fails. Thank you.
|
||||
|
||||
|
||||
[Testing Basics]
|
||||
----------------
|
||||
The easiest way to test your PHP build is to run "make test" from the
|
||||
command line after successfully compiling. This will run the complete
|
||||
tests for all enabled functionalities and extensions using the PHP
|
||||
CLI binary.
|
||||
To execute test scripts, you must build PHP with some SAPI, then you
|
||||
type "make test" to execute all or some test scripts saved under
|
||||
"tests" directory under source root directory.
|
||||
|
||||
-709
@@ -1,709 +0,0 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
As successful as PHP has proven to be in the past several years, it is still
|
||||
the only remaining member of the P-trinity of scripting languages - Perl and
|
||||
Python being the other two - that remains blithely ignorant of the
|
||||
multilingual and multinational environment around it. The software
|
||||
development community has been moving towards Unicode Standard for some time
|
||||
now, and PHP can no longer afford to be outside of this movement. Surely,
|
||||
some steps have been taken recently to allow for easier processing of
|
||||
multibyte data with the mbstring extension, but it is not enabled in PHP by
|
||||
default and is not as intuitive or transparent as it could be.
|
||||
|
||||
The basic goal of this document is to describe how PHP 6 will support the
|
||||
Unicode Standard natively. Since the full implementation of the Unicode
|
||||
Standard is very involved, the idea is to use the already existing,
|
||||
well-tested, full-featured, and freely available ICU (International
|
||||
Components for Unicode) library. This will allow us to concentrate on the
|
||||
details of PHP integration and speed up the implementation.
|
||||
|
||||
General Remarks
|
||||
===============
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
Throughout the design and implementation of Unicode support, backwards
|
||||
compatibility must be of paramount concern. PHP is used on an enormous number of
|
||||
sites and the upgrade to Unicode-enabled PHP has to be transparent. This means
|
||||
that the existing data types and functions must work as they have always
|
||||
done. However, the speed of certain operations may be affected, due to
|
||||
increased complexity of the code overall.
|
||||
|
||||
Unicode Encoding
|
||||
----------------
|
||||
The initial version will not support Byte Order Mark. Characters are
|
||||
expected to be composed, Normalization Form C. Later versions will support
|
||||
BOM, and decomposed and other characters.
|
||||
|
||||
|
||||
Implementation Approach
|
||||
=======================
|
||||
|
||||
The implementation is done in phases. This allows for more basic and
|
||||
low-level implementation issues to be ironed out and tested before
|
||||
proceeding to more advanced topics.
|
||||
|
||||
Legend:
|
||||
- TODO
|
||||
+ finished
|
||||
* in progress
|
||||
|
||||
Phase I
|
||||
-------
|
||||
+ Basic Unicode string support, including instantiation, concatenation,
|
||||
indexing
|
||||
|
||||
+ Simple output of Unicode strings via 'print' and 'echo' statements
|
||||
with appropriate output encoding conversion
|
||||
|
||||
+ Conversion of Unicode strings to/from various encodings via encode() and
|
||||
decode() functions
|
||||
|
||||
+ Determining length of Unicode strings via strlen() function, some
|
||||
simple string functions ported (substr).
|
||||
|
||||
|
||||
Phase II
|
||||
--------
|
||||
* HTTP input request decoding
|
||||
|
||||
+ Fixing remaining string-aware operators (assignment to {}, etc)
|
||||
|
||||
+ Comparison (collation) of Unicode strings with built-in operators
|
||||
|
||||
* Support for Unicode and binary strings in PHP streams
|
||||
|
||||
+ Support for Unicode identifiers
|
||||
|
||||
* Configurable handling of conversion failures
|
||||
|
||||
+ \C{} escape sequence in strings
|
||||
|
||||
|
||||
Phase III
|
||||
---------
|
||||
* Exposing ICU API
|
||||
|
||||
- Porting all remaining functions to support Unicode and/or binary
|
||||
strings
|
||||
|
||||
|
||||
Encoding Names
|
||||
==============
|
||||
All the encoding settings discussed in this document accept any valid
|
||||
encoding name supported by ICU. See ICU online documentation for the full
|
||||
list of encodings.
|
||||
|
||||
|
||||
Internal Encoding
|
||||
=================
|
||||
|
||||
UTF-16 is the internal encoding used for Unicode strings. UTF-16 consumes
|
||||
two bytes for any Unicode character in the Basic Multilingual Plane, which
|
||||
is where most of the current world's languages are represented. While being
|
||||
less memory efficient for basic ASCII text it simplifies the processing and
|
||||
makes interfacing with ICU easier, since ICU uses UTF-16 for its internal
|
||||
processing as well.
|
||||
|
||||
|
||||
Fallback Encoding
|
||||
=================
|
||||
|
||||
This setting specifies the "fallback" encoding for all the other ones. So if
|
||||
a specific encoding setting is not set, PHP defaults it to the fallback
|
||||
encoding. If the fallback_encoding is not specified either, it is set to
|
||||
UTF-8.
|
||||
|
||||
fallback_encoding = "iso-8859-1"
|
||||
|
||||
|
||||
Runtime Encoding
|
||||
================
|
||||
|
||||
Currently PHP neither specifies nor cares what the encoding of its strings
|
||||
is. However, the Unicode implementation needs to know what this encoding is
|
||||
for several reasons, including type coersion and encoding conversion for
|
||||
strings generated at runtime via function calls and casting. This setting
|
||||
specifies this runtime encoding.
|
||||
|
||||
runtime_encoding = "iso-8859-1"
|
||||
|
||||
|
||||
Output Encoding
|
||||
===============
|
||||
|
||||
Automatic output encoding conversion is supported on the standard output
|
||||
stream. Therefore, command such as 'print' and 'echo' automatically convert
|
||||
their arguments to the specified encoding. No automatic output encoding is
|
||||
performed for anything else. Therefore, when writing to files or external
|
||||
resources, the developer has to manually encode the data using functions
|
||||
provided by the unicode extension or rely on stream encoding filters. The
|
||||
unicode extension provides necessary stream filters to make developers'
|
||||
lives easier.
|
||||
|
||||
The existing default_charset setting so far has been used only for
|
||||
specifying the charset portion of the Content-Type MIME header. For several
|
||||
reasons, this setting is deprecated. Now it is only used when the Unicode
|
||||
semantics switch is disabled and does not affect the actual transcoding of
|
||||
the output stream. The output encoding setting takes precedence in all other
|
||||
cases.
|
||||
|
||||
output_encoding = "utf-8"
|
||||
|
||||
|
||||
HTTP Input Encoding
|
||||
===================
|
||||
|
||||
To make accessing HTTP input variables easier, PHP automatically decodes
|
||||
HTTP GET and POST requests based on the specified encoding. If the HTTP
|
||||
request contains the encoding specification in the headers, then it will be
|
||||
used instead of this setting. If the HTTP input encoding setting is not
|
||||
specified, PHP falls back onto the output encoding setting, because modern
|
||||
browsers are supposed to return the data in the same encoding as they
|
||||
received it in.
|
||||
|
||||
If the actual encoding is passed in the request itself or is found
|
||||
elsewhere, then the application can ask PHP to re-decode the raw input
|
||||
explicitly.
|
||||
|
||||
http_input_encoding = "utf-8"
|
||||
|
||||
|
||||
Script Encoding
|
||||
===============
|
||||
|
||||
PHP scripts may be written in any encoding supported by ICU. The encoding
|
||||
of the scripts can be specified site-wide via an INI directive
|
||||
script_encoding, or with a 'declare' pragma at the beginning of the script.
|
||||
The reason for pragma is that an application written in Shift-JIS, for
|
||||
example, should be executable on a system where the INI directive cannot be
|
||||
changed by the application itself. The pragma setting is valid only for the
|
||||
script it occurs in, and does not propagate to the included files.
|
||||
|
||||
pragma:
|
||||
<?php declare(encoding = 'utf-8'); ?>
|
||||
|
||||
INI setting:
|
||||
script_encoding = utf-8
|
||||
|
||||
|
||||
Conversion Semantics
|
||||
====================
|
||||
|
||||
Not all characters can be converted between Unicode and legacy encodings.
|
||||
Normally, when downconverting from Unicode, the default behavior of ICU
|
||||
converters is to substitute the missing sequence with the appropriate
|
||||
substitution sequence for that codepage, such as 0x1A (Control-Z) in
|
||||
ISO-8859-1. When upconverting to Unicode, if an encoding has a character
|
||||
which cannot be converted into Unicode, that sequence is replaced by the
|
||||
Unicode substitution character (U+FFFD).
|
||||
|
||||
The conversion failure behavior can be customized:
|
||||
|
||||
- perform substitution as described above with a custom substitution
|
||||
character
|
||||
- skip any invalid characters
|
||||
- stop the conversion, raise an error, and return partial conversion
|
||||
results
|
||||
- replace the missing character with a diagnostic character and continue,
|
||||
e.g. [U+hhhh]
|
||||
|
||||
There are two INI settings that control this.
|
||||
|
||||
unicode.from_error_mode = U_INVALID_SUBSTITUTE
|
||||
U_INVALID_SKIP
|
||||
U_INVALID_STOP
|
||||
U_INVALID_ESCAPE
|
||||
|
||||
unicode.from_error_subst_char = a2
|
||||
|
||||
The second setting is supposed to contain the Unicode code point value for
|
||||
the substitution character. This value has to be representable in the target
|
||||
encoding.
|
||||
|
||||
Note that PHP always tries to convert as much as of the data as possible and
|
||||
returns the converted results even if an error happens.
|
||||
|
||||
|
||||
Unicode Switch
|
||||
==============
|
||||
|
||||
Obviously, PHP cannot simply impose new Unicode support on everyone. There
|
||||
are many applications that do not care about Unicode and do not need it.
|
||||
Consequently, there is a switch that enables certain fundamental language
|
||||
changes related to Unicode. This switch is available as a site-wide, or
|
||||
per-dir INI setting only.
|
||||
|
||||
Note that having switch turned off does not imply that PHP is unaware of
|
||||
Unicode at all and that no Unicode string can exist. It only affects certain
|
||||
aspects of the language, and Unicode strings can always be created
|
||||
programmatically.
|
||||
|
||||
unicode_semantics = On
|
||||
|
||||
[TODO: list areas that are affected by this switch]
|
||||
|
||||
|
||||
Unicode String Type
|
||||
===================
|
||||
|
||||
Unicode string type (IS_UNICODE) is supposed to contain text data encoded in
|
||||
UTF-16 format. It is the main string type in PHP when Unicode semantics
|
||||
switch is turned on. Unicode strings can exist when the switch is off, but
|
||||
they have to be produced programmatically, via calls to functions that
|
||||
return Unicode type.
|
||||
|
||||
The operational unit when working with Unicode strings is a code point, not
|
||||
code unit or byte. One code point in UTF-16 may be comprised of 1 or 2 code
|
||||
units, each of which is a 16-bit word. Working on the code point level is
|
||||
necessary because doing otherwise would mean offloading the processing of
|
||||
surrogate pairs onto PHP users, and that is less than desirable.
|
||||
|
||||
The repercussions are that one cannot expect code point N to be at offset
|
||||
N in the Unicode string. Instead, one has to iterate from the beginning from
|
||||
the string using U16_FWD() macro until the desired codepoint is reached.
|
||||
|
||||
The codepoint access is one of the primary areas targeted for optimization.
|
||||
|
||||
|
||||
Native Encoding String Type
|
||||
===========================
|
||||
|
||||
Native encoding string type (IS_STRING) serves two purposes: backwards
|
||||
compatibility when Unicode semantics switch is off, and for representing
|
||||
strings in non-Unicode encodings (native encodings) when it is on. It is
|
||||
processsed on the byte level.
|
||||
|
||||
|
||||
Binary String Type
|
||||
==================
|
||||
|
||||
Binary string type (IS_BINARY) can be used for storing images, PDFs, or
|
||||
other binary data intended to be processed on a byte-level and that cannot
|
||||
be intepreted as text.
|
||||
|
||||
Binary data type does not participate in implicit conversions, and cannot be
|
||||
explicitly upconverted to other string types, although the inverse is
|
||||
possible.
|
||||
|
||||
Printing binary data to the standard output passes it through as-is,
|
||||
independent of the output encoding.
|
||||
|
||||
When Unicode semantics switch is off, binary string literals and binary
|
||||
strings returned by functions actually resolve to IS_STRING type, for
|
||||
backwards compatibility reasons.
|
||||
|
||||
|
||||
Zval Structure Changes
|
||||
======================
|
||||
|
||||
PHP is a type-agnostic language. Its data values are encapsulated in a zval
|
||||
(Zend value) structure that can change as necessary to accomodate various types.
|
||||
|
||||
struct _zval_struct {
|
||||
/* Variable information */
|
||||
union {
|
||||
long lval; /* long value */
|
||||
double dval; /* double value */
|
||||
struct {
|
||||
char *val;
|
||||
int len;
|
||||
} str; /* string value */
|
||||
HashTable *ht; /* hash table value */
|
||||
zend_object_value obj; /* object value */
|
||||
} value;
|
||||
zend_uint refcount;
|
||||
zend_uchar type; /* active type */
|
||||
zend_uchar is_ref;
|
||||
};
|
||||
|
||||
The type field determines what is stored in the union, IS_STRING being the only
|
||||
data type pertinent to this discussion. In the current version, the strings
|
||||
are binary-safe, but, for all intents and purposes, are assumed to be
|
||||
comprised of 8-bit characters. It is possible to treat the string value as
|
||||
an opaque type containing arbitrary binary data, and in fact that is how
|
||||
mbstring extension uses it, in order to store multibyte strings. However,
|
||||
many extensions and the Zend engine itself manipulate the string value
|
||||
directly without regard to its internals. Needless to say, this can lead to
|
||||
problems.
|
||||
|
||||
For IS_UNICODE type, we need to add another structure to the union:
|
||||
|
||||
union {
|
||||
....
|
||||
struct {
|
||||
UChar *val; /* Unicode string value */
|
||||
int32_t len; /* number of UChar's */
|
||||
....
|
||||
} value;
|
||||
|
||||
This cleanly separates the two types of strings and helps preserve backwards
|
||||
compatibility. For IS_BINARY type, we can re-use the str union.
|
||||
|
||||
|
||||
Language Modifications
|
||||
======================
|
||||
|
||||
If a Unicode switch is turned on, PHP string literals - single-quoted,
|
||||
double-quoted, and heredocs - become Unicode strings (IS_UNICODE type).
|
||||
They support all the same escape sequences and variable interpolations as
|
||||
previously, with the addition of some new escape sequences.
|
||||
|
||||
The contents of the strings are interpreted as follows:
|
||||
|
||||
- all non-escaped characters are interpreted as a corresponding Unicode
|
||||
codepoint based on the current script encoding, e.g. ASCII 'a' (0x51) =>
|
||||
U+0061, Shift-JIS (0x92 0x69) => U+4E2D
|
||||
|
||||
- existing PHP escape sequences are also interpreted as Unicode codepoints,
|
||||
including \xXX (hex) and \OOO (octal) numbers, e.g. "\x20" => U+0020
|
||||
|
||||
- two new escape sequences, \uXXXX and \UXXXXXX are interpreted as a 4 or
|
||||
6-hex Unicode codepoint value, e.g. \u0221 => U+0221, \U010410 =>
|
||||
U+10410
|
||||
|
||||
- a new escape sequence allows specifying a character by its full
|
||||
Unicode name, e.g. \C{THAI CHARACTER PHO SAMPHAO} => U+0E20
|
||||
|
||||
The single-quoted string is more restrictive than the other two types: so
|
||||
far the only escape sequence allowed inside of it was \', which specifies
|
||||
a literal single quote. However, single quoted strings now support the new
|
||||
Unicode character escape sequences as well.
|
||||
|
||||
PHP allows variable interpolation inside the double-quoted and heredoc strings.
|
||||
However, the parser separates the string into literal and variable chunks during
|
||||
compilation, e.g. "abc $var def" -> "abc" . $var . "def". This means that the
|
||||
literal chunks can be handled in the normal way for as far as Unicode
|
||||
support is concerned.
|
||||
|
||||
Since all string literals become Unicode by default, one loses the ability
|
||||
to specify byte-oriented or binary strings. In order to create binary string
|
||||
literals, a new syntax is necessary: prefixing a string literal with letter
|
||||
'b' creates a binary string.
|
||||
|
||||
$var = b'abc\001';
|
||||
$var = b"abc\001";
|
||||
$var = b<<<EOD
|
||||
abc\001
|
||||
EOD;
|
||||
|
||||
The binary string literals support the same escape sequences as the current
|
||||
PHP strings. If the Unicode switch is turned off, then the binary string
|
||||
literals generate normal string (IS_STRING) type internally, without any
|
||||
effect on the application.
|
||||
|
||||
The string operators have been changed to accomodate the new IS_UNICODE and
|
||||
IS_BINARY types. In more detail:
|
||||
|
||||
- The concatenation (.) operator has been changed to automatically coerce
|
||||
IS_STRING type to the more precise IS_UNICODE if its operands are of two
|
||||
different string types. It does not perform coersion for IS_BINARY type,
|
||||
however, since binary data is not considered to be in any encoding. To
|
||||
concatenate string with binary data, strings have to be cast to binary
|
||||
type first. The coersion uses the conversion matrix specified later in
|
||||
this document.
|
||||
|
||||
- The concatenation assignment operator (.=) has been changed similarly.
|
||||
|
||||
- The string indexing operators {}/[] have been changed to accomodate
|
||||
IS_UNICODE type strings and extract the specified character. Note that
|
||||
the index specifies a code point, not a byte, or a code unit, thus
|
||||
supporting supplementary characters as well.
|
||||
|
||||
- Both Unicode and binary string types can be used as array keys. If the
|
||||
Unicode switch is on, the native encoding strings are converted to
|
||||
Unicode, if they are used as hash keys, but binary strings are not.
|
||||
Note that this means if Unicode switch is off, then Unicode string "abc"
|
||||
and native string "abc" do not hash to the same value.
|
||||
|
||||
- Bitwise operators and increment/decrement operators do not work on
|
||||
Unicode strings. They do work on binary strings.
|
||||
|
||||
- Two new casting operators are introduced, (unicode) and (binary).
|
||||
They use the conversion matrix specified later in this document.
|
||||
|
||||
- The comparison operators when applied to Unicode strings, perform
|
||||
comparison in binary code point order. They also do appropriate coersion
|
||||
if the strings are of differing types.
|
||||
|
||||
- The arithmetic operators use the same semantic as today for converting
|
||||
strings to numbers. A Unicode string is considered numeric if it
|
||||
represents a long or a double number in en_US_POSIX locale.
|
||||
|
||||
|
||||
Inline HTML
|
||||
===========
|
||||
Because inline HTML blocks are intermixed with PHP ones, they are also
|
||||
written in the script encoding. PHP transcodes the HTML blocks to the output
|
||||
encoding as needed, resulting in direct passthrough if the script encoding
|
||||
matches output encoding.
|
||||
|
||||
|
||||
Identifiers
|
||||
===========
|
||||
Considering that scripts may be written in various encodings, we do not
|
||||
restrict identifiers to be ASCII-only. PHP allows any valid identifier based
|
||||
on the Unicode Standard Annex #31. The identifiers are case folded when
|
||||
necessary (class and function names) and converted to normalization form
|
||||
NFKC, so that two identifiers written in two compatible ways refer to the
|
||||
same thing.
|
||||
|
||||
|
||||
Numbers
|
||||
=======
|
||||
Unlike identifiers, we restrict numbers to consist only of ASCII digits and
|
||||
do not interpret them as written in a specific locale. The numbers are
|
||||
expected to adhere to en_US_POSIX or C locale, i.e. having no thousands
|
||||
separator and fractional separator being (.) "full stop". Numeric strings
|
||||
are supposed to adhere to the same rules, i.e. "10,3" is not interpreted as
|
||||
a number even if the current locale's fractional separator is comma.
|
||||
|
||||
|
||||
Parameter Parsing API Modifications
|
||||
===================================
|
||||
|
||||
Internal PHP functions largely uses zend_parse_parameters() API in order to
|
||||
obtain the parameters passed to them by the user. For example:
|
||||
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
This forces the input parameter to be a string, and its value and length are
|
||||
stored in the variables specified by the caller.
|
||||
|
||||
There are now three new specifiers: 't', 'u', and 'T'.
|
||||
|
||||
't' specifier
|
||||
-------------
|
||||
This specifier indicates that the caller requires the incoming parameter
|
||||
to be string data (IS_STRING, IS_UNICODE, IS_BINARY). The caller has to provide
|
||||
the storage for string value, length, and type.
|
||||
|
||||
void *str;
|
||||
int len;
|
||||
zend_uchar type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &str, &len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (type == IS_UNICODE) {
|
||||
/* process UTF-16 data */
|
||||
} else {
|
||||
/* process native string or binary data */
|
||||
}
|
||||
|
||||
For IS_STRING and IS_BINARY types, the length represents the number of
|
||||
bytes, and for IS_UNICODE the number of UChar's. When converting other
|
||||
types (numbers, booleans, etc) to strings, the exact behavior depends on
|
||||
the Unicode semantics switch: if on, they are converted to IS_UNICODE,
|
||||
otherwise to IS_STRING.
|
||||
|
||||
|
||||
'u' specifier
|
||||
-------------
|
||||
This specifier indicates that the caller requires the incoming parameter
|
||||
to be a Unicode UTF-16 encoded string. If a non-Unicode string is passed,
|
||||
the engine creates a copy of the string and automatically convert it
|
||||
to Unicode type before passing it to the internal function. No such
|
||||
conversion is necessary for Unicode strings, obviously. Binary type cannot
|
||||
be upconverted, and the engine issues an error in such case.
|
||||
|
||||
UChar *str;
|
||||
int32_t len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "u", &str, &len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
/* process UTF-16 data */
|
||||
|
||||
|
||||
'T' specifier
|
||||
-------------
|
||||
This specifier is useful when the function takes two or more strings and
|
||||
operates on them. Using 't' specifier for each one would be somewhat
|
||||
problematic if the passed-in strings are of mixed types, and multiple
|
||||
checks need to be performed in order to do anything. All parameters
|
||||
marked by the 'T' specifier are promoted to the same type.
|
||||
|
||||
Binary type is generally speaking the most precise one. However, we do not
|
||||
want to convert Unicode strings to binary ones, so an error is thrown
|
||||
if the incoming list of parameters has both Unicode and binary strings in
|
||||
it.
|
||||
|
||||
If there are no binary strings, and at least one of the strings is of
|
||||
Unicode type, then all the rest of the strings are upconverted to Unicode.
|
||||
|
||||
Otherwise the promotion is to IS_STRING type.
|
||||
|
||||
|
||||
void *str1, *str2;
|
||||
int len1, len2;
|
||||
zend_uchar type1, type2;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TT", &str1, &len1,
|
||||
&type1, &str2, &len2, &type2) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (type1 == IS_UNICODE) {
|
||||
/* process as Unicode, str2 is guaranteed to be Unicode as well */
|
||||
} else {
|
||||
/* process as native string, str2 is guaranteed to be the same */
|
||||
}
|
||||
|
||||
|
||||
The existing 's' specifier has been modified as well. If a Unicode string is
|
||||
passed in, it automatically copies and converts the string to the runtime
|
||||
encoding, and issues a warning. If a binary type is passed-in, no conversion
|
||||
is necessary.
|
||||
|
||||
|
||||
Upgrading Existing Functions
|
||||
============================
|
||||
|
||||
Upgrading functions to work with new data types will be a deliberate and
|
||||
involved process, because one needs to consider not only the mechanisms for
|
||||
processing Unicode characters, for example, but also the semantics of
|
||||
the function.
|
||||
|
||||
The main tenet of the upgrade process should be that when processing Unicode
|
||||
strings, the unit of operation is a code point, not a code unit or a byte.
|
||||
For example, strlen() returns the number of code points in the string.
|
||||
|
||||
strlen('abc') = 3
|
||||
strlen('ab\U010000') = 3
|
||||
strlen('ab\uD800\uDC00') = 3 /* not 4 */
|
||||
|
||||
Function upgrade guidelines are available in a separate document.
|
||||
|
||||
|
||||
Unicode Extension
|
||||
=================
|
||||
|
||||
There will be one or more extensions that provide Unicode and i18n services
|
||||
to PHP. In phase I only the conversion service is necessary. The Unicode
|
||||
extension is 'ext/unicode' and its functions should be prefixed with 'unicode'
|
||||
or 'icu'.
|
||||
|
||||
Conversion Functions
|
||||
--------------------
|
||||
|
||||
string unicode_encode(unicode $input, text $encoding)
|
||||
|
||||
Takes a UTF-16 Unicode string and converts it to the the target
|
||||
encoding, returning the result.
|
||||
|
||||
unicode unicode_decode(string $input, text $encoding)
|
||||
|
||||
Takes a string in the source encoding and converts it to a UTF-16
|
||||
Unicode string, returning the result.
|
||||
|
||||
|
||||
Type Conversion Matrix
|
||||
======================
|
||||
|
||||
to | IS_STRING | IS_UNICODE | IS_BINARY
|
||||
from | | |
|
||||
-------------------------------------------------------------------
|
||||
| | |
|
||||
IS_STRING | n/a | implicit=yes | explicit=yes
|
||||
| | explicit=yes | implicit=no
|
||||
| | |
|
||||
-------------------------------------------------------------------
|
||||
| | |
|
||||
IS_UNICODE | explicit=yes | n/a | explicit=yes
|
||||
| implicit=no | | implicit=no
|
||||
| | |
|
||||
------------------------------|------------------------------------
|
||||
| | |
|
||||
IS_BINARY | explicit=no | explicit=no | n/a
|
||||
| implicit=no | implicit=no |
|
||||
| | |
|
||||
|
||||
explicit = casting
|
||||
implicit = for concatenation, etc
|
||||
|
||||
IS_STRING <-> IS_UNICODE uses runtime-encoding
|
||||
IS_UNICODE -> IS_BINARY converts to runtime encoding first, then to binary
|
||||
|
||||
|
||||
Implementation Details That Need Expanding
|
||||
==========================================
|
||||
- Streams support for Unicode - What stream filters will we be providing?
|
||||
- Conversion errors behavior - Need to define the default.
|
||||
- INI files encoding - Do we support BOMs?
|
||||
- There are likely to be other issues which are missing from this document
|
||||
|
||||
|
||||
Build System
|
||||
============
|
||||
|
||||
Unicode support in PHP is always enabled. The only configuration option
|
||||
during development should be the location of the ICU headers and libraries.
|
||||
|
||||
--with-icu-dir=<dir> <dir> parameter specifies the location of ICU
|
||||
header and library files.
|
||||
|
||||
After the initial development we have to repackage ICU library for our needs
|
||||
and bundle it with PHP.
|
||||
|
||||
|
||||
Document History
|
||||
================
|
||||
0.5: Updated per latest discussions. Removed tentative language in several
|
||||
places, since we have decided on everything described here already.
|
||||
Clarified details according to Phase II progress.
|
||||
|
||||
0.4: Updated to include all the latest discussions. Updated development
|
||||
phases.
|
||||
|
||||
0.3: Updated to include all the latest discussions.
|
||||
|
||||
0.2: Updated Phase I design proposal per discussion on unicode@php.net.
|
||||
Modified Internal Encoding section to contain only UTF-16 info..
|
||||
Expanded Script Encoding section.
|
||||
Added Binary Data Type section.
|
||||
Amended Language Modifications section to describe string literals
|
||||
behavior.
|
||||
Amended Build System section.
|
||||
|
||||
0.1: Phase I design proposal
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
Unicode
|
||||
http://www.unicode.org
|
||||
|
||||
Unicode Glossary
|
||||
http://www.unicode.org/glossary/
|
||||
|
||||
UTF-8
|
||||
http://www.utf-8.com/
|
||||
|
||||
UTF-16
|
||||
http://www.ietf.org/rfc/rfc2781.txt
|
||||
|
||||
ICU Homepage
|
||||
http://www.ibm.com/software/globalization/icu/
|
||||
|
||||
ICU User Guide and API Reference
|
||||
http://icu.sourceforge.net/
|
||||
|
||||
Unicode Annex #31
|
||||
http://www.unicode.org/reports/tr31/
|
||||
|
||||
PHP Parameter Parsing API
|
||||
http://www.php.net/manual/en/zend.arguments.retrieval.php
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
Andrei Zmievski <andrei@gravitonic.com>
|
||||
|
||||
vim: set et :
|
||||
@@ -1,403 +0,0 @@
|
||||
This document attempts to describe portions of the API related to the new
|
||||
Unicode functionality and the best practices for upgrading existing
|
||||
functions to support Unicode.
|
||||
|
||||
Your first stop should be README.UNICODE: it covers the general Unicode
|
||||
functionality and concepts without going into technical implementation
|
||||
details.
|
||||
|
||||
Working in Unicode World
|
||||
========================
|
||||
|
||||
Strings
|
||||
-------
|
||||
|
||||
A lot of internal functionality is controlled by the unicode_semantics
|
||||
switch. Its value is found in the Unicode globals variable, UG(unicode). It
|
||||
is either on or off for the entire request.
|
||||
|
||||
The big thing is that there are two new string types: IS_UNICODE and
|
||||
IS_BINARY. The former one has its own storage in the value union part of
|
||||
zval (value.ustr) and the latter re-uses value.str.
|
||||
|
||||
Both types have new macros to set the zval value and to access it.
|
||||
|
||||
Z_USTRVAL(), Z_USTRLEN()
|
||||
- accesses the value and length (in code units) of the Unicode type string
|
||||
|
||||
Z_BINVAL(), Z_BINLEN()
|
||||
- accesses the value and length of the binary type string
|
||||
|
||||
Z_UNIVAL(), Z_UNILEN()
|
||||
- accesses either Unicode or native string value, depending on the current
|
||||
setting of UG(unicode) switch. The Z_UNIVAL() type resolves to char*, so
|
||||
you may need to cast it appropriately.
|
||||
|
||||
Z_USTRCPLEN()
|
||||
- gives the number of codepoints in the Unicode type string
|
||||
|
||||
ZVAL_BINARY(), ZVAL_BINARYL()
|
||||
- Sets zval to hold a binary string. Takes the same parameters as
|
||||
Z_STRING(), Z_STRINGL().
|
||||
|
||||
ZVAL_UNICODE, ZVAL_UNICODEL()
|
||||
- Sets zval to hold a Unicode string. Takes the same parameters as
|
||||
Z_STRING(), Z_STRINGL().
|
||||
|
||||
ZVAL_ASCII_STRING(), ZVAL_ASCII_STRINGL()
|
||||
- When UG(unicode) is off, it's equivalent to Z_STRING(), ZSTRINGL(). When
|
||||
UG(unicode) is on, it sets zval to hold a Unicode representation of the
|
||||
passed-in ASCII string. It will always create a new string in
|
||||
UG(unicode)=1 case, so the value of the duplicate flag is not taken into
|
||||
account.
|
||||
|
||||
ZVAL_RT_STRING()
|
||||
- When UG(unicode) is off, it's equivalent to Z_STRING(), Z_STRINGL(). WHen
|
||||
UG(unicode) is on, it takes the input string, converts it to Unicode
|
||||
using the runtime_encoding converter and sets zval to it. Since a new
|
||||
string is always created in this case, the value of the duplicate flag
|
||||
does not matter.
|
||||
|
||||
ZVAL_TEXT()
|
||||
- This macro sets the zval to hold either a Unicode or a normal string,
|
||||
depending on the value of UG(unicode). No conversion happens, so the
|
||||
argument has to be cast to (char*) when using this macro. One example of
|
||||
its usage would be to initialize zval to hold the name of a user
|
||||
function.
|
||||
|
||||
There are, of course, related conversion macros.
|
||||
|
||||
convert_to_string_with_converter(zval *op, UConverter *conv)
|
||||
- converts a zval to native string using the specified converter, if necessary.
|
||||
|
||||
convert_to_binary()
|
||||
- converts a zval to binary string.
|
||||
|
||||
convert_to_unicode()
|
||||
- converts a zval to Unicode string.
|
||||
|
||||
convert_to_unicode_with_converter(zval *op, UConverter *conv)
|
||||
- converts a zval to Unicode string using the specified converter, if
|
||||
necessary.
|
||||
|
||||
convert_to_text(zval *op)
|
||||
- converts a zval to either Unicode or native string, depending on the
|
||||
value of UG(unicode) switch
|
||||
|
||||
zend_ascii_to_unicode() function can be used to convert an ASCII char*
|
||||
string to Unicode. This is useful especially for inline string literals, in
|
||||
which case you can simply use USTR_MAKE() macro, e.g.:
|
||||
|
||||
UChar* ustr;
|
||||
|
||||
ustr = USTR_MAKE("main");
|
||||
|
||||
If you need to initialize a few such variables, it may be more efficient to
|
||||
use ICU macros, which avoid the conversion, depending on the platform. See
|
||||
[1] for more information.
|
||||
|
||||
USTR_FREE() can be used to free a UChar* string safely, since it checks for
|
||||
NULL argument. USTR_LEN() takes either a UChar* or a char* argument,
|
||||
depending on the UG(unicode) value, and returns its length. Cast the
|
||||
argument to char* before passing it.
|
||||
|
||||
The list of functions that add new array values and add object properties
|
||||
has also been expanded to include the new types. Please see zend_API.h for
|
||||
full listing (add_*_ascii_string_*, add_*_rt_string_*, add_*_unicode_*,
|
||||
add_*_binary_*).
|
||||
|
||||
UBYTES() macro can be used to obtain the number of bytes necessary to store
|
||||
the given number of UChar's. The typical usage is:
|
||||
|
||||
char *constant_name = colon + (UG(unicode)?UBYTES(2):2);
|
||||
|
||||
|
||||
Code Points and Code Units
|
||||
--------------------------
|
||||
|
||||
Unicode type strings are in the UTF-16 encoding where 1 Unicode character
|
||||
may be represented by 1 or 2 UChar's. Each UChar is referred to as a "code
|
||||
unit", and a full Unicode character as a "code point". Consequently, number
|
||||
of code units and number of code points for the same Unicode string may be
|
||||
different. This has many implications, the most important of which is that
|
||||
you cannot simply index the UChar* string to get the desired codepoint.
|
||||
|
||||
The zval's value.ustr.len contains actually the number of code units. To
|
||||
obtain the number of code points, one can use u_counChar32() ICU API
|
||||
function or Z_USTRCPLEN() macro.
|
||||
|
||||
ICU provides a number of macros for working with UTF-16 strings on the
|
||||
codepoint level [2]. They allow you to do things like obtain a codepoint at
|
||||
random code unit offset, move forward and backward over the string, etc.
|
||||
There are two versions of iterator macros, *_SAFE and *_UNSAFE. It is strong
|
||||
recommended to use *_SAFE version, since they handle unpaired surrogates and
|
||||
check for string boundaries. Here is an example of how to move through
|
||||
UChar* string and work on codepoints.
|
||||
|
||||
UChar *str = ...;
|
||||
int32_t str_len = ...;
|
||||
UChar32 codepoint;
|
||||
int32_t offset = 0;
|
||||
|
||||
while (offset < str_len) {
|
||||
U16_NEXT(str, offset, str_len, codepoint);
|
||||
/* now we have the Unicode character in codepoint */
|
||||
}
|
||||
|
||||
There is not macro to get a codepoint at a certain code point offset, but
|
||||
there is a Zend API function that does it.
|
||||
|
||||
inline UChar32 zend_get_codepoint_at(UChar *str, int32_t length, int32_t n);
|
||||
|
||||
To retrieve 3rd codepoint, you would call:
|
||||
|
||||
zend_get_codepoint_at(str, str_len, 3);
|
||||
|
||||
If you have a UChar32 codepoint and need to put it into a UChar* string,
|
||||
there is another helper function, zend_codepoint_to_uchar(). It takes
|
||||
a single UChar32 and converts it to a UChar sequence (1 or 2 UChar's).
|
||||
|
||||
UChar buf[8];
|
||||
UChar32 codepoint = 0x101a2;
|
||||
int8_t num_uchars;
|
||||
num_uchars = zend_codepoint_to_uchar(codepoint, buf);
|
||||
|
||||
The return value is the number of resulting UChar's or 0, which indicates
|
||||
invalid codepoint.
|
||||
|
||||
|
||||
Memory Allocation
|
||||
-----------------
|
||||
|
||||
For ease of use and to reduce possible bugs, there are memory allocation
|
||||
functions specific to Unicode strings. Please use them at all times when
|
||||
allocating UChar's.
|
||||
|
||||
eumalloc(size)
|
||||
eurealloc(ptr, size)
|
||||
eustrndup(s, length)
|
||||
eustrdup(s)
|
||||
|
||||
peumalloc(size, persistent)
|
||||
peurealloc(ptr, size, persistent)
|
||||
|
||||
The size parameter refers to the number of UChar's, not bytes.
|
||||
|
||||
|
||||
Hashes
|
||||
------
|
||||
|
||||
Hashes API has been upgraded to work with Unicode and binary strings. All
|
||||
hash functions that worked with string keys now have their equivalent
|
||||
zend_u_hash_* API. The zend_u_hash_* functions take the type of the key
|
||||
string as the second argument.
|
||||
|
||||
When UG(unicode) switch is on, the IS_STRING keys are upconverted to
|
||||
IS_UNICODE and then used in the hash lookup.
|
||||
|
||||
There are two new constants that define key types:
|
||||
|
||||
#define HASH_KEY_IS_BINARY 4
|
||||
#define HASH_KEY_IS_UNICODE 5
|
||||
|
||||
Note that zend_hash_get_current_key_ex() does not have a zend_u_hash_*
|
||||
version. It returns the key as a char* pointer, you can can cast it
|
||||
appropriately based on the key type.
|
||||
|
||||
|
||||
Identifiers and Class Entries
|
||||
-----------------------------
|
||||
|
||||
In Unicode mode all the identifiers are Unicode strings. This means that
|
||||
while various structures such as zend_class_entry, zend_function, etc store
|
||||
the identifier name as a char* pointer, it will actually point to UChar*
|
||||
string. Be careful when accessing the names of classes, functions, and such
|
||||
-- always check UG(unicode) before using them.
|
||||
|
||||
In addition, zend_class_entry has a u_twin field that points to its Unicode
|
||||
counterpart in UG(unicode) mode. Use U_CLASS_ENTRY() macro to access the
|
||||
correct class entry, e.g.:
|
||||
|
||||
ce = U_CLASS_ENTRY(default_exception_ce);
|
||||
|
||||
|
||||
Formatted Output
|
||||
----------------
|
||||
|
||||
Since UTF-16 strings frequently contain NULL bytes, you cannot simpley use
|
||||
%s format to print them out. Towards that end, output functions such as
|
||||
php_printf(), spprintf(), etc now have three different formats for use with
|
||||
Unicode strings:
|
||||
|
||||
%r
|
||||
This format treats the corresponding argument as a Unicode string. The
|
||||
string is automatically converted to the output encoding. If you wish to
|
||||
apply a different converter to the string, use %*r and pass the
|
||||
converter before the string argument.
|
||||
|
||||
UChar *class_name = USTR_NAME("ReflectionClass");
|
||||
zend_printf("%r", class_name);
|
||||
|
||||
%R
|
||||
This format requires at least two arguments: the first one specifies the
|
||||
type of the string to follow (IS_STRING or IS_UNICODE), and the second
|
||||
one - the string itself. If the string is of Unicode type, it is
|
||||
automatically converted to the output encoding. If you wish to apply
|
||||
a different converter to the string, use %*R and pass the converter
|
||||
before the string argument.
|
||||
|
||||
zend_throw_exception_ex(U_CLASS_ENTRY(reflection_exception_ptr), 0 TSRMLS_CC,
|
||||
"Interface %R does not exist",
|
||||
Z_TYPE_P(class_name), Z_UNIVAL_P(class_name));
|
||||
|
||||
%v
|
||||
This format takes only one parameter, the string, but the expected
|
||||
string type depends on the UG(unicode) value. If the string is of
|
||||
Unicode type, it is automatically converted to the output encoding. If
|
||||
you wish to apply a different converter to the string, use %*R and pass
|
||||
the converter before the string argument.
|
||||
|
||||
zend_error(E_WARNING, "%v::__toString() did not return anything",
|
||||
Z_OBJCE_P(object)->name);
|
||||
|
||||
|
||||
|
||||
Upgrading Functions
|
||||
===================
|
||||
|
||||
Let's take a look at a couple of functions that have been upgraded to
|
||||
support new string types.
|
||||
|
||||
substr()
|
||||
--------
|
||||
|
||||
This functions returns part of a string based on offset and length
|
||||
parameters.
|
||||
|
||||
void *str;
|
||||
int32_t str_len, cp_len;
|
||||
zend_uchar str_type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tl|l", &str, &str_len, &str_type, &f, &l) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
The first thing we notice is that the incoming string specifier is 't',
|
||||
which means that we can accept all 3 string types. The 'str' variable is
|
||||
declared as void*, because it can point to either UChar* or char*.
|
||||
The actual type of the incoming string is stored in 'str_type' variable.
|
||||
|
||||
if (str_type == IS_UNICODE) {
|
||||
cp_len = u_countChar32(str, str_len);
|
||||
} else {
|
||||
cp_len = str_len;
|
||||
}
|
||||
|
||||
If the string is a Unicode one, we cannot rely on the str_len value to tell
|
||||
us the number of characters in it. Instead, we call u_countChar32() to
|
||||
obtain it.
|
||||
|
||||
The next several lines normalize start and length parameters to fit within the
|
||||
string. Nothing new here. Then we locate the appropriate segment.
|
||||
|
||||
if (str_type == IS_UNICODE) {
|
||||
int32_t start = 0, end = 0;
|
||||
U16_FWD_N((UChar*)str, end, str_len, f);
|
||||
start = end;
|
||||
U16_FWD_N((UChar*)str, end, str_len, l);
|
||||
RETURN_UNICODEL((UChar*)str + start, end-start, 1);
|
||||
|
||||
Since codepoint (character) #n is not necessarily at offset #n in Unicode
|
||||
strings, we start at the beginning and iterate forward until we have gone
|
||||
through the required number of codepoints to reach the start of the segment.
|
||||
Then we save the location in 'start' and continue iterating through the number
|
||||
of codepoints specified by the offset. Once that's done, we can return the
|
||||
segment as a Unicode string.
|
||||
|
||||
} else {
|
||||
RETURN_STRINGL((char*)str + f, l, 1);
|
||||
}
|
||||
|
||||
For native and binary types, we can return the segment directly.
|
||||
|
||||
|
||||
strrev()
|
||||
--------
|
||||
|
||||
Let's look at strrev() which requires somewhat more complicated upgrade.
|
||||
While one of the guidelines for upgrades is that combining sequences are not
|
||||
really taken into account during processing -- substr() can break them up,
|
||||
for example -- in this case, we actually should be concerned, because
|
||||
reversing combining sequence may result in a completely different string. To
|
||||
illustrate:
|
||||
|
||||
a (U+0061 LATIN SMALL LETTER A)
|
||||
o (U+006f LATIN SMALL LETTER O)
|
||||
+ ' (U+0301 COMBINING ACUTE ACCENT)
|
||||
+ _ (U+0320 COMBINING MINUS SIGN BELOW)
|
||||
l (U+006C LATIN SMALL LETTER L)
|
||||
|
||||
Reversing this would result in:
|
||||
|
||||
l (U+006C LATIN SMALL LETTER L)
|
||||
+ _ (U+0320 COMBINING MINUS SIGN BELOW)
|
||||
+ ' (U+0301 COMBINING ACUTE ACCENT)
|
||||
o (U+006f LATIN SMALL LETTER O)
|
||||
a (U+0061 LATIN SMALL LETTER A)
|
||||
|
||||
All of a sudden the combining marks are being applied to 'l' instead of 'o'.
|
||||
To avoid this, we need to treat combininig sequences as a unit, by checking
|
||||
the combining character class of each character with u_getCombiningClass().
|
||||
|
||||
strrev() obtains its single argument, a string, and unless the string is of
|
||||
Unicode type, processes it exactly as before, simply swapping bytes around.
|
||||
For Unicode case, the magic is like this:
|
||||
|
||||
int32_t i, x1, x2;
|
||||
UChar32 ch;
|
||||
UChar *u_s, *u_n, *u_p;
|
||||
|
||||
u_n = eumalloc(Z_USTRLEN_PP(str)+1);
|
||||
u_p = u_n;
|
||||
u_s = Z_USTRVAL_PP(str);
|
||||
|
||||
i = Z_USTRLEN_PP(str);
|
||||
while (i > 0) {
|
||||
U16_PREV(u_s, 0, i, ch);
|
||||
if (u_getCombiningClass(ch) == 0) {
|
||||
u_p += zend_codepoint_to_uchar(ch, u_p);
|
||||
} else {
|
||||
x2 = i;
|
||||
do {
|
||||
U16_PREV(u_s, 0, i, ch);
|
||||
} while (u_getCombiningClass(ch) != 0);
|
||||
x1 = i;
|
||||
while (x1 <= x2) {
|
||||
U16_NEXT(u_s, x1, Z_USTRLEN_PP(str), ch);
|
||||
u_p += zend_codepoint_to_uchar(ch, u_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
*u_p = 0;
|
||||
|
||||
The basic idea is to walk the string backwards from the end, using
|
||||
U16_PREV() macro. If the combining class of the current character is 0,
|
||||
meaning it's a base character and not a combining mark, we simply append it
|
||||
to the new string. Otherwise, we save the location of the index and do a run
|
||||
over the characters until we get to the next one with combining class 0. At
|
||||
that point we append the sequence as is, without reversing, to the new
|
||||
string. Voila.
|
||||
|
||||
Note that the code uses zend_codepoint_to_uchar() to convert full Unicode
|
||||
characters (UChar32 type) to 1 or 2 UTF-16 code units (UChar type).
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] http://icu.sourceforge.net/apiref/icu4c/ustring_8h.html#a1
|
||||
|
||||
[2] http://icu.sourceforge.net/apiref/icu4c/utf16_8h.html
|
||||
|
||||
vim: set et ai tw=76 fo=tron21:
|
||||
@@ -1,174 +0,0 @@
|
||||
The Win32 Build System.
|
||||
$Id$
|
||||
Wez Furlong <wez@thebrainroom.com>
|
||||
|
||||
If you need help with the build system, send mail to
|
||||
internals@lists.php.net; please don't email me directly.
|
||||
|
||||
===========================================================
|
||||
Contents:
|
||||
1. How to build PHP under windows
|
||||
a. Requirements
|
||||
b. Opening a command prompt
|
||||
c. Generating configure.js
|
||||
d. Configuring
|
||||
e. Building
|
||||
f. Cleaning up
|
||||
g. Running the test suite
|
||||
h. snapshot building
|
||||
|
||||
2. How to write config.w32 files
|
||||
x. to be written.
|
||||
|
||||
===========================================================
|
||||
1. How to build PHP under windows
|
||||
a. Requirements
|
||||
|
||||
You need:
|
||||
- Windows Scripting Host (cscript.exe)
|
||||
- Microsoft Build Tools from:
|
||||
Microsoft Visual Studio (VC6) or later
|
||||
|
||||
You also need:
|
||||
- bindlib_w32 [http://www.php.net/extra/bindlib_w32.zip]
|
||||
- win32build [http://www.php.net/extra/win32build.zip]
|
||||
|
||||
b. Opening the Build Environment Command Prompt:
|
||||
- Using Visual Studio (VC6)
|
||||
1. Install it
|
||||
2. If you have a VC++ Command Prompt icon on your start menu,
|
||||
click on it to get a Command Prompt with the env vars
|
||||
set up correctly.
|
||||
|
||||
If not, create a new shortcut and set the Target to:
|
||||
|
||||
%comspec% /k "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
|
||||
|
||||
You might also want to set the prompt to start in
|
||||
a convenient location (such as the root of your
|
||||
PHP source checkout).
|
||||
|
||||
- Using Visual Studio .Net
|
||||
1. Install it.
|
||||
2. Under the Visual Studio .Net Tools sub menu of your start
|
||||
menu, you should have a Visual Studio .Net Command Prompt
|
||||
icon. If not, create a new shortcut and set the Target to:
|
||||
|
||||
%comspec% /k "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat"
|
||||
|
||||
You might also want to set the prompt to start in
|
||||
a convenient location (such as the root of your
|
||||
PHP source checkout).
|
||||
|
||||
- Using the Platform SDK tools
|
||||
1. Download the Platform SDK:
|
||||
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
|
||||
|
||||
- You need the Core SDK, which is approx 200MB to download
|
||||
and requires approx 500MB of disk space.
|
||||
- The other components of the SDK are not required by PHP
|
||||
- You might be able to reduce the download size by downloading
|
||||
the installer control component first and then selecting
|
||||
only the Build Environment (around 30MB), but I haven't
|
||||
tried this.
|
||||
|
||||
** Note: it seems that MS don't include the 32 bit
|
||||
build tools in the platform SDK any longer, so
|
||||
you will probably have very limited luck if you
|
||||
don't also have VC++ or VS.Net already installed.
|
||||
|
||||
2. Once installed, you will have an icon on your start menu
|
||||
that will launch the build environment; the latest SDK's
|
||||
install a number of different versions of this; you probably
|
||||
want to choose the Windows 2000 Retail build environment.
|
||||
Clicking on this will open a command prompt with its Path,
|
||||
Include and Lib env vars set to point to the build tools
|
||||
and win32 headers.
|
||||
|
||||
c. Generating configure
|
||||
|
||||
Change directory to where you have your PHP 5 sources.
|
||||
Run buildconf.bat.
|
||||
|
||||
d. Configuring
|
||||
|
||||
cscript /nologo configure.js --help
|
||||
|
||||
Will give you a list of configuration options; these will
|
||||
have the form:
|
||||
|
||||
--enable-foo or --disable-foo or --with-foo or --without-foo.
|
||||
|
||||
--enable-foo will turn something on, and is equivalent to
|
||||
specifying --enable-foo=yes
|
||||
|
||||
--disable-foo will turn something off, and is equivalent to
|
||||
specifying --enable-foo=no
|
||||
|
||||
--enable-foo=shared will attempt to build that feature as
|
||||
a shared, dynamically loadable module.
|
||||
|
||||
Sometimes a configure option needs additional information
|
||||
about where to find headers and libraries; quite often
|
||||
you can specify --enable-foo=option where option could be
|
||||
the path to where to find those files. If you want to
|
||||
specify a parameter and build it as shared, you can use
|
||||
this syntax instead: --enable-foo=shared,option
|
||||
|
||||
The same rules all apply to --with-foo and --without-foo;
|
||||
the only difference is the way the options are named;
|
||||
the convention is that --enable-foo means that you are
|
||||
switching on something that comes with PHP, whereas
|
||||
--with-foo means that you want to build in something
|
||||
external to PHP.
|
||||
|
||||
e. Building
|
||||
|
||||
Once you have successfully configured your build (make
|
||||
sure you read the output from the command to make sure
|
||||
it worked correctly), you can build the code; simply type
|
||||
|
||||
"nmake" at the command prompt, and it will build everthing
|
||||
you asked for.
|
||||
|
||||
Once the build has completed, you will find your binaries
|
||||
in the build dir determined by configure; this is typically
|
||||
Release_TS for release builds or Debug_TS for debug builds.
|
||||
If you build a non-thread-safe build, it will use Release
|
||||
or Debug to store the files. Also in this build dir you
|
||||
will find sub directories for each module that went into
|
||||
your PHP build. The files you'll want to keep are the
|
||||
.exe and .dll files directly in your build dir.
|
||||
|
||||
f. Cleaning Up
|
||||
|
||||
You can automatically delete everything that was built
|
||||
by running "nmake clean". This will delete everything
|
||||
that was put there when you ran nmake, including the
|
||||
.exe and .dll files.
|
||||
|
||||
g. Running the test suite
|
||||
|
||||
You can verify that your build is working well by running
|
||||
the regression test suite. You do this by typing
|
||||
"nmake test". You can specify the tests you want to run
|
||||
by defing the TESTS variable - if you wanted to run the
|
||||
sqlite test suite only, you would type
|
||||
"nmake /D TESTS=ext/sqlite/tests test"
|
||||
|
||||
h. Snapshot Building
|
||||
|
||||
If you want to set up an automated build that will tolerate
|
||||
breakages in some of the modules, you can use the
|
||||
--enable-snapshot-build configure option to generate a
|
||||
makefile optimized for that purpose. A snapshot build will
|
||||
switch the argument parser so that the default option for
|
||||
configure switches that your don't specify will be set
|
||||
to "shared". The effect of this is to turn on all options
|
||||
unless you explicitly disable them. When you have configured
|
||||
your snapshot build, you can use "nmake build-snap" to build
|
||||
everything, ignoring build errors in individual extensions
|
||||
or SAPI.
|
||||
|
||||
vim:tw=78:sw=1:ts=1:et
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Using PHP 5 with the Zeus Web Server
|
||||
Using PHP4 with the Zeus Web Server
|
||||
-----------------------------------
|
||||
|
||||
Zeus fully supports running PHP in combination with our
|
||||
|
||||
+7
-12
@@ -1,12 +1,12 @@
|
||||
Input Filter Support in PHP 5
|
||||
-----------------------------
|
||||
Input Filter Support in PHP5
|
||||
----------------------------
|
||||
|
||||
XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
|
||||
and can be quite difficult to prevent. Whenever you accept user data
|
||||
and somehow display this data back to users, you are likely vulnerable
|
||||
to XSS hacks.
|
||||
|
||||
The Input Filter support in PHP 5 is aimed at providing the framework
|
||||
The Input Filter support in PHP5 is aimed at providing the framework
|
||||
through which a company-wide or site-wide security policy can be
|
||||
enforced. It is implemented as a SAPI hook and is called from the
|
||||
treat_data and post handler functions. To implement your own security
|
||||
@@ -34,7 +34,7 @@ ZEND_END_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
zend_function_entry my_input_filter_functions[] = {
|
||||
function_entry my_input_filter_functions[] = {
|
||||
PHP_FE(my_get_raw, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
@@ -89,11 +89,7 @@ PHP_MINFO_FUNCTION(my_input_filter)
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
/* The filter handler. If you return 1 from it, then PHP also registers the
|
||||
* (modified) variable. Returning 0 prevents PHP from registering the variable;
|
||||
* you can use this if your filter already registers the variable under a
|
||||
* different name, or if you just don't want the variable registered at all. */
|
||||
SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
|
||||
unsigned int my_sapi_input_filter(int arg, char *var, char **val, unsigned int val_len)
|
||||
{
|
||||
zval new_var;
|
||||
zval *array_ptr = NULL;
|
||||
@@ -141,8 +137,7 @@ SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
|
||||
|
||||
php_strip_tags(*val, val_len, NULL, NULL, 0);
|
||||
|
||||
*new_val_len = strlen(*val);
|
||||
return 1;
|
||||
return strlen(*val);
|
||||
}
|
||||
|
||||
PHP_FUNCTION(my_get_raw)
|
||||
@@ -155,7 +150,7 @@ PHP_FUNCTION(my_get_raw)
|
||||
HashTable *hash_ptr;
|
||||
char *raw_var;
|
||||
|
||||
if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
|
||||
if(zend_parse_parameters(2 TSRMLS_CC, "ls|l", &arg, &var, &var_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,17 @@ Zend
|
||||
dimensional arrays.
|
||||
* Look at replacing c-lib call tolower().
|
||||
* Make hash API functions work with HASH_OF() to save time.
|
||||
* Allow to set a default value for call-by-reference-parameters.
|
||||
eg: function hello (&$pallo = NULL) {}
|
||||
* Add configure test to determine if dlsym() requires underscore and set
|
||||
DLSYM_NEEDS_UNDERSCORE accordingly. Perl and zsh have it in configure,
|
||||
for example. (DONE?)
|
||||
* Allow foreach ($array as $k => &$val) syntax. right now we cannot
|
||||
traverse an array without copying each element.
|
||||
* Native large number support (probably with GNU GMP)
|
||||
* Const'ify APIs. Right now, many functions leave parameters untouched,
|
||||
but don't declare those as const. This makes interaction with other
|
||||
interfaces difficult which pass const parameters to us.
|
||||
* Clean up object->string conversion behavior wherever possible (switch(),
|
||||
comparison, etc)
|
||||
|
||||
|
||||
global
|
||||
@@ -31,6 +36,8 @@ global
|
||||
of compliance.
|
||||
* see what functions might need to be changed to use HashPosition, so
|
||||
that the internal array pointer is not affected.
|
||||
* Move most extensions and PEAR packages out of the PHP CVS tree,
|
||||
include them again during release packaging.
|
||||
|
||||
Other
|
||||
* use thread-safe resolver functions (either require BIND 8 or adns).
|
||||
@@ -126,6 +133,10 @@ ext/session
|
||||
* Provide a callback facility which is executed upon encountering
|
||||
an unknown class name during deserialization
|
||||
|
||||
ext/sockets
|
||||
-----------
|
||||
* Review/Fix vectors
|
||||
|
||||
ext/standard
|
||||
------------
|
||||
* Add a version number to data serialized via serialize().
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Zend Engine
|
||||
-----------
|
||||
- Look at making zend_constant value member be a zval* instead of zval. (Andi)
|
||||
- Implement inheritance rules for type hints. (Marcus)
|
||||
- Find a keyword for the if-set-or operator (apply the patch). (Marcus, all)
|
||||
@@ -16,6 +16,83 @@ Responsibility: Andi, Stig?
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: Introspection
|
||||
|
||||
get_function_definition(<is_callable> [field]) =>
|
||||
array(
|
||||
file => filename
|
||||
line_start =>
|
||||
line_end =>
|
||||
parameters => array( name, byref, default )
|
||||
static_variables => array( name, value/default )
|
||||
scope => 'namespace' | 'class' | null
|
||||
namespace => classname | namespacename | 'main'
|
||||
protection => protection_flags
|
||||
phpdoc => pre-scanned-phpdoc-string
|
||||
type => 'internal' | 'user'
|
||||
)
|
||||
|
||||
get_class_definition(<class> [field]) =>
|
||||
array(
|
||||
type => 'internal' | 'user'
|
||||
file => filename
|
||||
line_start =>
|
||||
line_end =>
|
||||
name => pretty-name
|
||||
parent => classname | namespace | null
|
||||
flags => bitfield (ABSTRACT)
|
||||
methods => array( array( name, phpdoc ) )
|
||||
default_properties => array( array( name, value, phpdoc ) )
|
||||
private_properties => array( array( name, value, phpdoc ) )
|
||||
protected_properties => array( array( name, value, phpdoc ) )
|
||||
public_properties => array( array( name, value, phpdoc ) )
|
||||
static_members => array( array( name, value, phpdoc ) )
|
||||
constants => array( array( name, value, phpdoc ) )
|
||||
classes => array( array( name, phpdoc ) )
|
||||
phpdoc => pre-scanned-phpdoc-string
|
||||
)
|
||||
|
||||
get_constant_definition(<constant> [field]) =>
|
||||
array(
|
||||
file => filename
|
||||
line_start =>
|
||||
line_end =>
|
||||
name =>
|
||||
value =>
|
||||
phpdoc =>
|
||||
)
|
||||
|
||||
get_global_variable_defintion(<name> [field]) =>
|
||||
array(
|
||||
file =>
|
||||
line_start =>
|
||||
line_end =>
|
||||
name =>
|
||||
phpdoc =>
|
||||
)
|
||||
|
||||
We tried to take into account the implementation of each piece of
|
||||
information, and there are some that are problematic, especially those
|
||||
regarding constants and global variables (where do we store the extra
|
||||
information?)
|
||||
|
||||
With "pre-scanned-phpdoc-string" we mean converting:
|
||||
|
||||
/**
|
||||
* Blah blah blah
|
||||
* @param foo ...
|
||||
*/
|
||||
|
||||
to:
|
||||
|
||||
Blah blah blah
|
||||
@param foo
|
||||
|
||||
The rest of the phpdoc handling should be left to an extension.
|
||||
Responsibility: Stig, Andrei, Harald
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: Redesign of API Versioning
|
||||
Responsibility: ?
|
||||
Time frame: 1 month
|
||||
@@ -95,6 +172,31 @@ Responsibility: Sterling, Harald
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: MySQL Extension
|
||||
Complete rewrite, leveraging the new MySQL 4 / MySQL 5
|
||||
features.
|
||||
Responsibility: Georg Richter, Zak Greant
|
||||
Timeframe: ?
|
||||
|
||||
|
||||
Component: XML
|
||||
- Rewrite DOMXML and incorporate all (or most of) W3C-DOM2.
|
||||
- Use the new ZE2 features (Exceptions, setter/getter).
|
||||
- Add SAX(2), XML Schema.
|
||||
- XSLT, HTML, XPath, XPointer, DTD Validation will still be
|
||||
supported, have to find a meaningful API for it.
|
||||
- Break BC, warn users now.
|
||||
- Look at the libxml2 patch by lukas schröder and see if we can prevent
|
||||
memory leaks with it (anyway, getting rid of mem-leaks and intelligent
|
||||
memory management is on top prio...)
|
||||
- In the longer term, domxml (or another name, as with todays features
|
||||
domxml is a little bit misleading) shall be the main xml-class, which
|
||||
covers most of what's needed for decent XML support in PHP ;)
|
||||
But there is certainly place for others like Sablotron etc.
|
||||
Responsibility: Christian Stocker
|
||||
Timeframe: ?
|
||||
|
||||
|
||||
Component: Test Suite
|
||||
Extending the test suite with atleast a test for every
|
||||
function in an extension that doesn't require external
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
- clean up .cvsignores
|
||||
- purge Makefile.ins and replace PHP_EXTENSION in config.m4s
|
||||
with appropiate calls to PHP_NEW_EXTENSION
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski.
|
||||
Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+75
-127
@@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski|
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -34,7 +34,6 @@ typedef struct {
|
||||
size_t size;
|
||||
ts_allocate_ctor ctor;
|
||||
ts_allocate_dtor dtor;
|
||||
int done;
|
||||
} tsrm_resource_type;
|
||||
|
||||
|
||||
@@ -92,28 +91,12 @@ static FILE *tsrm_error_file;
|
||||
#if defined(PTHREADS)
|
||||
/* Thread local storage */
|
||||
static pthread_key_t tls_key;
|
||||
# define tsrm_tls_set(what) pthread_setspecific(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() pthread_getspecific(tls_key)
|
||||
|
||||
#elif defined(TSRM_ST)
|
||||
static int tls_key;
|
||||
# define tsrm_tls_set(what) st_thread_setspecific(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() st_thread_getspecific(tls_key)
|
||||
|
||||
#elif defined(TSRM_WIN32)
|
||||
static DWORD tls_key;
|
||||
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() TlsGetValue(tls_key)
|
||||
|
||||
#elif defined(BETHREADS)
|
||||
static int32 tls_key;
|
||||
# define tsrm_tls_set(what) tls_set(tls_key, (void*)(what))
|
||||
# define tsrm_tls_get() (tsrm_tls_entry*)tls_get(tls_key)
|
||||
|
||||
#else
|
||||
# define tsrm_tls_set(what)
|
||||
# define tsrm_tls_get() NULL
|
||||
# warning tsrm_set_interpreter_context is probably broken on this platform
|
||||
#endif
|
||||
|
||||
/* Startup TSRM (call once for the entire process) */
|
||||
@@ -174,13 +157,11 @@ TSRM_API void tsrm_shutdown(void)
|
||||
int j;
|
||||
|
||||
next_p = p->next;
|
||||
for (j=0; j<p->count; j++) {
|
||||
if (p->storage[j]) {
|
||||
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
for (j=0; j<id_count; j++) {
|
||||
if (resource_types_table && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
}
|
||||
free(p->storage);
|
||||
free(p);
|
||||
@@ -203,7 +184,6 @@ TSRM_API void tsrm_shutdown(void)
|
||||
#if defined(GNUPTH)
|
||||
pth_kill();
|
||||
#elif defined(PTHREADS)
|
||||
pthread_setspecific(tls_key, 0);
|
||||
pthread_key_delete(tls_key);
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsFree(tls_key);
|
||||
@@ -238,7 +218,6 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
|
||||
|
||||
/* enlarge the arrays for the already active threads */
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
@@ -278,29 +257,32 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
|
||||
(*thread_resources_ptr)->thread_id = thread_id;
|
||||
(*thread_resources_ptr)->next = NULL;
|
||||
|
||||
#if defined(PTHREADS)
|
||||
/* Set thread local storage to this new thread resources structure */
|
||||
tsrm_tls_set(*thread_resources_ptr);
|
||||
pthread_setspecific(tls_key, (void *) *thread_resources_ptr);
|
||||
#elif defined(TSRM_ST)
|
||||
st_thread_setspecific(tls_key, (void *) *thread_resources_ptr);
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsSetValue(tls_key, (void *) *thread_resources_ptr);
|
||||
#elif defined(BETHREADS)
|
||||
tls_set(tls_key, (void*) *thread_resources_ptr);
|
||||
#endif
|
||||
|
||||
if (tsrm_new_thread_begin_handler) {
|
||||
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
for (i=0; i<id_count; i++) {
|
||||
if (resource_types_table[i].done) {
|
||||
(*thread_resources_ptr)->storage[i] = NULL;
|
||||
} else
|
||||
{
|
||||
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
||||
if (resource_types_table[i].ctor) {
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
|
||||
}
|
||||
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
||||
if (resource_types_table[i].ctor) {
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
|
||||
}
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
if (tsrm_new_thread_end_handler) {
|
||||
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -321,13 +303,22 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
||||
if(tsrm_tls_table) {
|
||||
#endif
|
||||
if (!th_id) {
|
||||
#if defined(PTHREADS)
|
||||
/* Fast path for looking up the resources for the current
|
||||
* thread. Its used by just about every call to
|
||||
* ts_resource_ex(). This avoids the need for a mutex lock
|
||||
* and our hashtable lookup.
|
||||
*/
|
||||
thread_resources = tsrm_tls_get();
|
||||
|
||||
thread_resources = pthread_getspecific(tls_key);
|
||||
#elif defined(TSRM_ST)
|
||||
thread_resources = st_thread_getspecific(tls_key);
|
||||
#elif defined(TSRM_WIN32)
|
||||
thread_resources = TlsGetValue(tls_key);
|
||||
#elif defined(BETHREADS)
|
||||
thread_resources = (tsrm_tls_entry*)tls_get(tls_key);
|
||||
#else
|
||||
thread_resources = NULL;
|
||||
#endif
|
||||
if (thread_resources) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
|
||||
/* Read a specific resource from the thread's resources.
|
||||
@@ -378,65 +369,6 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* frees an interpreter context. You are responsible for making sure that
|
||||
* it is not linked into the TSRM hash, and not marked as the current interpreter */
|
||||
void tsrm_free_interpreter_context(void *context)
|
||||
{
|
||||
tsrm_tls_entry *next, *thread_resources = (tsrm_tls_entry*)context;
|
||||
int i;
|
||||
|
||||
while (thread_resources) {
|
||||
next = thread_resources->next;
|
||||
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
if (resource_types_table[i].dtor) {
|
||||
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
|
||||
}
|
||||
}
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
free(thread_resources->storage[i]);
|
||||
}
|
||||
free(thread_resources->storage);
|
||||
free(thread_resources);
|
||||
thread_resources = next;
|
||||
}
|
||||
}
|
||||
|
||||
void *tsrm_set_interpreter_context(void *new_ctx)
|
||||
{
|
||||
tsrm_tls_entry *current;
|
||||
|
||||
current = tsrm_tls_get();
|
||||
|
||||
/* TODO: unlink current from the global linked list, and replace it
|
||||
* it with the new context, protected by mutex where/if appropriate */
|
||||
|
||||
/* Set thread local storage to this new thread resources structure */
|
||||
tsrm_tls_set(new_ctx);
|
||||
|
||||
/* return old context, so caller can restore it when they're done */
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
/* allocates a new interpreter context */
|
||||
void *tsrm_new_interpreter_context(void)
|
||||
{
|
||||
tsrm_tls_entry *new_ctx, *current;
|
||||
THREAD_T thread_id;
|
||||
|
||||
thread_id = tsrm_thread_id();
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
current = tsrm_tls_get();
|
||||
|
||||
allocate_new_resource(&new_ctx, thread_id);
|
||||
|
||||
/* switch back to the context that was in use prior to our creation
|
||||
* of the new one */
|
||||
return tsrm_set_interpreter_context(current);
|
||||
}
|
||||
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
void ts_free_thread(void)
|
||||
@@ -467,7 +399,11 @@ void ts_free_thread(void)
|
||||
} else {
|
||||
tsrm_tls_table[hash_value] = thread_resources->next;
|
||||
}
|
||||
tsrm_tls_set(0);
|
||||
#if defined(PTHREADS)
|
||||
pthread_setspecific(tls_key, 0);
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsSetValue(tls_key, 0);
|
||||
#endif
|
||||
free(thread_resources);
|
||||
break;
|
||||
}
|
||||
@@ -483,34 +419,6 @@ void ts_free_thread(void)
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{
|
||||
int i;
|
||||
int j = TSRM_UNSHUFFLE_RSRC_ID(id);
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Freeing resource id %d", id));
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count > j && p->storage[j]) {
|
||||
if (resource_types_table && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
p->storage[j] = NULL;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
resource_types_table[j].done = 1;
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
||||
}
|
||||
|
||||
|
||||
@@ -525,6 +433,13 @@ TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
{
|
||||
#ifdef TSRM_WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(NETWARE)
|
||||
/* There seems to be some problem with the LibC call: NXThreadGetId().
|
||||
* Due to this, the PHPMyAdmin application is abending in PHP calls.
|
||||
* Used the call, kCurrentThread instead and it works fine.
|
||||
*/
|
||||
/* return NXThreadGetId(); */
|
||||
return kCurrentThread();
|
||||
#elif defined(GNUPTH)
|
||||
return pth_self();
|
||||
#elif defined(PTHREADS)
|
||||
@@ -545,9 +460,24 @@ TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
#ifdef NETWARE
|
||||
#ifndef USE_MPK
|
||||
/* To use the Recursive Mutex Locking of LibC */
|
||||
long flags = NX_MUTEX_RECURSIVE;
|
||||
NXHierarchy_t order = 0;
|
||||
NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
#ifdef USE_MPK
|
||||
mutexp = kMutexAlloc((BYTE*)"PHP-TSRM");
|
||||
#else
|
||||
mutexp = NXMutexAlloc(flags, order, &lockInfo);
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
||||
pth_mutex_init(mutexp);
|
||||
@@ -579,6 +509,12 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
DeleteCriticalSection(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
#ifdef USE_MPK
|
||||
kMutexFree(mutexp);
|
||||
#else
|
||||
NXMutexFree(mutexp);
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
free(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
@@ -608,6 +544,12 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
EnterCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
#ifdef USE_MPK
|
||||
return kMutexLock(mutexp);
|
||||
#else
|
||||
return NXLock(mutexp);
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_acquire(mutexp, 0, NULL);
|
||||
#elif defined(PTHREADS)
|
||||
@@ -633,6 +575,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
#ifdef TSRM_WIN32
|
||||
LeaveCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
#ifdef USE_MPK
|
||||
return kMutexUnlock(mutexp);
|
||||
#else
|
||||
return NXUnlock(mutexp);
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_release(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
|
||||
+18
-11
@@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999-2006, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
||||
| Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski|
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -14,8 +14,8 @@
|
||||
#define TSRM_H
|
||||
|
||||
/* #ifndef WIN32 */
|
||||
#ifndef WIN32
|
||||
# include <tsrm_config.h>
|
||||
#if !defined(WIN32) && !defined(NETWARE)
|
||||
# include "tsrm_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -41,7 +41,13 @@
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <shellapi.h>
|
||||
#elif defined(NETWARE)
|
||||
# include <nks/thread.h>
|
||||
#ifdef USE_MPK
|
||||
# include <mpklib4php.h>
|
||||
#else
|
||||
# include <nks/synch.h>
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
# include <pth.h>
|
||||
#elif defined(PTHREADS)
|
||||
@@ -59,6 +65,13 @@ typedef int ts_rsrc_id;
|
||||
#ifdef TSRM_WIN32
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T CRITICAL_SECTION *
|
||||
#elif defined(NETWARE)
|
||||
# define THREAD_T NXThreadId_t
|
||||
#ifdef USE_MPK
|
||||
# define MUTEX_T MUTEX
|
||||
#else
|
||||
# define MUTEX_T NXMutex_t *
|
||||
#endif
|
||||
#elif defined(GNUPTH)
|
||||
# define THREAD_T pth_t
|
||||
# define MUTEX_T pth_mutex_t *
|
||||
@@ -132,18 +145,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
|
||||
|
||||
/* these 3 APIs should only be used by people that fully understand the threading model
|
||||
* used by PHP/Zend and the selected SAPI. */
|
||||
TSRM_API void *tsrm_new_interpreter_context(void);
|
||||
TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
|
||||
TSRM_API void tsrm_free_interpreter_context(void *context);
|
||||
|
||||
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
||||
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
|
||||
|
||||
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
|
||||
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
|
||||
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
|
||||
#define TSRMLS_SET_CTX(ctx) (void ***) ctx = tsrm_ls
|
||||
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
#define TSRMLS_D void ***tsrm_ls
|
||||
#define TSRMLS_DC , TSRMLS_D
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// vim:ft=javascript
|
||||
// $Id$
|
||||
|
||||
if (CHECK_HEADER_ADD_INCLUDE("NewAPIs.h", "CFLAGS_PHP", php_usual_include_suspects)) {
|
||||
// Need to add the flag directly, since TSRM doesn't include the config
|
||||
// header
|
||||
ADD_FLAG("CFLAGS_PHP", "/DHAVE_NEWAPIS_H=1");
|
||||
}
|
||||
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
|
||||
|
||||
+5
-13
@@ -30,7 +30,7 @@ dnl PTHREADS_FLAGS
|
||||
dnl
|
||||
dnl Set some magic defines to achieve POSIX threads conformance
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_FLAGS],[
|
||||
AC_DEFUN(PTHREADS_FLAGS,[
|
||||
if test -z "$host_alias" && test -n "$host"; then
|
||||
host_alias=$host
|
||||
fi
|
||||
@@ -65,7 +65,7 @@ dnl PTHREADS_CHECK_COMPILE
|
||||
dnl
|
||||
dnl Check whether the current setup can use POSIX threads calls
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK_COMPILE], [
|
||||
AC_DEFUN(PTHREADS_CHECK_COMPILE, [
|
||||
AC_TRY_RUN( [
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
@@ -84,15 +84,7 @@ int main() {
|
||||
pthreads_working=yes
|
||||
], [
|
||||
pthreads_working=no
|
||||
], [
|
||||
dnl For cross compiling running this test is of no use. NetWare supports pthreads
|
||||
pthreads_working=no
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
pthreads_working=yes
|
||||
esac
|
||||
]
|
||||
) ] )dnl
|
||||
], pthreads_working=no ) ] )dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK()
|
||||
dnl
|
||||
@@ -108,7 +100,7 @@ dnl -pthreads gcc (Solaris)
|
||||
dnl -qthreaded AIX cc V5
|
||||
dnl -threads gcc (HP-UX)
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK],[
|
||||
AC_DEFUN(PTHREADS_CHECK,[
|
||||
|
||||
if test "$beos_threads" = "1"; then
|
||||
pthreads_working="yes"
|
||||
@@ -162,7 +154,7 @@ fi
|
||||
])dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_ASSIGN_VARS],[
|
||||
AC_DEFUN(PTHREADS_ASSIGN_VARS,[
|
||||
if test -n "$ac_cv_pthreads_lib"; then
|
||||
LIBS="$LIBS -l$ac_cv_pthreads_lib"
|
||||
fi
|
||||
|
||||
+8
-9
@@ -1,6 +1,6 @@
|
||||
|
||||
dnl TSRM_CHECK_GCC_ARG(ARG, ACTION-IF-FOUND, ACTION-IF-NOT_FOUND)
|
||||
AC_DEFUN([TSRM_CHECK_GCC_ARG],[
|
||||
AC_DEFUN(TSRM_CHECK_GCC_ARG,[
|
||||
gcc_arg_name=[ac_cv_gcc_arg]translit($1,A-Z-,a-z_)
|
||||
AC_CACHE_CHECK([whether $CC supports $1], [ac_cv_gcc_arg]translit($1,A-Z-,a-z_), [
|
||||
echo 'void somefunc() { };' > conftest.c
|
||||
@@ -21,7 +21,7 @@ AC_DEFUN([TSRM_CHECK_GCC_ARG],[
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_BASIC_CHECKS],[
|
||||
AC_DEFUN(TSRM_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
dnl AC_REQUIRE([AM_PROG_CC_STDC])dnl
|
||||
@@ -33,7 +33,7 @@ AC_CHECK_HEADERS(stdarg.h)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_PTH],[
|
||||
AC_DEFUN(TSRM_CHECK_PTH,[
|
||||
|
||||
AC_MSG_CHECKING(for GNU Pth)
|
||||
PTH_PREFIX="`$1 --prefix`"
|
||||
@@ -50,7 +50,7 @@ AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_ST],[
|
||||
AC_DEFUN(TSRM_CHECK_ST,[
|
||||
if test -r "$1/include/st.h"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$1/include"
|
||||
LDFLAGS="$LDFLAGS -L$1/lib"
|
||||
@@ -70,7 +70,7 @@ AC_DEFUN([TSRM_CHECK_ST],[
|
||||
sinclude(threads.m4)
|
||||
sinclude(TSRM/threads.m4)
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_PTHREADS],[
|
||||
AC_DEFUN(TSRM_CHECK_PTHREADS,[
|
||||
|
||||
PTHREADS_CHECK
|
||||
|
||||
@@ -89,21 +89,20 @@ fi
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_THREADS_CHECKS],[
|
||||
AC_DEFUN(TSRM_THREADS_CHECKS,[
|
||||
|
||||
dnl For the thread implementations, we always use --with-*
|
||||
dnl to maintain consistency
|
||||
|
||||
AC_ARG_WITH(tsrm-pth,
|
||||
[ --with-tsrm-pth[=pth-config]
|
||||
Use GNU Pth],[
|
||||
[ --with-tsrm-pth[=pth-config] Use GNU Pth.],[
|
||||
TSRM_PTH=$withval
|
||||
],[
|
||||
TSRM_PTH=no
|
||||
])
|
||||
|
||||
AC_ARG_WITH(tsrm-st,
|
||||
[ --with-tsrm-st Use SGI's State Threads],[
|
||||
[ --with-tsrm-st],[
|
||||
TSRM_ST=$withval
|
||||
],[
|
||||
TSRM_ST=no
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef TSRM_CONFIG_NW_H
|
||||
#define TSRM_CONFIG_NW_H
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Though we have alloca(), this seems to be causing some problem
|
||||
* with the stack pointer. Hence not using it
|
||||
*/
|
||||
/*#define HAVE_ALLOCA 1*/
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_ALLOCA 1
|
||||
#define HAVE_REALPATH 1
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include "tsrm_config.w32.h"
|
||||
#elif defined(NETWARE)
|
||||
# include "tsrm_config.nw.h"
|
||||
#else
|
||||
# include <tsrm_config.h>
|
||||
# include "tsrm_config.h"
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
@@ -20,7 +22,7 @@
|
||||
#ifndef __GNUC__
|
||||
# ifndef HAVE_ALLOCA_H
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# ifndef NETWARE
|
||||
@@ -42,8 +44,6 @@ char *alloca ();
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# elif defined(MAX_PATH)
|
||||
# define MAXPATHLEN MAX_PATH
|
||||
# else
|
||||
# define MAXPATHLEN 256
|
||||
# endif
|
||||
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
|
||||
+4
-4
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
|
||||
+63
-256
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tsrm_virtual_cwd.h"
|
||||
#include "tsrm_strtok_r.h"
|
||||
@@ -35,15 +34,11 @@
|
||||
#ifdef TSRM_WIN32
|
||||
#include <io.h>
|
||||
#include "tsrm_win32.h"
|
||||
# if HAVE_NEWAPIS_H
|
||||
# define WANT_GETLONGPATHNAME_WRAPPER
|
||||
# define COMPILE_NEWAPIS_STUBS
|
||||
# include <NewAPIs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
#include <fsio.h>
|
||||
/*#include "pipe.h"*/
|
||||
#include "tsrm_nw.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_REALPATH
|
||||
@@ -60,9 +55,9 @@ MUTEX_T cwd_mutex;
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
ts_rsrc_id cwd_globals_id;
|
||||
static ts_rsrc_id cwd_globals_id;
|
||||
#else
|
||||
virtual_cwd_globals cwd_globals;
|
||||
static virtual_cwd_globals cwd_globals;
|
||||
#endif
|
||||
|
||||
cwd_state main_cwd_state; /* True global */
|
||||
@@ -142,9 +137,15 @@ static int php_check_dots(const char *element, int n)
|
||||
|
||||
static int php_is_dir_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
@@ -152,9 +153,15 @@ static int php_is_dir_ok(const cwd_state *state)
|
||||
|
||||
static int php_is_file_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
@@ -163,27 +170,11 @@ static int php_is_file_ok(const cwd_state *state)
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
|
||||
cwd_globals->realpath_cache_size = 0;
|
||||
cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
|
||||
cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL;
|
||||
memset(cwd_globals->realpath_cache, 0, sizeof(cwd_globals->realpath_cache));
|
||||
}
|
||||
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_FREE(&cwd_globals->cwd);
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(cwd_globals->realpath_cache)/sizeof(cwd_globals->realpath_cache[0]); i++) {
|
||||
realpath_cache_bucket *p = cwd_globals->realpath_cache[i];
|
||||
while (p != NULL) {
|
||||
realpath_cache_bucket *r = p;
|
||||
p = p->next;
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *tsrm_strndup(const char *s, size_t length)
|
||||
@@ -206,20 +197,7 @@ CWD_API void virtual_cwd_startup(void)
|
||||
char cwd[MAXPATHLEN];
|
||||
char *result;
|
||||
|
||||
#ifdef NETWARE
|
||||
result = getcwdpath(cwd, NULL, 1);
|
||||
if(result)
|
||||
{
|
||||
char *c=cwd;
|
||||
while(c = strchr(c, '\\'))
|
||||
{
|
||||
*c='/';
|
||||
++c;
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
#endif
|
||||
if (!result) {
|
||||
cwd[0] = '\0';
|
||||
}
|
||||
@@ -304,63 +282,6 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline unsigned long realpath_cache_key(const char *path, int path_len)
|
||||
{
|
||||
register unsigned long h;
|
||||
|
||||
const char *e = path + path_len;
|
||||
for (h = 2166136261U; path < e; ) {
|
||||
h *= 16777619;
|
||||
h ^= *path++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, int realpath_len, time_t t TSRMLS_DC)
|
||||
{
|
||||
long size = sizeof(realpath_cache_bucket) + path_len + 1 + realpath_len + 1;
|
||||
if (CWDG(realpath_cache_size) + size <= CWDG(realpath_cache_size_limit)) {
|
||||
realpath_cache_bucket *bucket = malloc(size);
|
||||
unsigned long n;
|
||||
|
||||
bucket->key = realpath_cache_key(path, path_len);
|
||||
bucket->path = (char*)bucket + sizeof(realpath_cache_bucket);
|
||||
memcpy(bucket->path, path, path_len+1);
|
||||
bucket->path_len = path_len;
|
||||
bucket->realpath = bucket->path + (path_len + 1);
|
||||
memcpy(bucket->realpath, realpath, realpath_len+1);
|
||||
bucket->realpath_len = realpath_len;
|
||||
bucket->expires = t + CWDG(realpath_cache_ttl);
|
||||
n = bucket->key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
|
||||
bucket->next = CWDG(realpath_cache)[n];
|
||||
CWDG(realpath_cache)[n] = bucket;
|
||||
CWDG(realpath_cache_size) += size;
|
||||
}
|
||||
}
|
||||
|
||||
static inline realpath_cache_bucket* realpath_cache_find(const char *path, int path_len, time_t t TSRMLS_DC)
|
||||
{
|
||||
unsigned long key = realpath_cache_key(path, path_len);
|
||||
unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0]));
|
||||
realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n];
|
||||
|
||||
while (*bucket != NULL) {
|
||||
if (CWDG(realpath_cache_ttl) && (*bucket)->expires < t) {
|
||||
realpath_cache_bucket *r = *bucket;
|
||||
*bucket = (*bucket)->next;
|
||||
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1;
|
||||
free(r);
|
||||
} else if (key == (*bucket)->key && path_len == (*bucket)->path_len &&
|
||||
memcmp(path, (*bucket)->path, path_len) == 0) {
|
||||
return *bucket;
|
||||
} else {
|
||||
bucket = &(*bucket)->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Resolve path relatively to state and put the real path into state */
|
||||
/* returns 0 for ok, 1 for error */
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath)
|
||||
@@ -369,71 +290,26 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
char *ptr, *path_copy;
|
||||
char *tok = NULL;
|
||||
int ptr_length;
|
||||
cwd_state old_state;
|
||||
cwd_state *old_state;
|
||||
int ret = 0;
|
||||
int copy_amount = -1;
|
||||
char *free_path;
|
||||
unsigned char is_absolute = 0;
|
||||
#ifndef TSRM_WIN32
|
||||
char resolved_path[MAXPATHLEN];
|
||||
#else
|
||||
char *new_path;
|
||||
#endif
|
||||
char orig_path[MAXPATHLEN];
|
||||
int orig_path_len;
|
||||
realpath_cache_bucket *bucket;
|
||||
time_t t;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (path_length == 0)
|
||||
return (0);
|
||||
if (path_length >= MAXPATHLEN)
|
||||
return (1);
|
||||
|
||||
if (use_realpath && CWDG(realpath_cache_size_limit)) {
|
||||
if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
|
||||
memcpy(orig_path, path, path_length+1);
|
||||
orig_path_len = path_length;
|
||||
} else {
|
||||
orig_path_len = path_length + state->cwd_length + 1;
|
||||
if (orig_path_len >= MAXPATHLEN) {
|
||||
return 1;
|
||||
}
|
||||
memcpy(orig_path, state->cwd, state->cwd_length);
|
||||
orig_path[state->cwd_length] = DEFAULT_SLASH;
|
||||
memcpy(orig_path + state->cwd_length + 1, path, path_length + 1);
|
||||
}
|
||||
t = CWDG(realpath_cache_ttl)?time(NULL):0;
|
||||
if ((bucket = realpath_cache_find(orig_path, orig_path_len, t TSRMLS_CC)) != NULL) {
|
||||
int len = bucket->realpath_len;
|
||||
|
||||
CWD_STATE_COPY(&old_state, state);
|
||||
state->cwd = (char *) realloc(state->cwd, len+1);
|
||||
memcpy(state->cwd, bucket->realpath, len+1);
|
||||
state->cwd_length = len;
|
||||
if (verify_path && verify_path(state)) {
|
||||
CWD_STATE_FREE(state);
|
||||
*state = old_state;
|
||||
return 1;
|
||||
} else {
|
||||
CWD_STATE_FREE(&old_state);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
/* cwd_length can be 0 when getcwd() fails.
|
||||
* This can happen under solaris when a dir does not have read permissions
|
||||
* but *does* have execute permissions */
|
||||
if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
|
||||
if (use_realpath) {
|
||||
if (realpath(path, resolved_path)) { /* Note: Not threadsafe on older *BSD's */
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
} else {
|
||||
/* disable for now
|
||||
return 1; */
|
||||
}
|
||||
if (use_realpath && realpath(path, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
}
|
||||
} else { /* Concat current directory with relative path and then run realpath() on it */
|
||||
char *tmp;
|
||||
@@ -449,51 +325,17 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
memcpy(ptr, path, path_length);
|
||||
ptr += path_length;
|
||||
*ptr = '\0';
|
||||
if (strlen(tmp) >= MAXPATHLEN) {
|
||||
free(tmp);
|
||||
return 1;
|
||||
}
|
||||
if (use_realpath) {
|
||||
if (realpath(tmp, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
} else {
|
||||
/* disable for now
|
||||
free(tmp);
|
||||
return 1; */
|
||||
}
|
||||
if (use_realpath && realpath(tmp, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
#if defined(TSRM_WIN32)
|
||||
{
|
||||
int new_path_length;
|
||||
|
||||
new_path_length = GetLongPathName(path, NULL, 0);
|
||||
if (new_path_length == 0) {
|
||||
goto php_failed_getlongpath;
|
||||
}
|
||||
|
||||
/* GetLongPathName already counts the \0 */
|
||||
new_path = (char *) malloc(new_path_length);
|
||||
if (!new_path) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GetLongPathName(path, new_path, new_path_length) != 0) {
|
||||
path = new_path;
|
||||
path_length = new_path_length;
|
||||
} else {
|
||||
free(new_path);
|
||||
php_failed_getlongpath:
|
||||
new_path = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
free_path = path_copy = tsrm_strndup(path, path_length);
|
||||
|
||||
CWD_STATE_COPY(&old_state, state);
|
||||
old_state = (cwd_state *) malloc(sizeof(cwd_state));
|
||||
CWD_STATE_COPY(old_state, state);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
|
||||
#endif
|
||||
@@ -513,7 +355,7 @@ php_failed_getlongpath:
|
||||
memcpy(state->cwd, path_copy, copy_amount);
|
||||
path_copy += copy_amount;
|
||||
} else {
|
||||
memcpy(state->cwd, old_state.cwd, copy_amount);
|
||||
memcpy(state->cwd, old_state->cwd, copy_amount);
|
||||
}
|
||||
}
|
||||
state->cwd[copy_amount] = '\0';
|
||||
@@ -556,19 +398,8 @@ php_failed_getlongpath:
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#elif defined(NETWARE)
|
||||
/*
|
||||
Below code keeps appending to state->cwd a File system seperator
|
||||
cases where this appending should not happen is given below,
|
||||
a) sys: should just be left as it is
|
||||
b) sys:system should just be left as it is,
|
||||
Colon is allowed only in the first token as volume names alone can have the : in their names.
|
||||
Files and Directories cannot have : in their names
|
||||
So the check goes like this,
|
||||
For second token and above simply append the DEFAULT_SLASH to the state->cwd.
|
||||
For first token check for the existence of :
|
||||
if it exists don't append the DEFAULT_SLASH to the state->cwd.
|
||||
*/
|
||||
if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
|
||||
/* If the token is a volume name, it will have colon at the end -- so, no slash before it */
|
||||
if (ptr[ptr_length-1] != ':') {
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#else
|
||||
@@ -592,26 +423,20 @@ php_failed_getlongpath:
|
||||
state->cwd_length = path_length;
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
if (new_path) {
|
||||
free(new_path);
|
||||
}
|
||||
#endif
|
||||
free(free_path);
|
||||
|
||||
if (use_realpath && CWDG(realpath_cache_size_limit)) {
|
||||
realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (verify_path && verify_path(state)) {
|
||||
CWD_STATE_FREE(state);
|
||||
*state = old_state;
|
||||
|
||||
*state = *old_state;
|
||||
|
||||
ret = 1;
|
||||
} else {
|
||||
CWD_STATE_FREE(&old_state);
|
||||
CWD_STATE_FREE(old_state);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
free(old_state);
|
||||
|
||||
free(free_path);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
|
||||
#endif
|
||||
@@ -765,7 +590,7 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
|
||||
}
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int ret;
|
||||
@@ -773,15 +598,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, filename, NULL, 0);
|
||||
|
||||
if (link) {
|
||||
#if HAVE_LCHOWN
|
||||
ret = lchown(new_state.cwd, owner, group);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
} else {
|
||||
ret = chown(new_state.cwd, owner, group);
|
||||
}
|
||||
ret = chown(new_state.cwd, owner, group);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return ret;
|
||||
@@ -848,23 +665,37 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
if (virtual_file_ex(&new_state, path, NULL, 1)) {
|
||||
return -1;
|
||||
}
|
||||
virtual_file_ex(&new_state, path, NULL, 1);
|
||||
|
||||
retval = stat(new_state.cwd, buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
#if !defined(TSRM_WIN32)
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL, 1);
|
||||
|
||||
retval = stat(new_state.cwd, (struct stat*)buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
@@ -986,24 +817,13 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
|
||||
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
|
||||
{
|
||||
int command_length;
|
||||
int dir_length, extra = 0;
|
||||
char *command_line;
|
||||
char *ptr, *dir;
|
||||
char *ptr;
|
||||
FILE *retval;
|
||||
|
||||
command_length = strlen(command);
|
||||
|
||||
dir_length = CWDG(cwd).cwd_length;
|
||||
dir = CWDG(cwd).cwd;
|
||||
while (dir_length > 0) {
|
||||
if (*dir == '\'') extra+=3;
|
||||
dir++;
|
||||
dir_length--;
|
||||
}
|
||||
dir_length = CWDG(cwd).cwd_length;
|
||||
dir = CWDG(cwd).cwd;
|
||||
|
||||
ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1);
|
||||
ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1);
|
||||
if (!command_line) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1013,21 +833,8 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
|
||||
if (CWDG(cwd).cwd_length == 0) {
|
||||
*ptr++ = DEFAULT_SLASH;
|
||||
} else {
|
||||
*ptr++ = '\'';
|
||||
while (dir_length > 0) {
|
||||
switch (*dir) {
|
||||
case '\'':
|
||||
*ptr++ = '\'';
|
||||
*ptr++ = '\\';
|
||||
*ptr++ = '\'';
|
||||
/* fall-through */
|
||||
default:
|
||||
*ptr++ = *dir;
|
||||
}
|
||||
dir++;
|
||||
dir_length--;
|
||||
}
|
||||
*ptr++ = '\'';
|
||||
memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length);
|
||||
ptr += CWDG(cwd).cwd_length;
|
||||
}
|
||||
|
||||
*ptr++ = ' ';
|
||||
|
||||
+15
-58
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
@@ -41,10 +41,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__osf__) || defined(_AIX)
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include "readdir.h"
|
||||
#include <sys/utime.h>
|
||||
@@ -74,9 +70,10 @@ typedef unsigned short mode_t;
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
#define IS_SLASH_P(c) IS_SLASH(*(c))
|
||||
/* Colon indicates volume name, either first character should be forward slash or backward slash */
|
||||
#define COPY_WHEN_ABSOLUTE(path) \
|
||||
(strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
|
||||
(strchr(path, ':') != NULL) /* Colon indicates volume name */
|
||||
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
@@ -140,8 +137,12 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
|
||||
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#if !defined(TSRM_WIN32)
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC);
|
||||
#endif
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#endif
|
||||
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
|
||||
@@ -166,61 +167,23 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* On AIX & Tru64 when a file does not exist realpath() returns
|
||||
* NULL, and sets errno to ENOENT. Unlike in other libc implementations
|
||||
* the destination is not filled and remains undefined. Therefor, we
|
||||
* must populate it manually using strcpy as done on systems with no
|
||||
* realpath() function.
|
||||
*/
|
||||
#if defined(__osf__) || defined(_AIX)
|
||||
static char *php_realpath_hack(char *src, char *dest)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if ((ret = realpath(src, dest)) == NULL && errno == ENOENT) {
|
||||
return strcpy(dest, src);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_UTIME
|
||||
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
|
||||
#endif
|
||||
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC);
|
||||
#endif
|
||||
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
|
||||
|
||||
#define REALPATH_CACHE_TTL (2*60) /* 2 minutes */
|
||||
#define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */
|
||||
|
||||
typedef struct _realpath_cache_bucket {
|
||||
unsigned long key;
|
||||
char *path;
|
||||
int path_len;
|
||||
char *realpath;
|
||||
int realpath_len;
|
||||
time_t expires;
|
||||
struct _realpath_cache_bucket *next;
|
||||
} realpath_cache_bucket;
|
||||
|
||||
typedef struct _virtual_cwd_globals {
|
||||
cwd_state cwd;
|
||||
long realpath_cache_size;
|
||||
long realpath_cache_size_limit;
|
||||
long realpath_cache_ttl;
|
||||
realpath_cache_bucket *realpath_cache[1024];
|
||||
} virtual_cwd_globals;
|
||||
|
||||
#ifdef ZTS
|
||||
extern ts_rsrc_id cwd_globals_id;
|
||||
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
|
||||
#else
|
||||
extern virtual_cwd_globals cwd_globals;
|
||||
# define CWDG(v) (cwd_globals.v)
|
||||
#endif
|
||||
|
||||
@@ -243,7 +206,7 @@ extern virtual_cwd_globals cwd_globals;
|
||||
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
|
||||
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
|
||||
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#endif
|
||||
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
|
||||
@@ -257,8 +220,7 @@ extern virtual_cwd_globals cwd_globals;
|
||||
#endif
|
||||
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
|
||||
#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
|
||||
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group TSRMLS_CC)
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -286,11 +248,7 @@ extern virtual_cwd_globals cwd_globals;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REALPATH
|
||||
#if defined(__osf__) || defined(_AIX)
|
||||
#define VCWD_REALPATH(path, real_path) php_realpath_hack(path, real_path)
|
||||
#else
|
||||
#define VCWD_REALPATH(path, real_path) realpath(path, real_path)
|
||||
#endif
|
||||
#else
|
||||
#define VCWD_REALPATH(path, real_path) strcpy(real_path, path)
|
||||
#endif
|
||||
@@ -301,7 +259,6 @@ extern virtual_cwd_globals cwd_globals;
|
||||
#define VCWD_CHMOD(path, mode) chmod(path, mode)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
|
||||
#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+4
-15
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
|
||||
#include "tsrm_win32.h"
|
||||
|
||||
#ifdef ZTS
|
||||
@@ -375,14 +374,4 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
TSRM_API char *realpath(char *orig_path, char *buffer)
|
||||
{
|
||||
int ret = GetFullPathName(orig_path, _MAX_PATH, buffer, NULL);
|
||||
if(!ret || ret > _MAX_PATH) {
|
||||
return NULL;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
-6
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
@@ -102,5 +102,4 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags);
|
||||
TSRM_API int shmdt(const void *shmaddr);
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
|
||||
|
||||
TSRM_API char *realpath(char *orig_path, char *buffer);
|
||||
#endif
|
||||
#endif
|
||||
+2
-11184
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The Zend Engine License, Version 2.00
|
||||
Copyright (c) 1999-2006 Zend Technologies Ltd. All rights reserved.
|
||||
Copyright (c) 1999-2003 Zend Technologies Ltd. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+1
-3
@@ -15,9 +15,7 @@ libZend_la_SOURCES=\
|
||||
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
|
||||
zend_ini.c zend_qsort.c zend_objects.c zend_object_handlers.c \
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c zend_mm.c \
|
||||
zend_default_classes.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_strtod.c zend_strtol.c
|
||||
zend_default_classes.c zend_reflection_api.c
|
||||
|
||||
libZend_la_LDFLAGS =
|
||||
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h $(srcdir)/zend_vm_opcodes.h
|
||||
+1
-1
@@ -51,7 +51,7 @@ write_property is used to directly write object's property by
|
||||
name. This handler is used to assign property variables or to change them
|
||||
in operations like += or ++ (unless get_property_zval_ptr is also set).
|
||||
|
||||
get_property_zval_ptr is used to obtain pointer to modifiable zval for
|
||||
get_property_zval_ptr is used to obtain pointer to modifyable zval for
|
||||
operations like += or ++. This should be used only if your object model
|
||||
stores properties as real zval's that can be modified from outside.
|
||||
Otherwise this handler should be NULL and the engine will use
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
ZEND_VM
|
||||
=======
|
||||
|
||||
ZEND_VM architecture allows specializing opcode handlers according to op_type
|
||||
fields and using different execution methods (call threading, switch threading
|
||||
and direct threading). As a result ZE2 got more than 20% speedup on raw PHP
|
||||
code execution (with specialized executor and direct threading execution
|
||||
method). As in most PHP applications raw execution speed isn't the limiting
|
||||
factor but system calls and database callls are, your mileage with this patch
|
||||
will vary.
|
||||
|
||||
Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can
|
||||
find opcode handlers and helpers. The typical opcode handler template looks
|
||||
like this:
|
||||
|
||||
ZEND_VM_HANDLER(<OPCODE-NUMBER>, <OPCODE>, <OP1_TYPES>, <OP2_TYPES>)
|
||||
{
|
||||
<HANDLER'S CODE>
|
||||
}
|
||||
|
||||
<OPCODE-NUMBER> is a opcode number (0, 1, ...)
|
||||
<OPCODE> is an opcode name (ZEN_NOP, ZEND_ADD, :)
|
||||
<OP1_TYPES> & <OP2_TYPES> are masks for allowed operand op_types. Specializer
|
||||
will generate code only for defined combination of types. You can use any
|
||||
combination of the following op_types UNUSED, CONST, VAR, TMP and CV also
|
||||
you can use ANY mask to disable specialization according operand's op_type.
|
||||
<HANDLER'S CODE> is a handler's code itself. For most handlers it stills the
|
||||
same as in old zend_execute.c, but now it uses macros to access opcode operands
|
||||
and some internal executor data.
|
||||
|
||||
You can see the conformity of new macros to old code in the following list:
|
||||
|
||||
EXECUTE_DATA
|
||||
execute_data
|
||||
ZEND_VM_DISPATCH_TO_HANDLER(<OP>)
|
||||
return <OP>_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_DISPATCH_TO_HELPER(<NAME>)
|
||||
return <NAME>(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_DISPATCH_TO_HELPER_EX(<NAME>,<PARAM>,<VAL>)
|
||||
return <NAME>(<VAL>, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
ZEND_VM_CONTINUE()
|
||||
return 0
|
||||
ZEND_VM_NEXT_OPCODE()
|
||||
NEXT_OPCODE()
|
||||
ZEND_VM_SET_OPCODE(<TARGET>
|
||||
SET_OPCODE(<TARGET>
|
||||
ZEND_VM_INC_OPCODE()
|
||||
INC_OPCOD()
|
||||
ZEND_VM_RETURN_FROM_EXECUTE_LOOP()
|
||||
RETURN_FROM_EXECUTE_LOOP()
|
||||
ZEND_VM_C_LABEL(<LABEL>):
|
||||
<LABEL>:
|
||||
ZEND_VM_C_GOTO(<LABEL>)
|
||||
goto <LABEL>
|
||||
OP<X>_TYPE
|
||||
opline->op<X>.op_type
|
||||
GET_OP<X>_ZVAL_PTR(<TYPE>)
|
||||
get_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_ZVAL_PTR_PTR(<TYPE>)
|
||||
get_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_OBJ_ZVAL_PTR(<TYPE>)
|
||||
get_obj_zval_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
GET_OP<X>_OBJ_ZVAL_PTR_PTR(<TYPE>)
|
||||
get_obj_zval_ptr_ptr(&opline->op<X>, EX(Ts), &free_op<X>, <TYPE>)
|
||||
IS_OP<X>_TMP_FREE()
|
||||
IS_TMP_FREE(free_op<X>)
|
||||
FREE_OP<X>()
|
||||
FREE_OP(free_op<X>)
|
||||
FREE_OP<X>_IF_VAR()
|
||||
FREE_VAR(free_op<X>)
|
||||
FREE_OP<X>_VAR_PTR()
|
||||
FREE_VAR_PTR(free_op<X>)
|
||||
|
||||
|
||||
Executor's helpers can be defined without parameters or with one parameter.
|
||||
This is done with the following constructs:
|
||||
|
||||
ZEND_VM_HELPER(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>)
|
||||
{
|
||||
<HELPER'S CODE>
|
||||
}
|
||||
|
||||
ZEND_VM_HELPER_EX(<HELPER-NAME>, <OP1_TYPES>, <OP2_TYPES>, <PARAM_SPEC>)
|
||||
{
|
||||
<HELPER'S CODE>
|
||||
}
|
||||
|
||||
Executor's code is generated by PHP script zend_vm_gen.php it uses zend_vm_def.h
|
||||
and zend_vm_execute.skl as input and produces zend_vm_opcodes.h and
|
||||
zend_vm_execute.h. The first file is a list of opcode definitions. It is
|
||||
included from zend_compile.h. The second one is an executor code itself. It is
|
||||
included from zend_execute.c.
|
||||
|
||||
zend_vm_gen.php can produce different kind of executors. You can select
|
||||
different opcode threading model using --with-vm-kind=CALL|SWITCH|GOTO. You can
|
||||
disable opcode specialization using --without-specializer. You can include or
|
||||
exclude old executor together with specialized one using --without-old-executor.
|
||||
At last you can debug executor using original zend_vm_def.h or generated file
|
||||
zend_vm_execute.h. Debugging with original file requires --with-lines
|
||||
option. By default ZE2 uses the following command to generate executor:
|
||||
|
||||
$ php zend_vm_gen.php --with-vm-kind=CALL
|
||||
|
||||
Zend Engine II currently includes two executors during the build process, one
|
||||
is the specialized version and the other is the old one non-specialized with
|
||||
function handlers. By default Zend Engine II uses the specialized one but you
|
||||
can switch to the old executor at runtime by calling zend_vm_use_old_executor().
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
Title: Zend 2.0 Namespaces
|
||||
Version: $Revision$
|
||||
Status: declined
|
||||
Status: draft
|
||||
Maintainer: Stig S. Bakken <ssb@php.net>
|
||||
Created: 2001-09-08
|
||||
Modified: 2001-09-08
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
Title: Delegation
|
||||
(a/k/a. Object-Based Inheritance)
|
||||
Version: $Revision$
|
||||
Status: draft
|
||||
Maintainer: Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
|
||||
|
||||
Dynamic Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class aDelegatee {
|
||||
function doSomething() {
|
||||
echo 'hubu';
|
||||
}
|
||||
}
|
||||
|
||||
class anotherDelegatee {
|
||||
function doSomething() {
|
||||
echo 'tubu';
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
delegatee $bar;
|
||||
|
||||
function setDelegatee($delegatee) {
|
||||
$this->delegatee = $delegatee;
|
||||
}
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
|
||||
$foo->setDelegatee(new aDelegatee);
|
||||
$foo->doSomething(); /* prints "hubu" */
|
||||
|
||||
$foo->setDelegatee(new anotherDelegatee);
|
||||
$foo->doSomething(); /* prints "tubu" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
The "Foo" class may use all methods available in "$bar" as if they
|
||||
where locally defined or inherited from a superclass. The essential
|
||||
difference is that by assigning another object to "$bar" it is
|
||||
possible to dynamically switch between different implementations for
|
||||
these methods.
|
||||
|
||||
|
||||
Fixed Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class aDelegatee {
|
||||
function doSomething() {
|
||||
echo 'hubu';
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
final delegatee $bar = new aDelegatee;
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
|
||||
$foo->doSomething(); /* prints "hubu" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
The "Foo" class may use all methods available in "$bar" as if they
|
||||
where locally defined or inherited from a superclass. The difference
|
||||
to the dynamic delegation is that once the delegatee object is set,
|
||||
it cannot be changed.
|
||||
|
||||
|
||||
Default Delegation
|
||||
|
||||
Syntax / Example
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function __delegate($name, $parameters = array()) {
|
||||
echo $name;
|
||||
}
|
||||
}
|
||||
|
||||
$foo = new Foo;
|
||||
$foo->bar(); /* prints "bar" */
|
||||
?>
|
||||
|
||||
Semantics / Synopsis
|
||||
|
||||
If a class has a __delegate() method, it is called whenever a
|
||||
method on an object of this class is called that is
|
||||
|
||||
* Not defined in the class.
|
||||
|
||||
* Not provided by a delegatee object.
|
||||
|
||||
The __delegate() method is called with the name and parameters
|
||||
of the method call.
|
||||
|
||||
This supersedes / obsoletes similar functionality introduced in
|
||||
Zend Engine 1 by ext/overload.
|
||||
+72
-485
@@ -19,43 +19,11 @@ Changes in the Zend Engine 2.0
|
||||
the box or after a very small amount of modifications would be
|
||||
high.
|
||||
|
||||
* $this
|
||||
|
||||
Unlike in Zend Engine 1 the pseudo variable $this cannot be
|
||||
exchanged in Zend Engine 2. You can of course modify or work with
|
||||
an object by using $this but you cannot replace $this with another
|
||||
object to change the original object.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function replace($other)
|
||||
{
|
||||
$this = $other;
|
||||
}
|
||||
}
|
||||
|
||||
$object = new Foo;
|
||||
$object->prop = 'Hello';
|
||||
|
||||
$other = new Foo;
|
||||
$other->prop = 'Bye';
|
||||
|
||||
$object->replace($other);
|
||||
|
||||
print $object->prop; // still shows 'Hello'
|
||||
|
||||
?>
|
||||
|
||||
Zend Engine 2.0 will issue a compile error, if an assignment
|
||||
to $this is found.
|
||||
|
||||
* Private and Protected Members.
|
||||
|
||||
The Zend Engine 2.0 introduces private and protected member
|
||||
variables. Note that for performance reasons no error message is
|
||||
emitted in case of an illegal access to a private or protectecd
|
||||
The Zend Engine 2.0 introduces private and protected member
|
||||
variables. Note that for performance reasons no error message is
|
||||
emitted in case of an illegal access to a private or protectecd
|
||||
member variable.
|
||||
|
||||
Example:
|
||||
@@ -75,7 +43,7 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
class MyClass2 extends MyClass {
|
||||
protected $Foo;
|
||||
|
||||
|
||||
function printHello() {
|
||||
MyClass::printHello(); /* Should print */
|
||||
print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */
|
||||
@@ -96,9 +64,9 @@ Changes in the Zend Engine 2.0
|
||||
print $obj->Foo; /* Shouldn't print out anything */
|
||||
$obj->printHello();
|
||||
?>
|
||||
|
||||
Protected member variables can be accessed in classes extending the
|
||||
class they are declared in, whereas private member variables can
|
||||
|
||||
Protected member variables can be accessed in classes extending the
|
||||
class they are declared in, whereas private member variables can
|
||||
only be accessed by the class they belong to.
|
||||
|
||||
* Private and protected methods.
|
||||
@@ -130,14 +98,14 @@ Changes in the Zend Engine 2.0
|
||||
$o->aPublicMethod();
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'public', 'protected' or 'private' should run without modifications.
|
||||
|
||||
* Abstract Classes and Methods.
|
||||
|
||||
The Zend Engine 2.0 introduces abstract classes and methods. An
|
||||
abstract method only declares the method's signature and does not
|
||||
provide an implementation. A class that contains abstract methods
|
||||
The Zend Engine 2.0 introduces abstract classes and methods. An
|
||||
abstract method only declares the method's signature and does not
|
||||
provide an implementation. A class that contains abstract methods
|
||||
needs to be declared abstract.
|
||||
|
||||
Example:
|
||||
@@ -157,10 +125,9 @@ Changes in the Zend Engine 2.0
|
||||
$o->test();
|
||||
?>
|
||||
|
||||
Classes that do not have abstract methods can be declared abstract
|
||||
to prevent them from being instantiated.
|
||||
Abstract classes cannot be instantiated.
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'abstract' should run without modifications.
|
||||
|
||||
* Interfaces.
|
||||
@@ -171,58 +138,24 @@ Changes in the Zend Engine 2.0
|
||||
Example:
|
||||
|
||||
<?php
|
||||
interface Printable {
|
||||
public function dump();
|
||||
interface Throwable {
|
||||
public function getMessage();
|
||||
}
|
||||
|
||||
class PrintableExample implements Printable {
|
||||
public function dump() {
|
||||
class Exception implements Throwable {
|
||||
public function getMessage() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'interface' or 'implements' should run without modifications.
|
||||
|
||||
An interface may extend one or more base interfaces (but not
|
||||
implement them). Neither a class nor an interface can inherit
|
||||
methods of the same name from different root interfaces.
|
||||
|
||||
Interfaces may contain abstract static methods.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
interface Printable {
|
||||
function dump();
|
||||
}
|
||||
|
||||
interface Streamable extends Printable {
|
||||
function writeToStream();
|
||||
static function readFromStream();
|
||||
}
|
||||
|
||||
class PrintableExample implements Streamable {
|
||||
public function dump() {
|
||||
// ...
|
||||
}
|
||||
function writeToStream() {
|
||||
// ...
|
||||
}
|
||||
static function readFromStream() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
A class that does not implement all interface methods must be
|
||||
declared as an abstract class.
|
||||
|
||||
* Class Type Hints.
|
||||
|
||||
While remaining loosely typed the Zend Engine 2.0 introduces the
|
||||
ability to use class type hints to declare the expected class of
|
||||
While remaining loosely typed the Zend Engine 2.0 introduces the
|
||||
ability to use class type hints to declare the expected class of
|
||||
objects that are passed as parameters to a method.
|
||||
|
||||
Example:
|
||||
@@ -272,10 +205,11 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
This syntax only applies to objects/classes, not built-in types.
|
||||
|
||||
* Final methods and classes.
|
||||
* final.
|
||||
|
||||
The Zend Engine 2.0 introduces the "final" keyword to declare
|
||||
final methods. Those cannot be overridden by sub-classes.
|
||||
final members and methods. Those cannot be overridden by
|
||||
sub-classes.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -287,24 +221,7 @@ Changes in the Zend Engine 2.0
|
||||
}
|
||||
?>
|
||||
|
||||
It is furthermore possible to make a class final. Doing this
|
||||
prevents a class from being specialized (it cannot be inherited
|
||||
by another class). There's no need to declare the methods of
|
||||
a final class themselves as final.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
final class Foo {
|
||||
// class definition
|
||||
}
|
||||
// the next line is impossible
|
||||
// class Bork extends Foo {}
|
||||
?>
|
||||
|
||||
Properties cannot be final. See per-class constants below.
|
||||
|
||||
Old code that has no user-defined classes or functions named
|
||||
Old code that has no user-defined classes or functions named
|
||||
'final' should run without modifications.
|
||||
|
||||
* Object Cloning.
|
||||
@@ -325,12 +242,13 @@ Changes in the Zend Engine 2.0
|
||||
replicate the parent object you want to create a new instance of
|
||||
this other object so that the replica has its own separate copy.
|
||||
|
||||
An object copy is created by using the clone operator.
|
||||
An object copy is created by calling the object's __clone()
|
||||
method.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
$copy_of_object = clone $object;
|
||||
$copy_of_object = $object->__clone();
|
||||
?>
|
||||
|
||||
When the developer asks to create a new copy of an object, the
|
||||
@@ -339,40 +257,40 @@ Changes in the Zend Engine 2.0
|
||||
all of the object's properties. If a __clone() method is
|
||||
defined, then it will be responsible to set the necessary
|
||||
properties in the created object. For convenience, the engine
|
||||
ensures, that the clone will be initialized with all of the
|
||||
properties from the source object, so that developers can start
|
||||
with a by-value replica of the source object, and only override
|
||||
properties that need to be changed.
|
||||
will supply a function that imports all of the properties from
|
||||
the source object, so that they can start with a by-value
|
||||
replica of the source object, and only override properties that
|
||||
need to be changed. [The function hasn't been implemented yet]
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class MyCloneable {
|
||||
static $id = 0;
|
||||
static $id = 0;
|
||||
|
||||
function MyCloneable() {
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
function MyCloneable() {
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
|
||||
function __clone() {
|
||||
$this->address = 'New York';
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
function __clone() {
|
||||
$this->name = $that->name;
|
||||
$this->address = 'New York';
|
||||
$this->id = self::$id++;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new MyCloneable();
|
||||
|
||||
$obj->name = 'Hello';
|
||||
$obj->name = 'Hello';
|
||||
$obj->address = 'Tel-Aviv';
|
||||
|
||||
$obj_clone = clone $obj;
|
||||
print $obj->id . "\n";
|
||||
|
||||
$obj = $obj->__clone();
|
||||
|
||||
print $obj->id . "\n";
|
||||
print $obj->name . "\n";
|
||||
print $obj->address . "\n";
|
||||
|
||||
print $obj_clone->id . "\n";
|
||||
print $obj_clone->name . "\n";
|
||||
print $obj_clone->address . "\n";
|
||||
?>
|
||||
|
||||
* Unified Constructors.
|
||||
@@ -474,27 +392,24 @@ Changes in the Zend Engine 2.0
|
||||
echo 'Foo::constant = ' . Foo::constant . "\n";
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions
|
||||
The Zend Engine 2.0 allows for expressions within constants:
|
||||
|
||||
<?php
|
||||
class Bar {
|
||||
const a = 1<<0;
|
||||
const b = 1<<1;
|
||||
const c = a | b;
|
||||
}
|
||||
?>
|
||||
|
||||
Old code that has no user-defined classes or functions
|
||||
named 'const' will run without modifications.
|
||||
|
||||
* Exceptions.
|
||||
|
||||
The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0
|
||||
introduces a exception model similar to that of other programming
|
||||
languages. But there is no catch all and no finally clause.
|
||||
|
||||
Old code that has no user-defined classes or functions 'catch',
|
||||
'throw' and 'try' will run without modifications.
|
||||
|
||||
Exceptions can be rethrown in catch blocks. Also it is possible to
|
||||
have multiple catch blocks. In that case the caught exception is
|
||||
compared with the classtype of each catch block from top to bottom
|
||||
and the first block that has a 'instanceof' match gets executed.
|
||||
When the catch block finishes execution continues at the end of
|
||||
the last catch block. If no catch block has a 'instanceof' match
|
||||
then the next try/catch block is searched until no more try/catch
|
||||
blocks are available. In that case the exception is an uncaught
|
||||
exception and the program terminates with showing the exception.
|
||||
languages.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -522,106 +437,14 @@ Changes in the Zend Engine 2.0
|
||||
try {
|
||||
throw new MyExceptionFoo('Hello');
|
||||
}
|
||||
|
||||
catch (MyException $exception) {
|
||||
$exception->Display();
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
echo $exception;
|
||||
}
|
||||
?>
|
||||
|
||||
Even though the above example shows that it is possible to define
|
||||
exception classes that don't inherit from Exception it is best to
|
||||
do so. This is because the internal Exception class can gather a
|
||||
lot of information otherwise not available. The PHP code emulation
|
||||
code would look something like shown below. The comments show the
|
||||
meaning of each property. As the code shows it is possible to read
|
||||
any available information by using the getter methods. But since
|
||||
some of the methods are used internally they are marked final. All
|
||||
in all the class is very restrictive because it must be ensured
|
||||
that anything used internally always works as expected.
|
||||
|
||||
Emulating class Exception:
|
||||
|
||||
<?php
|
||||
class Exception {
|
||||
function __construct(/*string*/ $message=NULL, /*int*/ $code=0) {
|
||||
if (func_num_args()) {
|
||||
$this->message = $message;
|
||||
}
|
||||
$this->code = $code;
|
||||
$this->file = __FILE__; // of throw clause
|
||||
$this->line = __LINE__; // of throw clause
|
||||
$this->trace = debug_backtrace();
|
||||
$this->string = StringFormat($this);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
private $trace; // backtrace of exception
|
||||
private $string; // internal only!!
|
||||
|
||||
final function getMessage() {
|
||||
return $this->message;
|
||||
}
|
||||
final function getCode() {
|
||||
return $this->code;
|
||||
}
|
||||
final function getFile() {
|
||||
return $this->file;
|
||||
}
|
||||
final function getTrace() {
|
||||
return $this->trace;
|
||||
}
|
||||
final function getTraceAsString() {
|
||||
return self::TraceFormat($this);
|
||||
}
|
||||
function _toString() {
|
||||
return $this->string;
|
||||
}
|
||||
static private function StringFormat(Exception $exception) {
|
||||
// ... a function not available in PHP scripts
|
||||
// that returns all relevant information as a string
|
||||
}
|
||||
static private function TraceFormat(Exception $exception) {
|
||||
// ... a function not available in PHP scripts
|
||||
// that returns the backtrace as a string
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
If you derive your exception classes from this Exception base class
|
||||
your exceptions will be nicely shown in the builtin handler for
|
||||
uncaught exceptions.
|
||||
|
||||
Note: The method getMessage() is a final read only access method to
|
||||
the private proeprty message that is set in the constructor. If you
|
||||
feel a need to overwrite the exception display then overload method
|
||||
__toString() in your derived class or implement your own extneral
|
||||
exception display function to accomplish your desired formatting.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
function display_exception(Exception $ex)
|
||||
{
|
||||
echo 'Exception: ' . $ex->getMessage() . 'with backtrace: <pre>';
|
||||
echo $ex->getTrace();
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// your code here
|
||||
}
|
||||
catch (Exception $ex)
|
||||
{
|
||||
display_exeption($ex);
|
||||
}
|
||||
?>
|
||||
Old code that has no user-defined classes or functions 'catch',
|
||||
'throw' and 'try' will run without modifications.
|
||||
|
||||
* Dereferencing objects returned from functions.
|
||||
|
||||
@@ -651,21 +474,17 @@ Changes in the Zend Engine 2.0
|
||||
ShapeFactoryMethod('Square')->draw();
|
||||
?>
|
||||
|
||||
* Member variables of classes can now be initialized.
|
||||
* Static member variables of static classes can now be
|
||||
initialized.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class foo {
|
||||
static $my_static = 5;
|
||||
public $my_prop = 'bla';
|
||||
}
|
||||
|
||||
print foo::$my_static;
|
||||
|
||||
$obj = foo;
|
||||
|
||||
print $obj->my_prop;
|
||||
?>
|
||||
|
||||
* Static Methods.
|
||||
@@ -688,22 +507,14 @@ Changes in the Zend Engine 2.0
|
||||
The pseudo variable $this is not available inside a method that
|
||||
has been declared static.
|
||||
|
||||
* instanceof.
|
||||
New support for an instanceof operator which checks if an object
|
||||
is of a certain class or interface type.
|
||||
* instanceof (TBD)
|
||||
|
||||
Example:
|
||||
* Static function variables.
|
||||
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
}
|
||||
|
||||
$obj = new Foo();
|
||||
if ($obj instanceof Foo) {
|
||||
print "Yay!\n";
|
||||
}
|
||||
?>
|
||||
Statics are now treated at compile-time which allows developers
|
||||
to assign variables to statics by reference. This change also
|
||||
greatly improves their performance but means that indirect
|
||||
references to statics will not work anymore.
|
||||
|
||||
* Parameters that are passed by reference to a function
|
||||
may now have default values.
|
||||
@@ -720,11 +531,10 @@ Changes in the Zend Engine 2.0
|
||||
|
||||
* __autoload().
|
||||
|
||||
The __autoload() interceptor function will be automatically called
|
||||
when an undeclared class is to be instantiated. The name of that
|
||||
class will be passed to the __autoload() interceptor function as its
|
||||
only argument. __autoload() must succeed in loading the class. If it
|
||||
doesn't then an E_ERROR is emitted.
|
||||
The __autoload() interceptor function will be automatically called
|
||||
when an undeclared class is to be instantiated. The name of that
|
||||
class will be passed to the __autoload() interceptor function as its
|
||||
only argument.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -796,229 +606,6 @@ Changes in the Zend Engine 2.0
|
||||
var_dump($a);
|
||||
?>
|
||||
|
||||
* Iteration
|
||||
|
||||
Objects may be iterated in an overloaded way when used with
|
||||
foreach. The default behavior is to iterate over all properties
|
||||
with respect to property visibility.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
var $x = 1;
|
||||
var $y = 2;
|
||||
}
|
||||
|
||||
$obj = new Foo;
|
||||
|
||||
foreach ($obj as $prp_name => $prop_value) {
|
||||
// using the property
|
||||
}
|
||||
?>
|
||||
|
||||
Each class whose instances can be iterated with foreach should
|
||||
implement the empty interface 'Traversable'. Hence any object
|
||||
that says it implements 'Traversable' can be used with foreach.
|
||||
|
||||
The interfaces 'IteratorAggregate' and 'Iterator' allow to specify
|
||||
how class objects are iterated in PHP code. The first of them simply
|
||||
has a method 'getIterator' which must return an object that either
|
||||
implements the interface 'Iterator' or is instantiated from an
|
||||
internal class that can be iterated.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class ObjectIterator implements Iterator {
|
||||
|
||||
private $obj;
|
||||
private $num;
|
||||
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function rewind() {
|
||||
$this->num = 0;
|
||||
}
|
||||
function valid() {
|
||||
return $this->num < $this->obj->max;
|
||||
}
|
||||
function key() {
|
||||
return $this->num;
|
||||
}
|
||||
function current() {
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return $this->num."th";
|
||||
}
|
||||
}
|
||||
function next() {
|
||||
$this->num++;
|
||||
}
|
||||
}
|
||||
|
||||
class Object implements IteratorAggregate {
|
||||
|
||||
public $max = 3;
|
||||
|
||||
function getIterator() {
|
||||
return new ObjectIterator($this);
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Object;
|
||||
|
||||
// this foreach ...
|
||||
foreach($obj as $key => $val) {
|
||||
echo "$key = $val\n";
|
||||
}
|
||||
|
||||
// matches the following 7 lines with the for directive.
|
||||
$it = $obj->getIterator();
|
||||
for($it->rewind(); $it->valid(); $it->next()) {
|
||||
$key = $it->key();
|
||||
$val = $it->current();
|
||||
echo "$key = $val\n";
|
||||
}
|
||||
unset($it);
|
||||
?>
|
||||
|
||||
The matching for directive is very intersting here since it shows
|
||||
the use of all abstract methods declared in the interfaces Iterator
|
||||
and IteratorAggregate respectively.
|
||||
|
||||
* Array overloading
|
||||
|
||||
Objects can be used with Array notation when they implement the
|
||||
interface ArrayAccess. You cannot use such objects in standard
|
||||
array functions, however you have full control over the array
|
||||
notation. This allows lazy initialization or read only array.
|
||||
|
||||
Note that setting [] results in a call to offsetSet() with
|
||||
index being NULL. That means that as with standard arrays you
|
||||
cannot store NULL keys.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class ArrayClass implements ArrayAccess {
|
||||
public $a = array();
|
||||
|
||||
function offsetExists($index) {
|
||||
return array_key_exists($index, $this->a);
|
||||
}
|
||||
function offsetGet($index) {
|
||||
return $this->a[$index];
|
||||
}
|
||||
function offsetSet($index, $newval) {
|
||||
return $this->a[$index] = $newval;
|
||||
}
|
||||
function offsetUnset($index) {
|
||||
unset($this->a[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new ArrayClass;
|
||||
|
||||
$obj[0] = 'bla'; // calls offsetSet(0,'bla')
|
||||
$obj[] = 42; // calls offsetSet(NULL, 42)
|
||||
$x = $obj[0]; // calls offsetGet(0)
|
||||
$b = isset($obj[0]); // calls offsetExists(0)
|
||||
unset($obj[0]); // calls offsetUnset(0)
|
||||
?>
|
||||
|
||||
|
||||
* __METHOD__
|
||||
|
||||
The pseudo constant __METHOD__ shows the current class and method
|
||||
when used inside a method and the function when used outside of a
|
||||
class.
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function Show() {
|
||||
echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
|
||||
}
|
||||
}
|
||||
function Test() {
|
||||
echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__;
|
||||
}
|
||||
?>
|
||||
|
||||
* __toString()
|
||||
|
||||
The magic method __toString() allows to overload the object to
|
||||
string conversion. This conversion is only done automatically for
|
||||
the printing functions (echo, print) but not for other functions
|
||||
that expect strings. Also the function __toString is not used in
|
||||
places where objects are not allowed but strings are like array
|
||||
indices. Note that specialized objects may be converted to a string
|
||||
in any place but without calling __toString().
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
function __toString() {
|
||||
return "What ever";
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Foo;
|
||||
|
||||
$str = (string) $obj; // call __toString()
|
||||
|
||||
echo $obj; // call __toString()
|
||||
|
||||
$ar = array();
|
||||
$ar[(string)$obj]; // this works
|
||||
$ar[$obj]; // this is not allowed
|
||||
?>
|
||||
|
||||
* Reflection API
|
||||
|
||||
PHP 5 comes with a complete Reflection API that adds the ability to
|
||||
reverse-engineer classes, interfaces, functions and methods as well
|
||||
as extensions.
|
||||
|
||||
The Reflection API also offers ways of getting doc comments for
|
||||
functions, classes and methods.
|
||||
|
||||
Nearly all aspects of object oriented code can be reflected by
|
||||
using the Reflection API which is documented separately:
|
||||
http://sitten-polizei.de/php/reflection_api/docs/language.reflection.html
|
||||
|
||||
Example:
|
||||
|
||||
<?php
|
||||
class Foo {
|
||||
public $prop;
|
||||
function Func($name) {
|
||||
echo "Hello $name";
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionClass::export('Foo');
|
||||
ReflectionObject::export(new Foo);
|
||||
ReflectionMethod::export('Foo', 'func');
|
||||
ReflectionProperty::export('Foo', 'prop');
|
||||
ReflectionExtension::export('standard');
|
||||
?>
|
||||
|
||||
* New memory manager
|
||||
The Zend Engine has a new memory manager which allows it to run efficiently
|
||||
in multi-threaded environments as it doesn't need to use mutexes to lock
|
||||
and unlock during allocation/deallocation.
|
||||
|
||||
* Others
|
||||
Probably other changes which we forgot to list. This list will be kept up-to-date
|
||||
as much as possible.
|
||||
|
||||
|
||||
Changes in the Zend Engine 1.0
|
||||
|
||||
|
||||
+11
-27
@@ -7,20 +7,20 @@
|
||||
CFG=Zend - Win32 Release_inline
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Zend.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Zend.mak" CFG="Zend - Win32 Release_inline"
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE "Zend - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Zend - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Zend - Win32 Release_inline" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
@@ -95,7 +95,7 @@ LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
@@ -175,10 +175,6 @@ SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -243,10 +239,6 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -351,10 +343,6 @@ SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -419,10 +407,6 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -457,7 +441,7 @@ BuildCmds= \
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -512,7 +496,7 @@ BuildCmds= \
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -541,7 +525,7 @@ InputPath=.\zend_ini_scanner.l
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -578,7 +562,7 @@ InputPath=".\zend_language_scanner.l"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
+26
-91
@@ -4,29 +4,22 @@ dnl
|
||||
dnl This file contains Zend specific autoconf functions.
|
||||
dnl
|
||||
|
||||
AC_DEFUN([LIBZEND_CHECK_INT_TYPE],[
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_TRY_COMPILE([
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif],
|
||||
[if (($1 *) 0)
|
||||
return 0;
|
||||
if (sizeof ($1))
|
||||
return 0;
|
||||
],[
|
||||
AC_DEFINE_UNQUOTED([HAVE_]translit($1,a-z_-,A-Z__), 1,[Define if $1 type is present. ])
|
||||
AC_MSG_RESULT(yes)
|
||||
], AC_MSG_RESULT(no)
|
||||
)dnl
|
||||
AC_DEFUN(LIBZEND_BISON_CHECK,[
|
||||
|
||||
if test "$YACC" != "bison -y"; then
|
||||
AC_MSG_WARN(You will need bison if you want to regenerate the Zend parser.)
|
||||
else
|
||||
AC_MSG_CHECKING(bison version)
|
||||
set `bison --version| grep 'GNU Bison' | cut -d ' ' -f 4 | sed -e 's/\./ /'`
|
||||
if test "${1}" = "1" -a "${2}" -lt "28"; then
|
||||
AC_MSG_WARN(You will need bison 1.28 if you want to regenerate the Zend parser (found ${1}.${2}).)
|
||||
fi
|
||||
AC_MSG_RESULT(${1}.${2} (ok))
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_YACC])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
@@ -49,8 +42,6 @@ if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(
|
||||
inttypes.h \
|
||||
stdint.h \
|
||||
limits.h \
|
||||
malloc.h \
|
||||
string.h \
|
||||
@@ -61,18 +52,17 @@ sys/time.h \
|
||||
signal.h \
|
||||
unix.h \
|
||||
stdlib.h \
|
||||
mach-o/dyld.h \
|
||||
dlfcn.h)
|
||||
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
AC_DEFUN([LIBZEND_LIBDL_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_LIBDL_CHECKS,[
|
||||
AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS"])
|
||||
AC_CHECK_FUNC(dlopen,[AC_DEFINE(HAVE_LIBDL, 1,[ ])])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
|
||||
AC_DEFUN(LIBZEND_DLSYM_CHECK,[
|
||||
dnl
|
||||
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
|
||||
dnl
|
||||
@@ -91,10 +81,6 @@ dnl This is required for QNX and may be some BSD derived systems
|
||||
AC_CHECK_TYPE( uint, unsigned int )
|
||||
AC_CHECK_TYPE( ulong, unsigned long )
|
||||
|
||||
dnl Check if int32_t and uint32_t are defined
|
||||
LIBZEND_CHECK_INT_TYPE(int32_t)
|
||||
LIBZEND_CHECK_INT_TYPE(uint32_t)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_MEMCMP
|
||||
@@ -108,10 +94,10 @@ ZEND_FP_EXCEPT
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_ENABLE_DEBUG],[
|
||||
AC_DEFUN(LIBZEND_ENABLE_DEBUG,[
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Compile with debugging symbols],[
|
||||
[ --enable-debug Compile with debugging symbols],[
|
||||
ZEND_DEBUG=$enableval
|
||||
],[
|
||||
ZEND_DEBUG=no
|
||||
@@ -119,53 +105,30 @@ AC_ARG_ENABLE(debug,
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
|
||||
|
||||
AC_ARG_WITH(zend-vm,
|
||||
[ --with-zend-vm=TYPE Set virtual machine dispatch method. Type is
|
||||
one of "CALL", "SWITCH" or "GOTO" [TYPE=CALL]],[
|
||||
PHP_ZEND_VM=$withval
|
||||
],[
|
||||
PHP_ZEND_VM=CALL
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(zend-memory-manager,
|
||||
[ --disable-zend-memory-manager
|
||||
Disable the Zend memory manager - FOR DEVELOPERS ONLY!!],
|
||||
[
|
||||
ZEND_USE_ZEND_ALLOC=$enableval
|
||||
], [
|
||||
ZEND_USE_ZEND_ALLOC=yes
|
||||
])
|
||||
AC_DEFUN(LIBZEND_OTHER_CHECKS,[
|
||||
|
||||
AC_ARG_ENABLE(maintainer-zts,
|
||||
[ --enable-maintainer-zts Enable thread safety - for code maintainers only!!],[
|
||||
[ --enable-maintainer-zts Enable thread safety - for code maintainers only],[
|
||||
ZEND_MAINTAINER_ZTS=$enableval
|
||||
],[
|
||||
ZEND_MAINTAINER_ZTS=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(inline-optimization,
|
||||
[ --disable-inline-optimization
|
||||
If building zend_execute.lo fails, try this switch],[
|
||||
[ --disable-inline-optimization If building zend_execute.lo fails, try
|
||||
this switch.],[
|
||||
ZEND_INLINE_OPTIMIZATION=$enableval
|
||||
],[
|
||||
ZEND_INLINE_OPTIMIZATION=yes
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(memory-limit,
|
||||
[ --enable-memory-limit Compile with memory limit support], [
|
||||
[ --enable-memory-limit Compile with memory limit support. ], [
|
||||
ZEND_MEMORY_LIMIT=$enableval
|
||||
],[
|
||||
ZEND_MEMORY_LIMIT=no
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([virtual machine dispatch method])
|
||||
AC_MSG_RESULT($PHP_ZEND_VM)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable the Zend memory manager)
|
||||
AC_MSG_RESULT($ZEND_USE_ZEND_ALLOC)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable thread-safety)
|
||||
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
|
||||
|
||||
@@ -177,20 +140,7 @@ AC_MSG_RESULT($ZEND_MEMORY_LIMIT)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend debugging)
|
||||
AC_MSG_RESULT($ZEND_DEBUG)
|
||||
|
||||
case $PHP_ZEND_VM in
|
||||
SWITCH)
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_SWITCH,[virtual machine dispatch method])
|
||||
;;
|
||||
GOTO)
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_GOTO,[virtual machine dispatch method])
|
||||
;;
|
||||
*)
|
||||
PHP_ZEND_VM=CALL
|
||||
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_CALL,[virtual machine dispatch method])
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
if test "$ZEND_DEBUG" = "yes"; then
|
||||
AC_DEFINE(ZEND_DEBUG,1,[ ])
|
||||
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
|
||||
@@ -206,12 +156,6 @@ fi
|
||||
|
||||
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
|
||||
|
||||
if test "$ZEND_USE_ZEND_ALLOC" = "yes"; then
|
||||
AC_DEFINE(USE_ZEND_ALLOC,1,[Use Zend memory manager])
|
||||
else
|
||||
AC_DEFINE(USE_ZEND_ALLOC,0,[Use Zend memory manager])
|
||||
fi
|
||||
|
||||
if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
|
||||
AC_DEFINE(ZTS,1,[ ])
|
||||
CFLAGS="$CFLAGS -DZTS"
|
||||
@@ -224,6 +168,7 @@ else
|
||||
AC_DEFINE(MEMORY_LIMIT, 0, [Memory limit])
|
||||
fi
|
||||
|
||||
|
||||
changequote({,})
|
||||
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
|
||||
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
|
||||
@@ -236,13 +181,6 @@ AC_C_INLINE
|
||||
|
||||
AC_SUBST(INLINE_CFLAGS)
|
||||
|
||||
AC_MSG_CHECKING(target system is Darwin)
|
||||
if echo "$target" | grep "darwin" > /dev/null; then
|
||||
AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl test and set the alignment define for ZEND_MM
|
||||
dnl this also does the logarithmic test for ZEND_MM.
|
||||
@@ -285,9 +223,6 @@ int main()
|
||||
LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
|
||||
], [], [
|
||||
dnl cross-compile needs something here
|
||||
LIBZEND_MM_ALIGN=8
|
||||
])
|
||||
|
||||
AC_MSG_RESULT(done)
|
||||
@@ -295,7 +230,7 @@ AC_MSG_RESULT(done)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_CPLUSPLUS_CHECKS,[
|
||||
|
||||
])
|
||||
|
||||
+13
-41
@@ -7,21 +7,21 @@
|
||||
CFG=ZendTS - Win32 Release_TSDbg
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZendTS.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZendTS.mak" CFG="ZendTS - Win32 Release_TSDbg"
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE "ZendTS - Win32 Release_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZendTS - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZendTS - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZendTS - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
@@ -119,7 +119,7 @@ LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
@@ -164,10 +164,6 @@ SOURCE=.\zend_dynamic_array.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -204,14 +200,6 @@ SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -276,10 +264,6 @@ SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -336,11 +320,11 @@ SOURCE=.\zend_errors.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.h
|
||||
SOURCE=.\zend_execute.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.h
|
||||
SOURCE=.\zend_execute_locks.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -384,18 +368,10 @@ SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -456,10 +432,6 @@ SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -538,7 +510,7 @@ BuildCmds= \
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -609,7 +581,7 @@ BuildCmds= \
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -664,7 +636,7 @@ InputPath=.\zend_ini_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -711,7 +683,7 @@ InputPath=".\zend_language_scanner.l"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
+7
-23
@@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2006 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
| Copyright (c) 1998-2003 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
@@ -23,7 +23,9 @@
|
||||
#define ZEND_DLEXPORT
|
||||
#define ZEND_DLIMPORT
|
||||
|
||||
#ifndef NETWARE
|
||||
@TOP@
|
||||
#endif
|
||||
|
||||
#undef uint
|
||||
#undef ulong
|
||||
@@ -31,9 +33,9 @@
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
|
||||
#ifndef NETWARE
|
||||
@BOTTOM@
|
||||
|
||||
#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
@@ -43,10 +45,6 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
@@ -65,16 +63,11 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* To enable the is_nan, is_infinite and is_finite PHP functions */
|
||||
#ifdef NETWARE
|
||||
#define HAVE_ISNAN 1
|
||||
#define HAVE_ISINF 1
|
||||
#define HAVE_ISFINITE 1
|
||||
#endif
|
||||
|
||||
#ifndef zend_isnan
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(NAN)
|
||||
#define zend_isnan(a) (((a)==NAN)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#else
|
||||
@@ -103,15 +96,6 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
|
||||
#endif
|
||||
|
||||
#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */
|
||||
|
||||
#ifdef NETWARE
|
||||
#ifdef USE_WINSOCK
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
||||
+4
-64
@@ -2,40 +2,7 @@ dnl $Id$
|
||||
dnl
|
||||
dnl This file contains local autoconf functions.
|
||||
|
||||
AC_DEFUN([LIBZEND_BISON_CHECK],[
|
||||
# we only support certain bison versions
|
||||
bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1"
|
||||
|
||||
# for standalone build of Zend Engine
|
||||
test -z "$SED" && SED=sed
|
||||
|
||||
bison_version=none
|
||||
if test "$YACC"; then
|
||||
AC_CACHE_CHECK([for bison version], php_cv_bison_version, [
|
||||
bison_version_vars=`bison --version 2> /dev/null | grep 'GNU Bison' | cut -d ' ' -f 4 | $SED -e 's/\./ /' | tr -d a-z`
|
||||
php_cv_bison_version=invalid
|
||||
if test -n "$bison_version_vars"; then
|
||||
set $bison_version_vars
|
||||
bison_version="${1}.${2}"
|
||||
for bison_check_version in $bison_version_list; do
|
||||
if test "$bison_version" = "$bison_check_version"; then
|
||||
php_cv_bison_version="$bison_check_version (ok)"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
fi
|
||||
case $php_cv_bison_version in
|
||||
""|invalid[)]
|
||||
bison_msg="bison versions supported for regeneration of the Zend/PHP parsers: $bison_version_list (found: $bison_version)."
|
||||
AC_MSG_WARN([$bison_msg])
|
||||
YACC="exit 0;"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
AC_DEFUN([ZEND_FP_EXCEPT],[
|
||||
AC_DEFUN(ZEND_FP_EXCEPT,[
|
||||
AC_CACHE_CHECK(whether fp_except is defined, ac_cv_type_fp_except,[
|
||||
AC_TRY_COMPILE([
|
||||
#include <floatingpoint.h>
|
||||
@@ -56,7 +23,7 @@ fp_except x = (fp_except) 0;
|
||||
dnl
|
||||
dnl Check for broken sprintf()
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
AC_DEFUN(AC_ZEND_BROKEN_SPRINTF,[
|
||||
AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
|
||||
AC_TRY_RUN([main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }],[
|
||||
ac_cv_broken_sprintf=no
|
||||
@@ -74,34 +41,7 @@ AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
AC_DEFINE_UNQUOTED(ZEND_BROKEN_SPRINTF, $ac_result, [Whether sprintf is broken])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl AC_ZEND_C_BIGENDIAN
|
||||
dnl Replacement macro for AC_C_BIGENDIAN
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_C_BIGENDIAN],
|
||||
[AC_CACHE_CHECK([whether byte ordering is bigendian], ac_cv_c_bigendian_php,
|
||||
[
|
||||
ac_cv_c_bigendian_php=unknown
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
int main(void)
|
||||
{
|
||||
short one = 1;
|
||||
char *cp = (char *)&one;
|
||||
|
||||
if (*cp == 0) {
|
||||
return(0);
|
||||
} else {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
], [ac_cv_c_bigendian_php=yes], [ac_cv_c_bigendian_php=no], [ac_cv_c_bigendian_php=unknown])
|
||||
])
|
||||
if test $ac_cv_c_bigendian_php = yes; then
|
||||
AC_DEFINE(WORDS_BIGENDIAN, [], [Define if processor uses big-endian word])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
-419
@@ -1,419 +0,0 @@
|
||||
<?php
|
||||
|
||||
function simple() {
|
||||
$a = 0;
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
$a++;
|
||||
|
||||
$thisisanotherlongname = 0;
|
||||
for ($thisisalongname = 0; $thisisalongname < 1000000; $thisisalongname++)
|
||||
$thisisanotherlongname++;
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function simplecall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
strlen("hallo");
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hallo($a) {
|
||||
}
|
||||
|
||||
function simpleucall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
hallo("hallo");
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function simpleudcall() {
|
||||
for ($i = 0; $i < 1000000; $i++)
|
||||
hallo2("hallo");
|
||||
}
|
||||
|
||||
function hallo2($a) {
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mandel() {
|
||||
$w1=50;
|
||||
$h1=150;
|
||||
$recen=-.45;
|
||||
$imcen=0.0;
|
||||
$r=0.7;
|
||||
$s=0; $rec=0; $imc=0; $re=0; $im=0; $re2=0; $im2=0;
|
||||
$x=0; $y=0; $w2=0; $h2=0; $color=0;
|
||||
$s=2*$r/$w1;
|
||||
$w2=40;
|
||||
$h2=12;
|
||||
for ($y=0 ; $y<=$w1; $y=$y+1) {
|
||||
$imc=$s*($y-$h2)+$imcen;
|
||||
for ($x=0 ; $x<=$h1; $x=$x+1) {
|
||||
$rec=$s*($x-$w2)+$recen;
|
||||
$re=$rec;
|
||||
$im=$imc;
|
||||
$color=1000;
|
||||
$re2=$re*$re;
|
||||
$im2=$im*$im;
|
||||
while( ((($re2+$im2)<1000000) && $color>0)) {
|
||||
$im=$re*$im*2+$imc;
|
||||
$re=$re2-$im2+$rec;
|
||||
$re2=$re*$re;
|
||||
$im2=$im*$im;
|
||||
$color=$color-1;
|
||||
}
|
||||
if ( $color==0 ) {
|
||||
print "_";
|
||||
} else {
|
||||
print "#";
|
||||
}
|
||||
}
|
||||
print "<br>";
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mandel2() {
|
||||
$b = " .:,;!/>)|&IH%*#";
|
||||
//float r, i, z, Z, t, c, C;
|
||||
for ($y=30; printf("\n"), $C = $y*0.1 - 1.5, $y--;){
|
||||
for ($x=0; $c = $x*0.04 - 2, $z=0, $Z=0, $x++ < 75;){
|
||||
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
|
||||
if ($z*$z + $Z*$Z > 500000) break;
|
||||
echo $b[$k%16];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function Ack($m, $n){
|
||||
if($m == 0) return $n+1;
|
||||
if($n == 0) return Ack($m-1, 1);
|
||||
return Ack($m - 1, Ack($m, ($n - 1)));
|
||||
}
|
||||
|
||||
function ackermann($n) {
|
||||
$r = Ack(3,$n);
|
||||
print "Ack(3,$n): $r\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary($n) {
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$X[$i] = $i;
|
||||
}
|
||||
for ($i=$n-1; $i>=0; $i--) {
|
||||
$Y[$i] = $X[$i];
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary2($n) {
|
||||
for ($i=0; $i<$n;) {
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
$X[$i] = $i; ++$i;
|
||||
}
|
||||
for ($i=$n-1; $i>=0;) {
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
$Y[$i] = $X[$i]; --$i;
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function ary3($n) {
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
$X[$i] = $i + 1;
|
||||
$Y[$i] = 0;
|
||||
}
|
||||
for ($k=0; $k<1000; $k++) {
|
||||
for ($i=$n-1; $i>=0; $i--) {
|
||||
$Y[$i] += $X[$i];
|
||||
}
|
||||
}
|
||||
$last = $n-1;
|
||||
print "$Y[0] $Y[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function fibo_r($n){
|
||||
return(($n < 2) ? 1 : fibo_r($n - 2) + fibo_r($n - 1));
|
||||
}
|
||||
|
||||
function fibo($n) {
|
||||
$r = fibo_r($n);
|
||||
print "$r\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hash($n) {
|
||||
for ($i = 1; $i <= $n; $i++) {
|
||||
$X[dechex($i)] = $i;
|
||||
}
|
||||
$c = 0;
|
||||
for ($i = $n; $i > 0; $i--) {
|
||||
if ($X[dechex($i)]) { $c++; }
|
||||
}
|
||||
print "$c\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function hash2($n) {
|
||||
for ($i = 0; $i < $n; $i++) {
|
||||
$hash1["foo_$i"] = $i;
|
||||
$hash2["foo_$i"] = 0;
|
||||
}
|
||||
for ($i = $n; $i > 0; $i--) {
|
||||
foreach($hash1 as $key => $value) $hash2[$key] += $value;
|
||||
}
|
||||
$first = "foo_0";
|
||||
$last = "foo_".($n-1);
|
||||
print "$hash1[$first] $hash1[$last] $hash2[$first] $hash2[$last]\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function gen_random ($n) {
|
||||
global $LAST;
|
||||
return( ($n * ($LAST = ($LAST * IA + IC) % IM)) / IM );
|
||||
}
|
||||
|
||||
function heapsort_r($n, &$ra) {
|
||||
$l = ($n >> 1) + 1;
|
||||
$ir = $n;
|
||||
|
||||
while (1) {
|
||||
if ($l > 1) {
|
||||
$rra = $ra[--$l];
|
||||
} else {
|
||||
$rra = $ra[$ir];
|
||||
$ra[$ir] = $ra[1];
|
||||
if (--$ir == 1) {
|
||||
$ra[1] = $rra;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$i = $l;
|
||||
$j = $l << 1;
|
||||
while ($j <= $ir) {
|
||||
if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
|
||||
$j++;
|
||||
}
|
||||
if ($rra < $ra[$j]) {
|
||||
$ra[$i] = $ra[$j];
|
||||
$j += ($i = $j);
|
||||
} else {
|
||||
$j = $ir + 1;
|
||||
}
|
||||
}
|
||||
$ra[$i] = $rra;
|
||||
}
|
||||
}
|
||||
|
||||
function heapsort($N) {
|
||||
global $LAST;
|
||||
|
||||
define("IM", 139968);
|
||||
define("IA", 3877);
|
||||
define("IC", 29573);
|
||||
|
||||
$LAST = 42;
|
||||
for ($i=1; $i<=$N; $i++) {
|
||||
$ary[$i] = gen_random(1);
|
||||
}
|
||||
heapsort_r($N, $ary);
|
||||
printf("%.10f\n", $ary[$N]);
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function mkmatrix ($rows, $cols) {
|
||||
$count = 1;
|
||||
$mx = array();
|
||||
for ($i=0; $i<$rows; $i++) {
|
||||
for ($j=0; $j<$cols; $j++) {
|
||||
$mx[$i][$j] = $count++;
|
||||
}
|
||||
}
|
||||
return($mx);
|
||||
}
|
||||
|
||||
function mmult ($rows, $cols, $m1, $m2) {
|
||||
$m3 = array();
|
||||
for ($i=0; $i<$rows; $i++) {
|
||||
for ($j=0; $j<$cols; $j++) {
|
||||
$x = 0;
|
||||
for ($k=0; $k<$cols; $k++) {
|
||||
$x += $m1[$i][$k] * $m2[$k][$j];
|
||||
}
|
||||
$m3[$i][$j] = $x;
|
||||
}
|
||||
}
|
||||
return($m3);
|
||||
}
|
||||
|
||||
function matrix($n) {
|
||||
$SIZE = 30;
|
||||
$m1 = mkmatrix($SIZE, $SIZE);
|
||||
$m2 = mkmatrix($SIZE, $SIZE);
|
||||
while ($n--) {
|
||||
$mm = mmult($SIZE, $SIZE, $m1, $m2);
|
||||
}
|
||||
print "{$mm[0][0]} {$mm[2][3]} {$mm[3][2]} {$mm[4][4]}\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function nestedloop($n) {
|
||||
$x = 0;
|
||||
for ($a=0; $a<$n; $a++)
|
||||
for ($b=0; $b<$n; $b++)
|
||||
for ($c=0; $c<$n; $c++)
|
||||
for ($d=0; $d<$n; $d++)
|
||||
for ($e=0; $e<$n; $e++)
|
||||
for ($f=0; $f<$n; $f++)
|
||||
$x++;
|
||||
print "$x\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function sieve($n) {
|
||||
$count = 0;
|
||||
while ($n-- > 0) {
|
||||
$count = 0;
|
||||
$flags = range (0,8192);
|
||||
for ($i=2; $i<8193; $i++) {
|
||||
if ($flags[$i] > 0) {
|
||||
for ($k=$i+$i; $k <= 8192; $k+=$i) {
|
||||
$flags[$k] = 0;
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
print "Count: $count\n";
|
||||
}
|
||||
|
||||
/****/
|
||||
|
||||
function strcat($n) {
|
||||
$str = "";
|
||||
while ($n-- > 0) {
|
||||
$str .= "hello\n";
|
||||
}
|
||||
$len = strlen($str);
|
||||
print "$len\n";
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
function getmicrotime()
|
||||
{
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name)
|
||||
{
|
||||
global $total;
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$total += $end-$start;
|
||||
$num = number_format($end-$start,3);
|
||||
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
|
||||
|
||||
echo $name.$pad.$num."\n";
|
||||
ob_start();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
{
|
||||
global $total;
|
||||
$pad = str_repeat("-", 24);
|
||||
echo $pad."\n";
|
||||
$num = number_format($total,3);
|
||||
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
|
||||
echo "Total".$pad.$num."\n";
|
||||
}
|
||||
|
||||
$t0 = $t = start_test();
|
||||
simple();
|
||||
$t = end_test($t, "simple");
|
||||
simplecall();
|
||||
$t = end_test($t, "simplecall");
|
||||
simpleucall();
|
||||
$t = end_test($t, "simpleucall");
|
||||
simpleudcall();
|
||||
$t = end_test($t, "simpleudcall");
|
||||
mandel();
|
||||
$t = end_test($t, "mandel");
|
||||
mandel2();
|
||||
$t = end_test($t, "mandel2");
|
||||
ackermann(7);
|
||||
$t = end_test($t, "ackermann(7)");
|
||||
ary(50000);
|
||||
$t = end_test($t, "ary(50000)");
|
||||
ary2(50000);
|
||||
$t = end_test($t, "ary2(50000)");
|
||||
ary3(2000);
|
||||
$t = end_test($t, "ary3(2000)");
|
||||
fibo(30);
|
||||
$t = end_test($t, "fibo(30)");
|
||||
hash(50000);
|
||||
$t = end_test($t, "hash(50000)");
|
||||
hash2(500);
|
||||
$t = end_test($t, "hash2(500)");
|
||||
heapsort(20000);
|
||||
$t = end_test($t, "heapsort(20000)");
|
||||
matrix(20);
|
||||
$t = end_test($t, "matrix(20)");
|
||||
nestedloop(12);
|
||||
$t = end_test($t, "nestedloop(12)");
|
||||
sieve(30);
|
||||
$t = end_test($t, "sieve(30)");
|
||||
strcat(200000);
|
||||
$t = end_test($t, "strcat(200000)");
|
||||
total($t0, "Total");
|
||||
?>
|
||||
@@ -10,14 +10,10 @@ AC_PROG_CC
|
||||
AM_PROG_LEX
|
||||
AM_PROG_CC_STDC
|
||||
ZEND_VERSION=$VERSION
|
||||
AC_ZEND_C_BIGENDIAN
|
||||
|
||||
dnl We want this one before the checks, so the checks can modify CFLAGS.
|
||||
test -z "$CFLAGS" && auto_cflags=1
|
||||
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
|
||||
sinclude(Zend.m4)
|
||||
|
||||
LIBZEND_BASIC_CHECKS
|
||||
|
||||
@@ -440,6 +440,13 @@ YY_MALLOC_DECL
|
||||
#define ECHO /* There is no output */
|
||||
#endif
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
|
||||
|
||||
|
||||
#ifndef ECHO
|
||||
%- Standard (non-C++) definition
|
||||
/* This used to be an fputs(), but since the string might contain NUL's,
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2006 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -1,15 +0,0 @@
|
||||
--TEST--
|
||||
Array type hint
|
||||
--FILE--
|
||||
<?php
|
||||
function foo(array $a) {
|
||||
echo count($a)."\n";
|
||||
}
|
||||
|
||||
foo(array(1,2,3));
|
||||
foo(123);
|
||||
?>
|
||||
--EXPECTF--
|
||||
3
|
||||
|
||||
Catchable fatal error: Argument 1 passed to foo() must be an array, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php on line 2
|
||||
@@ -7,7 +7,7 @@ Bug #20240 (order of destructor calls)
|
||||
|
||||
class test
|
||||
{
|
||||
public $member;
|
||||
var $member;
|
||||
|
||||
function test() {
|
||||
$this->member = 1;
|
||||
@@ -39,5 +39,5 @@ echo "Done\n";
|
||||
2
|
||||
3
|
||||
Done
|
||||
test::__destruct
|
||||
test::destructor
|
||||
test::__destruct
|
||||
@@ -3,7 +3,7 @@ Bug #21478 (Zend/zend_alloc.c :: shutdown_memory_manager produces segfault)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed');
|
||||
if (!function_exists('stream_filter_register')) die('skip stream_filter_register() not available');
|
||||
if (!function_exists('stream_filter_register') die('skip stream_filter_register() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -34,3 +34,6 @@ $c->viewMom();
|
||||
--EXPECT--
|
||||
protected method
|
||||
protected property
|
||||
--EXPECT--
|
||||
protected method
|
||||
protected property
|
||||
@@ -7,9 +7,9 @@ Bug #22836 (returning references to NULL)
|
||||
function &f()
|
||||
{
|
||||
$x = "foo";
|
||||
var_dump($x);
|
||||
print "'$x'\n";
|
||||
return ($a);
|
||||
var_dump($x);
|
||||
print "'$x'\n";
|
||||
return ($a);
|
||||
}
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$h =& f();
|
||||
@@ -18,34 +18,7 @@ for ($i = 0; $i < 8; $i++) {
|
||||
--EXPECTF--
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
--UEXPECTF--
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
unicode(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Fatal error: Only variables or references can be returned by reference in %s on line %d
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
Bug #23104 (Hash position not reset for constant arrays)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($bar = array("a", "b", "c"))
|
||||
{
|
||||
var_dump(current($bar));
|
||||
}
|
||||
foo();
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "a"
|
||||
--UEXPECT--
|
||||
unicode(1) "a"
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Bug #24635 (crash on dtor calling other functions)
|
||||
Bug #24635: crash on dtor calling other functions
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
--TEST--
|
||||
Bug #24699 (Memory Leak with per-class constants)
|
||||
Bug #24699 Memory Leak with per-class constants
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
<?
|
||||
class TEST { const FOO = SEEK_CUR; };
|
||||
class TEST2 { const FOO = 1; };
|
||||
class TEST3 { const FOO = PHP_VERSION; };
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24773 (unset() of integers treated as arrays causes a crash)
|
||||
--FILE--
|
||||
<?php
|
||||
$array = 'test';
|
||||
unset($array["lvl1"]["lvl2"]["b"]);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot unset string offsets in %s on line %d
|
||||
@@ -1,28 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24884 (calling $this->__clone(); crashes php)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Test {
|
||||
function __copy()
|
||||
{
|
||||
$string = PHP_VERSION;
|
||||
$version = $string{0};
|
||||
if($string < 5)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
$test = new Test();
|
||||
$test2 = $test->__copy();
|
||||
var_dump($test2);
|
||||
?>
|
||||
--EXPECT--
|
||||
object(Test)#2 (0) {
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26010 (private / protected variables get exposed by get_object_vars())
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $private = 'private';
|
||||
protected $protected = 'protected';
|
||||
public $public = 'public';
|
||||
}
|
||||
$data = new foo();
|
||||
$obj_vars = get_object_vars($data);
|
||||
var_dump($obj_vars);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["public"]=>
|
||||
string(6) "public"
|
||||
}
|
||||
--UEXPECT--
|
||||
array(1) {
|
||||
[u"public"]=>
|
||||
unicode(6) "public"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26077 (Memory leaks when creating an instance of an object)
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {} new foo();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -1,81 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26166 (__toString() crash when no values returned)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
{
|
||||
function __toString()
|
||||
{
|
||||
return "Hello World!\n";
|
||||
}
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
private $obj;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->obj = new Foo();
|
||||
}
|
||||
|
||||
function __toString()
|
||||
{
|
||||
return $this->obj->__toString();
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Bar;
|
||||
echo $o;
|
||||
|
||||
echo "===NONE===\n";
|
||||
|
||||
function my_error_handler($errno, $errstr, $errfile, $errline) {
|
||||
var_dump($errstr);
|
||||
}
|
||||
|
||||
set_error_handler('my_error_handler');
|
||||
|
||||
class None
|
||||
{
|
||||
function __toString() {
|
||||
}
|
||||
}
|
||||
|
||||
$o = new None;
|
||||
echo $o;
|
||||
|
||||
echo "===THROW===\n";
|
||||
|
||||
class Error
|
||||
{
|
||||
function __toString() {
|
||||
throw new Exception("This is an error!");
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Error;
|
||||
try {
|
||||
echo $o;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "Got the exception\n";
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Hello World!
|
||||
===NONE===
|
||||
string(52) "Method None::__toString() must return a string value"
|
||||
===THROW===
|
||||
|
||||
Fatal error: Object of class Error could not be converted to string in %sbug26166.php on line %d
|
||||
--UEXPECTF--
|
||||
Hello World!
|
||||
===NONE===
|
||||
unicode(52) "Method None::__toString() must return a string value"
|
||||
===THROW===
|
||||
|
||||
Fatal error: Object of class Error could not be converted to string in %sbug26166.php on line %d
|
||||
@@ -1,29 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26229 (getIterator() segfaults when it returns arrays or scalars)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class array_iterator implements IteratorAggregate {
|
||||
public function getIterator() {
|
||||
return array('foo', 'bar');
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new array_iterator;
|
||||
|
||||
try
|
||||
{
|
||||
foreach ($obj as $property => $value)
|
||||
{
|
||||
var_dump($value);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Objects returned by array_iterator::getIterator() must be traversable or implement interface Iterator
|
||||
===DONE===
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26281 (switch() crash when condition is a string offset)
|
||||
--FILE--
|
||||
<?php
|
||||
$x = 'abc';
|
||||
switch ($x{0}) {
|
||||
case 'a':
|
||||
echo "no crash\n";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
no crash
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26696 (crash in switch() when string index is used)
|
||||
--FILE--
|
||||
<?php
|
||||
$str = 'asdd/?';
|
||||
$len = strlen($str);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
switch ($str[$i]) {
|
||||
case '?':
|
||||
echo "?+\n";
|
||||
break;
|
||||
default:
|
||||
echo $str[$i].'-';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
a-s-d-d-/-?+
|
||||
===DONE===
|
||||
@@ -1,24 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26697 (calling class_exists on a nonexistent class in __autoload results in segfault)
|
||||
--SKIPIF--
|
||||
<?php if (function_exists('__autoload')) die('skip __autoload() declared in auto_prepend_file');?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function __autoload($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
var_dump(class_exists('NotExistingClass'));
|
||||
echo __METHOD__ . "($name), done\n";
|
||||
}
|
||||
|
||||
var_dump(class_exists('NotExistingClass'));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
__autoload(NotExistingClass)
|
||||
bool(false)
|
||||
__autoload(NotExistingClass), done
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,73 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26698 (Thrown exceptions while evaluting argument to pass as parameter crash PHP)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ini_set("report_memleaks", 0); // the exception thrown in this test results in a memory leak, which is fine
|
||||
|
||||
class Object
|
||||
{
|
||||
function getNone()
|
||||
{
|
||||
throw new Exception('NONE');
|
||||
}
|
||||
}
|
||||
|
||||
class Proxy
|
||||
{
|
||||
function three($a, $b, $c)
|
||||
{
|
||||
}
|
||||
|
||||
function callOne()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three($res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function callTwo()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three(1, $res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function callThree()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three(1, 2, $res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Proxy();
|
||||
|
||||
$p->callOne();
|
||||
$p->callTwo();
|
||||
$p->callThree();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
Caught: NONE
|
||||
Caught: NONE
|
||||
Caught: NONE
|
||||
===DONE===
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26801 (switch ($a{0}) crash)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = '11';
|
||||
$b = $a{0};
|
||||
switch ($b) {
|
||||
case '-':
|
||||
break;
|
||||
}
|
||||
|
||||
$a = '22';
|
||||
switch ($a{0}) {
|
||||
case '-':
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26802 (Can't call static method using a variable)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function global_func()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
|
||||
$function = 'global_func';
|
||||
$function();
|
||||
|
||||
class foo
|
||||
{
|
||||
static $method = 'global_func';
|
||||
|
||||
static public function foo_func()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* The following is a BC break with PHP 4 where it would
|
||||
* call foo::fail. In PHP 5 we first evaluate static class
|
||||
* properties and then do the function call.
|
||||
*/
|
||||
$method = 'foo_func';
|
||||
foo::$method();
|
||||
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
global_func
|
||||
foo::foo_func
|
||||
===DONE===
|
||||
@@ -1,28 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27268 (Bad references accentuated by clone)
|
||||
--FILE--
|
||||
<?php
|
||||
class A
|
||||
{
|
||||
public function &getA()
|
||||
{
|
||||
return $this->a;
|
||||
}
|
||||
}
|
||||
|
||||
$A = new A;
|
||||
$A->a = array(1);
|
||||
$x = $A->getA();
|
||||
$clone = clone $A;
|
||||
$clone->a = array();
|
||||
print_r($A);
|
||||
?>
|
||||
--EXPECT--
|
||||
A Object
|
||||
(
|
||||
[a] => Array
|
||||
(
|
||||
[0] => 1
|
||||
)
|
||||
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27304
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Staticexample
|
||||
{
|
||||
static function test()
|
||||
{
|
||||
var_dump(isset($this));
|
||||
}
|
||||
}
|
||||
|
||||
$b = new Staticexample();
|
||||
Staticexample::test();
|
||||
$b->test();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27598 (list() array key assignment causes HUGE memory leak)
|
||||
--FILE--
|
||||
<?php
|
||||
list($out[0]) = array(1);
|
||||
var_dump($out);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27641 (zend.ze1_compatibility_mode = On causes object properties to be misreported)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--INI--
|
||||
error_reporting=4095
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
public $a = "Default for A";
|
||||
public $b = "Default for B";
|
||||
|
||||
function __construct($a, $b) {
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
}
|
||||
function A() {
|
||||
$args = func_get_args();
|
||||
call_user_func_array(Array(&$this, '__construct'), $args);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new A("New A", "New B");
|
||||
print_r($t);
|
||||
print_r(get_class_vars(get_class($t)));
|
||||
print_r(get_object_vars($t));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: Redefining already defined constructor for class A in %sbug27641.php on line %d
|
||||
A Object
|
||||
(
|
||||
[a] => New A
|
||||
[b] => New B
|
||||
)
|
||||
Array
|
||||
(
|
||||
[a] => Default for A
|
||||
[b] => Default for B
|
||||
)
|
||||
Array
|
||||
(
|
||||
[a] => New A
|
||||
[b] => New B
|
||||
)
|
||||
@@ -1,18 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27669 (PHP 5 didn't support all possibilities for calling static methods dynamically)
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL & !E_STRICT);
|
||||
|
||||
class A {
|
||||
function hello() {
|
||||
echo "Hello World\n";
|
||||
}
|
||||
}
|
||||
$y[0] = 'hello';
|
||||
A::$y[0]();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Hello World
|
||||
===DONE===
|
||||
@@ -1,10 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27731 (error_reporing() call inside @ block does not work correctly)
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
@error_reporting(E_WARNING);
|
||||
var_dump(error_reporting());
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2)
|
||||
@@ -1,109 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27798 (private / protected variables not exposed by get_object_vars() inside class)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Base
|
||||
{
|
||||
public $Foo = 1;
|
||||
protected $Bar = 2;
|
||||
private $Baz = 3;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
var_dump(get_object_vars($this));
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Base
|
||||
{
|
||||
private $Baz = 4;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
echo __METHOD__ . "\n";
|
||||
var_dump(get_object_vars($this));
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(get_object_vars(new Base));
|
||||
var_dump(get_object_vars(new Child));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
Base::__construct
|
||||
array(3) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
["Baz"]=>
|
||||
int(3)
|
||||
}
|
||||
array(1) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
Base::__construct
|
||||
array(3) {
|
||||
["Baz"]=>
|
||||
int(4)
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
Child::__construct
|
||||
array(3) {
|
||||
["Baz"]=>
|
||||
int(4)
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
array(1) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
===DONE===
|
||||
--UEXPECT--
|
||||
Base::__construct
|
||||
array(3) {
|
||||
[u"Foo"]=>
|
||||
int(1)
|
||||
[u"Bar"]=>
|
||||
int(2)
|
||||
[u"Baz"]=>
|
||||
int(3)
|
||||
}
|
||||
array(1) {
|
||||
[u"Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
Base::__construct
|
||||
array(3) {
|
||||
[u"Baz"]=>
|
||||
int(4)
|
||||
[u"Foo"]=>
|
||||
int(1)
|
||||
[u"Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
Child::__construct
|
||||
array(3) {
|
||||
[u"Baz"]=>
|
||||
int(4)
|
||||
[u"Foo"]=>
|
||||
int(1)
|
||||
[u"Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
array(1) {
|
||||
[u"Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
===DONE===
|
||||
@@ -1,46 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28072 (static array with some constant keys will be incorrectly ordered)
|
||||
--FILE--
|
||||
<?php
|
||||
define("FIRST_KEY", "a");
|
||||
define("THIRD_KEY", "c");
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
static $arr = array(
|
||||
FIRST_KEY => "111",
|
||||
"b" => "222",
|
||||
THIRD_KEY => "333",
|
||||
"d" => "444"
|
||||
);
|
||||
print_r($arr);
|
||||
}
|
||||
|
||||
function test2()
|
||||
{
|
||||
static $arr = array(
|
||||
FIRST_KEY => "111",
|
||||
"a" => "222",
|
||||
"c" => "333",
|
||||
THIRD_KEY => "444"
|
||||
);
|
||||
print_r($arr);
|
||||
}
|
||||
|
||||
test();
|
||||
test2();
|
||||
?>
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[a] => 111
|
||||
[b] => 222
|
||||
[c] => 333
|
||||
[d] => 444
|
||||
)
|
||||
Array
|
||||
(
|
||||
[a] => 111
|
||||
[c] => 444
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28377 (debug_backtrace is intermittently passing args)
|
||||
--FILE--
|
||||
<?php
|
||||
function doit($a, $b)
|
||||
{
|
||||
$trace = debug_backtrace();
|
||||
custom_callback('dereferenced', $trace);
|
||||
custom_callback('direct', debug_backtrace());
|
||||
}
|
||||
|
||||
function custom_callback($traceName, $btInfo)
|
||||
{
|
||||
echo $traceName ." -- args: ";
|
||||
echo isset($btInfo[0]['args']) ? count($btInfo[0]['args']) : 'does not exist';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
doit('a','b');
|
||||
?>
|
||||
--EXPECT--
|
||||
dereferenced -- args: 2
|
||||
direct -- args: 2
|
||||
@@ -1,83 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28442 (Changing a static variables in a class changes it across sub/super classes.)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class ClassA
|
||||
{
|
||||
static $prop;
|
||||
}
|
||||
|
||||
class ClassB extends ClassA
|
||||
{
|
||||
static $prop;
|
||||
}
|
||||
|
||||
class ClassC extends ClassB
|
||||
{
|
||||
}
|
||||
|
||||
echo "===INIT===\n";
|
||||
ClassA::$prop = 'A';
|
||||
ClassB::$prop = 'B';
|
||||
ClassC::$prop = 'C';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetA===\n";
|
||||
ClassA::$prop = 'A2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetB===\n";
|
||||
ClassB::$prop = 'B2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetC===\n";
|
||||
ClassC::$prop = 'C2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
===INIT===
|
||||
string(1) "A"
|
||||
string(1) "C"
|
||||
string(1) "C"
|
||||
===SetA===
|
||||
string(2) "A2"
|
||||
string(1) "C"
|
||||
string(1) "C"
|
||||
===SetB===
|
||||
string(2) "A2"
|
||||
string(2) "B2"
|
||||
string(2) "B2"
|
||||
===SetC===
|
||||
string(2) "A2"
|
||||
string(2) "C2"
|
||||
string(2) "C2"
|
||||
===DONE===
|
||||
--UEXPECTF--
|
||||
===INIT===
|
||||
unicode(1) "A"
|
||||
unicode(1) "C"
|
||||
unicode(1) "C"
|
||||
===SetA===
|
||||
unicode(2) "A2"
|
||||
unicode(1) "C"
|
||||
unicode(1) "C"
|
||||
===SetB===
|
||||
unicode(2) "A2"
|
||||
unicode(2) "B2"
|
||||
unicode(2) "B2"
|
||||
===SetC===
|
||||
unicode(2) "A2"
|
||||
unicode(2) "C2"
|
||||
unicode(2) "C2"
|
||||
===DONE===
|
||||
@@ -1,105 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28444 (Cannot access undefined property for object with overloaded property access)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function my_error_handler($errno, $errstr, $errfile, $errline) {
|
||||
var_dump($errstr);
|
||||
}
|
||||
|
||||
set_error_handler('my_error_handler');
|
||||
|
||||
class Object
|
||||
{
|
||||
public $x;
|
||||
|
||||
function __construct($x)
|
||||
{
|
||||
$this->x = $x;
|
||||
}
|
||||
}
|
||||
|
||||
class Overloaded
|
||||
{
|
||||
public $props = array();
|
||||
public $x;
|
||||
|
||||
function __construct($x)
|
||||
{
|
||||
$this->x = new Object($x);
|
||||
}
|
||||
|
||||
function __get($prop)
|
||||
{
|
||||
echo __METHOD__ . "($prop)\n";
|
||||
return $this->props[$prop];
|
||||
}
|
||||
|
||||
function __set($prop, $val)
|
||||
{
|
||||
echo __METHOD__ . "($prop,$val)\n";
|
||||
$this->props[$prop] = $val;
|
||||
}
|
||||
}
|
||||
$y = new Overloaded(2);
|
||||
var_dump($y->x);
|
||||
var_dump($y->x->x);
|
||||
var_dump($y->x->x = 3);
|
||||
var_dump($y->y = 3);
|
||||
var_dump($y->y);
|
||||
var_dump($y->z = new Object(4));
|
||||
var_dump($y->z->x);
|
||||
$t = $y->z;
|
||||
var_dump($t->x = 5);
|
||||
var_dump($y->z->x = 6);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
object(Object)#%d (1) {
|
||||
["x"]=>
|
||||
int(2)
|
||||
}
|
||||
int(2)
|
||||
int(3)
|
||||
Overloaded::__set(y,3)
|
||||
int(3)
|
||||
Overloaded::__get(y)
|
||||
int(3)
|
||||
string(55) "Object of class Object could not be converted to string"
|
||||
Overloaded::__set(z,)
|
||||
object(Object)#%d (1) {
|
||||
["x"]=>
|
||||
int(4)
|
||||
}
|
||||
Overloaded::__get(z)
|
||||
int(4)
|
||||
Overloaded::__get(z)
|
||||
int(5)
|
||||
Overloaded::__get(z)
|
||||
int(6)
|
||||
===DONE===
|
||||
--UEXPECTF--
|
||||
object(Object)#%d (1) {
|
||||
[u"x"]=>
|
||||
int(2)
|
||||
}
|
||||
int(2)
|
||||
int(3)
|
||||
Overloaded::__set(y,3)
|
||||
int(3)
|
||||
Overloaded::__get(y)
|
||||
int(3)
|
||||
unicode(55) "Object of class Object could not be converted to string"
|
||||
Overloaded::__set(z,)
|
||||
object(Object)#%d (1) {
|
||||
[u"x"]=>
|
||||
int(4)
|
||||
}
|
||||
Overloaded::__get(z)
|
||||
int(4)
|
||||
Overloaded::__get(z)
|
||||
int(5)
|
||||
Overloaded::__get(z)
|
||||
int(6)
|
||||
===DONE===
|
||||
@@ -1,11 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29015 (Incorrect behavior of member vars(non string ones)-numeric mem vars und others)
|
||||
--FILE--
|
||||
<?php
|
||||
$a = new stdClass();
|
||||
$x = "";
|
||||
$a->$x = "string('')";
|
||||
var_dump($a);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot access empty property in %sbug29015.php on line 4
|
||||
@@ -1,27 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29104 Function declaration in method doesn't work
|
||||
--FILE--
|
||||
<?php
|
||||
class A
|
||||
{
|
||||
function g()
|
||||
{
|
||||
echo "function g - begin\n";
|
||||
|
||||
function f()
|
||||
{
|
||||
echo "function f\n";
|
||||
}
|
||||
|
||||
echo "function g - end\n";
|
||||
}
|
||||
}
|
||||
|
||||
$a = new A;
|
||||
$a->g();
|
||||
f();
|
||||
?>
|
||||
--EXPECT--
|
||||
function g - begin
|
||||
function g - end
|
||||
function f
|
||||
@@ -1,104 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29210 Function: is_callable - no support for private and protected classes
|
||||
--FILE--
|
||||
<?php
|
||||
class test_class {
|
||||
private function test_func1() {
|
||||
echo "test_func1\n";
|
||||
}
|
||||
protected function test_func2() {
|
||||
echo "test_func2\n";
|
||||
}
|
||||
static private function test_func3() {
|
||||
echo "test_func3\n";
|
||||
}
|
||||
static protected function test_func4() {
|
||||
echo "test_func4\n";
|
||||
}
|
||||
function test() {
|
||||
if (is_callable(array($this,'test_func1'))) {
|
||||
$this->test_func1();
|
||||
} else {
|
||||
echo "test_func1 isn't callable from inside\n";
|
||||
}
|
||||
if (is_callable(array($this,'test_func2'))) {
|
||||
$this->test_func2();
|
||||
} else {
|
||||
echo "test_func2 isn't callable from inside\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func3'))) {
|
||||
test_class::test_func3();
|
||||
} else {
|
||||
echo "test_func3 isn't callable from inside\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func4'))) {
|
||||
test_class::test_func4();
|
||||
} else {
|
||||
echo "test_func4 isn't callable from inside\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class foo extends test_class {
|
||||
function test() {
|
||||
if (is_callable(array($this,'test_func1'))) {
|
||||
$this->test_func1();
|
||||
} else {
|
||||
echo "test_func1 isn't callable from child\n";
|
||||
}
|
||||
if (is_callable(array($this,'test_func2'))) {
|
||||
$this->test_func2();
|
||||
} else {
|
||||
echo "test_func2 isn't callable from child\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func3'))) {
|
||||
test_class::test_func3();
|
||||
} else {
|
||||
echo "test_func3 isn't callable from child\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func4'))) {
|
||||
test_class::test_func4();
|
||||
} else {
|
||||
echo "test_func4 isn't callable from child\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$object = new test_class;
|
||||
$object->test();
|
||||
if (is_callable(array($object,'test_func1'))) {
|
||||
$object->test_func1();
|
||||
} else {
|
||||
echo "test_func1 isn't callable from outside\n";
|
||||
}
|
||||
if (is_callable(array($object,'test_func2'))) {
|
||||
$object->test_func2();
|
||||
} else {
|
||||
echo "test_func2 isn't callable from outside\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func3'))) {
|
||||
test_class::test_func3();
|
||||
} else {
|
||||
echo "test_func3 isn't callable from outside\n";
|
||||
}
|
||||
if (is_callable(array('test_class','test_func4'))) {
|
||||
test_class::test_func4();
|
||||
} else {
|
||||
echo "test_func4 isn't callable from outside\n";
|
||||
}
|
||||
$object = new foo();
|
||||
$object->test();
|
||||
?>
|
||||
--EXPECTF--
|
||||
test_func1
|
||||
test_func2
|
||||
test_func3
|
||||
test_func4
|
||||
test_func1 isn't callable from outside
|
||||
test_func2 isn't callable from outside
|
||||
test_func3 isn't callable from outside
|
||||
test_func4 isn't callable from outside
|
||||
test_func1 isn't callable from child
|
||||
test_func2
|
||||
test_func3 isn't callable from child
|
||||
test_func4
|
||||
@@ -1,34 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29368 (The destructor is called when an exception is thrown from the constructor)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
throw new Exception;
|
||||
}
|
||||
function __destruct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$bar = new Foo;
|
||||
} catch(Exception $exc)
|
||||
{
|
||||
echo "Caught exception!\n";
|
||||
}
|
||||
|
||||
unset($bar);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Foo::__construct
|
||||
Caught exception!
|
||||
===DONE===
|
||||
@@ -1,48 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29505 (get_class_vars() severely broken when used with arrays)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public $empty = array();
|
||||
public $three = array(1, "b"=>"c", 3=>array());
|
||||
}
|
||||
|
||||
var_dump(get_class_vars('Test'));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["empty"]=>
|
||||
array(0) {
|
||||
}
|
||||
["three"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
string(1) "c"
|
||||
[3]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
--UEXPECT--
|
||||
array(2) {
|
||||
[u"empty"]=>
|
||||
array(0) {
|
||||
}
|
||||
[u"three"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[u"b"]=>
|
||||
unicode(1) "c"
|
||||
[3]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
@@ -1,51 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29674 (inherited method doesn't have access to private variables of the derived class)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class BaseClass
|
||||
{
|
||||
private $private_base = "Base";
|
||||
|
||||
function printVars ()
|
||||
{
|
||||
var_dump($this->private_base);
|
||||
var_dump($this->private_child);
|
||||
}
|
||||
}
|
||||
|
||||
class ChildClass extends BaseClass
|
||||
{
|
||||
private $private_child = "Child";
|
||||
}
|
||||
|
||||
echo "===BASE===\n";
|
||||
$obj = new BaseClass;
|
||||
$obj->printVars();
|
||||
|
||||
echo "===CHILD===\n";
|
||||
$obj = new ChildClass;
|
||||
$obj->printVars();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
===BASE===
|
||||
string(4) "Base"
|
||||
|
||||
Notice: Undefined property: BaseClass::$private_child in %sbug29674.php on line %d
|
||||
NULL
|
||||
===CHILD===
|
||||
string(4) "Base"
|
||||
|
||||
Fatal error: Cannot access private property ChildClass::$private_child in %sbug29674.php on line %d
|
||||
--UEXPECTF--
|
||||
===BASE===
|
||||
unicode(4) "Base"
|
||||
|
||||
Notice: Undefined property: BaseClass::$private_child in %sbug29674.php on line %d
|
||||
NULL
|
||||
===CHILD===
|
||||
unicode(4) "Base"
|
||||
|
||||
Fatal error: Cannot access private property ChildClass::$private_child in %sbug29674.php on line %d
|
||||
@@ -1,62 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29689 (default value of protected member overrides default value of private)
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $foo = 'foo';
|
||||
private $foo2 = 'foo2';
|
||||
|
||||
function printFoo()
|
||||
{
|
||||
echo __CLASS__, ': ', $this->foo, " ", $this->foo2, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
class bar extends foo {
|
||||
protected $foo = 'bar';
|
||||
|
||||
function printFoo()
|
||||
{
|
||||
parent::printFoo();
|
||||
echo __CLASS__, ': ', $this->foo, " ", $this->foo2, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
class baz extends bar {
|
||||
protected $foo = 'baz';
|
||||
protected $foo2 = 'baz2';
|
||||
}
|
||||
|
||||
class bar2 extends foo {
|
||||
function printFoo()
|
||||
{
|
||||
parent::printFoo();
|
||||
echo __CLASS__, ': ', $this->foo, " ", $this->foo2, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
class baz2 extends bar2 {
|
||||
protected $foo = 'baz2';
|
||||
protected $foo2 = 'baz22';
|
||||
}
|
||||
|
||||
$bar = new bar;
|
||||
$bar->printFoo();
|
||||
echo "---baz--\n";
|
||||
$baz = new baz();
|
||||
$baz->printFoo();
|
||||
echo "---baz2--\n";
|
||||
$baz = new baz2();
|
||||
$baz->printFoo();
|
||||
?>
|
||||
--EXPECTF--
|
||||
foo: foo foo2
|
||||
bar: bar
|
||||
Notice: Undefined property: bar::$foo2 in %s on line %d
|
||||
|
||||
---baz--
|
||||
foo: foo foo2
|
||||
bar: baz baz2
|
||||
---baz2--
|
||||
foo: foo foo2
|
||||
bar2: baz2 baz22
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Bug #29883 (isset gives invalid values on strings)
|
||||
--FILE--
|
||||
<?php
|
||||
$x = "bug";
|
||||
var_dump(isset($x[-1]));
|
||||
var_dump(isset($x["1"]));
|
||||
echo $x["1"]."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(true)
|
||||
u
|
||||
Loaded 100 of 4615 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user