mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-10 02:30:50 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52597c960 | ||
|
|
93def6e3a1 | ||
|
|
d8cd47aa83 |
No files matched your search
+9
-6
@@ -1,13 +1,19 @@
|
||||
|
||||
version: "{branch}.build.{build}"
|
||||
|
||||
image: Visual Studio 2017
|
||||
image: Visual Studio 2015
|
||||
|
||||
branches:
|
||||
except:
|
||||
- PHP-5.6
|
||||
- PHP-7.0
|
||||
|
||||
skip_commits:
|
||||
files:
|
||||
- NEWS
|
||||
- UPGRADING*
|
||||
- README.*
|
||||
|
||||
clone_depth: 64
|
||||
|
||||
cache:
|
||||
@@ -17,8 +23,7 @@ environment:
|
||||
PHP_BUILD_CACHE_BASE_DIR: c:\build-cache
|
||||
PHP_BUILD_OBJ_DIR: c:\obj
|
||||
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.1.7beta1
|
||||
PHP_BUILD_CRT: vc15
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.1.1
|
||||
# ext and env setup for tests
|
||||
#MYSQL_TEST_PASSWD: Password12!
|
||||
#MYSQL_TEST_USER: root
|
||||
@@ -33,13 +38,11 @@ environment:
|
||||
OPCACHE: 0
|
||||
- THREAD_SAFE: 1
|
||||
OPCACHE: 1
|
||||
INTRINSICS: AVX
|
||||
|
||||
services:
|
||||
# the setup scripts have to be touched, once some other db version is used
|
||||
- mysql
|
||||
- postgresql101
|
||||
- mssql2017
|
||||
- postgresql96
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
@@ -16,11 +16,9 @@ define ____executor_globals
|
||||
end
|
||||
set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1])
|
||||
set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
|
||||
set $eg_ptr = $eg
|
||||
else
|
||||
set $eg = executor_globals
|
||||
set $cg = compiler_globals
|
||||
set $eg_ptr = (zend_executor_globals*) &executor_globals
|
||||
end
|
||||
end
|
||||
|
||||
@@ -291,16 +289,6 @@ define ____printzv
|
||||
end
|
||||
end
|
||||
|
||||
define print_global_vars
|
||||
____executor_globals
|
||||
set $symtable = ((HashTable *)&($eg_ptr->symbol_table))
|
||||
print_ht $symtable
|
||||
end
|
||||
|
||||
document print_global_vars
|
||||
Prints the global variables
|
||||
end
|
||||
|
||||
define print_const_table
|
||||
set $ind = 1
|
||||
printf "[%p] {\n", $arg0
|
||||
|
||||
+18
-1
@@ -1,11 +1,28 @@
|
||||
ext/mysqlnd/mysqlnd.h ident
|
||||
ext/ext_skel.php ident
|
||||
ext/simplexml/simplexml.c ident
|
||||
ext/iconv/php_iconv.h ident
|
||||
ext/posix/posix.c ident
|
||||
ext/recode/recode.c ident
|
||||
ext/skeleton/create_stubs ident
|
||||
ext/phar/phar/pharcommand.inc ident
|
||||
ext/phar/phar.c ident
|
||||
ext/sysvmsg/sysvmsg.c ident
|
||||
ext/enchant/enchant.c ident
|
||||
ext/reflection/php_reflection.c ident
|
||||
ext/oci8/oci8.c ident
|
||||
ext/dba/libinifile/inifile.c ident
|
||||
ext/dba/libflatfile/flatfile.c ident
|
||||
ext/dba/libcdb/cdb_make.c ident
|
||||
ext/dba/libcdb/cdb.c ident
|
||||
ext/filter/filter.c ident
|
||||
README.input_filter ident
|
||||
run-tests.php ident
|
||||
Zend/RFCs/002.txt ident
|
||||
Zend/RFCs/003.txt ident
|
||||
ext/exif/exif.c ident
|
||||
ext/ldap/ldap.c ident
|
||||
ext/pdo_pgsql/pdo_pgsql.c ident
|
||||
ext/tidy/tidy.c ident
|
||||
NEWS merge=NEWS
|
||||
UPGRADING merge=NEWS
|
||||
UPGRADING.INTERNALS merge=NEWS
|
||||
|
||||
+138
-80
@@ -1,4 +1,4 @@
|
||||
# General ignores
|
||||
# General Ignores
|
||||
*~
|
||||
.#*
|
||||
*.
|
||||
@@ -31,9 +31,17 @@
|
||||
phpt.*
|
||||
core
|
||||
dynlib.m4
|
||||
Debug
|
||||
Debug_TS
|
||||
Makefile
|
||||
Makefile.fragments
|
||||
Makefile.objects
|
||||
Release
|
||||
Release_TS
|
||||
Release_TSDbg
|
||||
Release_TS_inline
|
||||
Release_inline
|
||||
ZendEngine1
|
||||
_libs
|
||||
acconfig.h
|
||||
aclocal.m4
|
||||
@@ -48,6 +56,7 @@ config.cache
|
||||
config.h.in
|
||||
config.log
|
||||
config.nice
|
||||
config.nice.bat
|
||||
config.status
|
||||
config.sub
|
||||
config_vars.mk
|
||||
@@ -56,6 +65,8 @@ configuration-parser.h
|
||||
configuration-parser.output
|
||||
configuration-scanner.c
|
||||
configure
|
||||
configure.bat
|
||||
configure.js
|
||||
conftest
|
||||
conftest.c
|
||||
debug.log
|
||||
@@ -74,6 +85,7 @@ missing
|
||||
mkinstalldirs
|
||||
modules
|
||||
php
|
||||
php-*.tar.gz
|
||||
php7.spec
|
||||
php_lcov.info
|
||||
php_test_results_*.txt
|
||||
@@ -83,49 +95,11 @@ shlibtool
|
||||
stamp-h
|
||||
test.php3
|
||||
tmp-php.ini
|
||||
want_dependencies
|
||||
x64
|
||||
stamp-h.in
|
||||
scan_makefile_in.awk
|
||||
main/php_config.h
|
||||
main/php_config.h.in
|
||||
main/build-defs.h
|
||||
main/internal_functions_cli.c
|
||||
main/config.w32.h
|
||||
main/stamp-h1
|
||||
main/streams/build-defs.h
|
||||
main/streams/stamp-h1
|
||||
pear/install-pear-nozlib.phar
|
||||
pear/phpize
|
||||
pear/run-tests
|
||||
pear/php-config
|
||||
pear/scripts
|
||||
sapi/apache2handler/libphp7.module
|
||||
sapi/cgi/php-cgi
|
||||
sapi/cgi/php-cgi.1
|
||||
sapi/cli/php.1
|
||||
sapi/fpm/php-fpm
|
||||
sapi/fpm/php-fpm.1
|
||||
sapi/fpm/init.d.php-fpm
|
||||
sapi/fpm/php-fpm.conf
|
||||
sapi/fpm/fpm/php-cgi
|
||||
sapi/fpm/php-fpm.8
|
||||
sapi/fpm/php-fpm.service
|
||||
sapi/fpm/status.html
|
||||
sapi/fpm/www.conf
|
||||
sapi/phpdbg/phpdbg_parser.c
|
||||
sapi/phpdbg/phpdbg_parser.h
|
||||
sapi/phpdbg/phpdbg
|
||||
sapi/phpdbg/build
|
||||
sapi/phpdbg/*.output
|
||||
scripts/php-config
|
||||
scripts/phpize
|
||||
scripts/man1/*.1
|
||||
TSRM/tsrm_config.h
|
||||
win32/*.suo
|
||||
win32/*.aps
|
||||
win32/*.positions
|
||||
win32/ext
|
||||
win32/phpts.def
|
||||
win32/wsyslog.h
|
||||
Zend/zend_config.h
|
||||
Zend/zend_dtrace_gen.h
|
||||
Zend/zend_dtrace_gen.hbak
|
||||
@@ -135,9 +109,71 @@ Zend/zend_ini_parser.output
|
||||
Zend/zend_language_parser.c
|
||||
Zend/zend_language_parser.h
|
||||
Zend/zend_language_parser.output
|
||||
ext/date/lib/timelib_config.h
|
||||
ext/iconv/php_iconv_aliased_libiconv.h
|
||||
ext/phar/phar.php
|
||||
main/php_config.h
|
||||
main/php_config.h.in
|
||||
|
||||
# Extension specific ignores
|
||||
ext/*/configure.ac
|
||||
# Test specific Ignores
|
||||
tests/*/*.diff
|
||||
tests/*/*.out
|
||||
tests/*/*.php
|
||||
tests/*/*.exp
|
||||
tests/*/*.log
|
||||
tests/*/*.sh
|
||||
tests/*/*/*.diff
|
||||
tests/*/*/*.out
|
||||
tests/*/*/*.php
|
||||
tests/*/*/*.exp
|
||||
tests/*/*/*.log
|
||||
tests/*/*/*.sh
|
||||
*/tests/*.diff
|
||||
*/tests/*.out
|
||||
*/tests/*.php
|
||||
*/tests/*.exp
|
||||
*/tests/*.log
|
||||
*/tests/*.sh
|
||||
*/tests/*/*.diff
|
||||
*/tests/*/*.out
|
||||
*/tests/*/*.php
|
||||
*/tests/*/*.exp
|
||||
*/tests/*/*.log
|
||||
*/tests/*/*.sh
|
||||
*/tests/*/*/*.diff
|
||||
*/tests/*/*/*.out
|
||||
*/tests/*/*/*.php
|
||||
*/tests/*/*/*.exp
|
||||
*/tests/*/*/*.log
|
||||
*/tests/*/*/*.sh
|
||||
*/*/tests/*.diff
|
||||
*/*/tests/*.out
|
||||
*/*/tests/*.out.png
|
||||
*/*/tests/*.php
|
||||
*/*/tests/*.exp
|
||||
*/*/tests/*.log
|
||||
*/*/tests/*.sh
|
||||
*/*/tests/*/*.diff
|
||||
*/*/tests/*/*.out
|
||||
*/*/tests/*/*.php
|
||||
*/*/tests/*/*.exp
|
||||
*/*/tests/*/*.log
|
||||
*/*/tests/*/*.sh
|
||||
*/*/tests/*/*/*.diff
|
||||
*/*/tests/*/*/*.out
|
||||
*/*/tests/*/*/*.php
|
||||
*/*/tests/*/*/*.exp
|
||||
*/*/tests/*/*/*.log
|
||||
*/*/tests/*/*/*.sh
|
||||
*/*/tests/*/*/*/*.diff
|
||||
*/*/tests/*/*/*/*.out
|
||||
*/*/tests/*/*/*/*.php
|
||||
*/*/tests/*/*/*/*.exp
|
||||
*/*/tests/*/*/*/*.log
|
||||
*/*/tests/*/*/*/*.sh
|
||||
|
||||
# Extension specifc ignores
|
||||
ext/*/configure.in
|
||||
ext/*/ltmain.sh
|
||||
ext/*/libs.mk
|
||||
ext/*/build
|
||||
@@ -145,7 +181,9 @@ ext/*/scan_makefile_in.awk
|
||||
ext/*/Makefile.global
|
||||
ext/*/acinclude.m4
|
||||
ext/*/config.sub
|
||||
ext/date/lib/timelib_config.h
|
||||
|
||||
# Extension specific
|
||||
ext/iconv/scan_makefile_in.awk
|
||||
ext/iconv/php_have_bsd_iconv.h
|
||||
ext/iconv/php_have_ibm_iconv.h
|
||||
ext/iconv/php_have_libiconv.h
|
||||
@@ -155,7 +193,6 @@ ext/iconv/php_php_iconv_impl.h
|
||||
ext/iconv/php_have_iconv.h
|
||||
ext/iconv/php_iconv_supports_errno.h
|
||||
ext/iconv/php_iconv_broken_ignore.h
|
||||
ext/iconv/php_iconv_aliased_libiconv.h
|
||||
ext/mbstring/libmbfl/Makefile.in
|
||||
ext/mbstring/libmbfl/autoscan.log
|
||||
ext/mbstring/libmbfl/config.sub
|
||||
@@ -172,56 +209,77 @@ ext/mbstring/libmbfl/filters/Makefile.in
|
||||
ext/mbstring/libmbfl/mbfl/Makefile.in
|
||||
ext/mbstring/libmbfl/mbfl/EastAsianWidth.txt
|
||||
ext/mbstring/libmbfl/nls/Makefile.in
|
||||
ext/mbstring/oniguruma/oniguruma.h
|
||||
ext/mssql/#*#
|
||||
ext/mssql/Makefile.global
|
||||
ext/mssql/acinclude.m4
|
||||
ext/mssql/config.sub
|
||||
ext/mssql/configure.in
|
||||
ext/mssql/ltmain.sh
|
||||
ext/mysql/weztest.sqlite
|
||||
ext/oci8/tests/*.tmp
|
||||
ext/oci8/tests/*.vglog
|
||||
ext/pdo/conftest*
|
||||
ext/pdo/tests/*.db
|
||||
ext/pdo/tests/*.tmp
|
||||
ext/pdo_firebird/conftest*
|
||||
ext/pdo_mysql/conftest*
|
||||
ext/pdo_mysql/tests/*.db
|
||||
ext/pdo_mysql/tests/*.tmp
|
||||
ext/pdo_oci/conftest*
|
||||
ext/pdo_odbc/tests/*.db
|
||||
ext/pdo_odbc/tests/*.tmp
|
||||
ext/pdo_odbc/tests/*.mdb
|
||||
ext/pdo_pgsql/conftest*
|
||||
ext/pdo_pgsql/tests/*.db
|
||||
ext/pdo_pgsql/tests/*.tmp
|
||||
ext/pdo_sqlite/conftest*
|
||||
ext/pdo_sqlite/sqlite3.h
|
||||
ext/pdo_sqlite/tests/*.db
|
||||
ext/pdo_sqlite/tests/*.tmp
|
||||
ext/phar/phar.phar
|
||||
ext/phar/phar.1
|
||||
ext/phar/phar.phar.1
|
||||
ext/phar/phar.php
|
||||
ext/pspell/tests/*.tmp
|
||||
ext/reflection/xml
|
||||
ext/reflection/html
|
||||
ext/reflection/spl.chm
|
||||
ext/simplexml/examples/security.new.xml
|
||||
ext/spl/examples/.htaccess
|
||||
ext/spl/examples/*.phps
|
||||
ext/sqlite3/tests/phpsql*
|
||||
|
||||
# ------------------------------------------------------------------------------ Windows
|
||||
# Generated by `/buildconf.bat`
|
||||
/configure.bat
|
||||
/configure.js
|
||||
|
||||
# Generated by `/configure.(bat|js)` (architecture dependend)
|
||||
/config.nice.bat
|
||||
/Debug/
|
||||
/Debug_TS/
|
||||
/Release/
|
||||
/Release_TS/
|
||||
/x64/
|
||||
|
||||
# ------------------------------------------------------------------------------ Tests
|
||||
# Generated by `/run-tests.php` upon failure
|
||||
**/tests/**/*.diff
|
||||
**/tests/**/*.out*
|
||||
**/tests/**/*.php
|
||||
**/tests/**/*.exp
|
||||
**/tests/**/*.log
|
||||
**/tests/**/*.sh
|
||||
|
||||
# Used by some test cases.
|
||||
**/tests/**/*.db
|
||||
**/tests/**/*.txt
|
||||
**/tests/**/*.tmp
|
||||
|
||||
# Special cases to invert previous ignore rules
|
||||
!ext/fileinfo/libmagic.patch
|
||||
!ext/mbstring/oniguruma.patch
|
||||
!scripts/dev/generate-phpt/tests/*.php
|
||||
!ext/pcre/pcre2lib/config.h
|
||||
ext/sqlite3/tests/*.db
|
||||
ext/sqlite3/tests/*.tmp
|
||||
ext/standard/tests/misc/*.txt
|
||||
ext/standard/tests/strings/*.txt
|
||||
main/build-defs.h
|
||||
main/internal_functions_cli.c
|
||||
main/config.w32.h
|
||||
main/stamp-h1
|
||||
main/streams/build-defs.h
|
||||
main/streams/stamp-h1
|
||||
#pear/install-pear-nozlib.phar
|
||||
pear/phpize
|
||||
pear/run-tests
|
||||
pear/php-config
|
||||
pear/scripts
|
||||
sapi/apache2handler/libphp7.module
|
||||
sapi/cgi/php-cgi
|
||||
sapi/cgi/php-cgi.1
|
||||
sapi/cli/php.1
|
||||
sapi/fpm/php-fpm
|
||||
sapi/fpm/php-fpm.1
|
||||
sapi/fpm/init.d.php-fpm
|
||||
sapi/fpm/php-fpm.conf
|
||||
sapi/fpm/fpm/php-cgi
|
||||
sapi/phpdbg/phpdbg_parser.c
|
||||
sapi/phpdbg/phpdbg_parser.h
|
||||
sapi/phpdbg/phpdbg
|
||||
scripts/php-config
|
||||
scripts/phpize
|
||||
scripts/man1/*.1
|
||||
win32/*.suo
|
||||
win32/*.aps
|
||||
win32/*.positions
|
||||
win32/ext
|
||||
win32/phpts.def
|
||||
win32/wsyslog.h
|
||||
+5
-14
@@ -9,6 +9,7 @@ addons:
|
||||
- re2c
|
||||
- libgmp-dev
|
||||
- libicu-dev
|
||||
- libmcrypt-dev
|
||||
- libtidy-dev
|
||||
- libenchant-dev
|
||||
- libaspell-dev
|
||||
@@ -17,7 +18,6 @@ addons:
|
||||
- libsasl2-dev
|
||||
- libxpm-dev
|
||||
- libt1-dev
|
||||
- libzip-dev
|
||||
|
||||
notifications:
|
||||
email:
|
||||
@@ -30,9 +30,8 @@ notifications:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
ccache: true
|
||||
cache:
|
||||
- apt
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -48,14 +47,9 @@ env:
|
||||
- ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1
|
||||
|
||||
before_script:
|
||||
- ccache --version
|
||||
- ccache --zero-stats
|
||||
- export USE_CCACHE=1
|
||||
# Enable IPv6
|
||||
- sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
|
||||
# Compile PHP
|
||||
- ./travis/compile.sh
|
||||
# Setup Extensions
|
||||
# Setup Extensions
|
||||
- . ./travis/ext/mysql/setup.sh
|
||||
- . ./travis/ext/mysqli/setup.sh
|
||||
- . ./travis/ext/pdo_mysql/setup.sh
|
||||
@@ -64,7 +58,4 @@ before_script:
|
||||
|
||||
# Run PHPs run-tests.php
|
||||
script:
|
||||
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
|
||||
|
||||
after_success:
|
||||
- ccache --show-stats
|
||||
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --set-timeout 120
|
||||
+10
-10
@@ -4,9 +4,10 @@
|
||||
|
||||
This file lists several standards that any programmer adding or changing
|
||||
code in PHP should follow. Since this file was added at a very late
|
||||
stage of the development of PHP v3.0, the code base does not fully
|
||||
follow it, but new features are going in that general direction. Many
|
||||
sections have been recoded to use these rules.
|
||||
stage of the development of PHP v3.0, the code base does not (yet) fully
|
||||
follow it, but it's going in that general direction. Since we are now
|
||||
well into version 5 releases, many sections have been recoded to use
|
||||
these rules.
|
||||
|
||||
Code Implementation
|
||||
-------------------
|
||||
@@ -92,12 +93,12 @@ User Functions/Methods Naming Conventions
|
||||
readability of the function name itself::
|
||||
|
||||
Good:
|
||||
'str_word_count'
|
||||
'array_key_exists'
|
||||
'mcrypt_enc_self_test'
|
||||
'mysql_list_fields'
|
||||
|
||||
Ok:
|
||||
'date_interval_create_from_date_string'
|
||||
(could be 'date_intvl_create_from_date_str'?)
|
||||
'mcrypt_module_get_algo_supported_key_sizes'
|
||||
(could be 'mcrypt_mod_get_algo_sup_key_sizes'?)
|
||||
'get_html_translation_table'
|
||||
(could be 'html_get_trans_table'?)
|
||||
|
||||
@@ -297,6 +298,5 @@ highlight_file and show_source), will be separately documented. The
|
||||
proto should still be included, describing which function is aliased.
|
||||
|
||||
Backwards compatible functions and names should be maintained as long
|
||||
as the code can be reasonably be kept as part of the codebase. See the
|
||||
README in the PHP documentation repository for more information on
|
||||
documentation.
|
||||
as the code can be reasonably be kept as part of the codebase. See
|
||||
/phpdoc/README for more information on documentation.
|
||||
+8
-13
@@ -11,20 +11,15 @@ co-ordination.
|
||||
PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to
|
||||
implement RFCs. Please be sure to include tests as appropriate!
|
||||
|
||||
If you are fixing a bug, then please submit your PR against the lowest actively
|
||||
supported branch of PHP that the bug affects (only green branches on
|
||||
[the supported version page](http://php.net/supported-versions.php) are supported).
|
||||
For example, at the time of writing in early-2018, the lowest supported version is
|
||||
PHP 7.1, which corresponds to the `PHP-7.1` branch in Git. Please also make sure you
|
||||
add a link to the PR in the bug on [the bug tracker](https://bugs.php.net/).
|
||||
If you are fixing a bug, then please submit your PR against the lowest branch
|
||||
of PHP that the bug affects, or the oldest fully supported version (the first
|
||||
green branch on
|
||||
[the supported version page](http://php.net/supported-versions.php). For
|
||||
example, at the time of writing in mid-2015, this is PHP 5.5, which corresponds
|
||||
to the `PHP-5.5` branch in Git. Please also make sure you add a link to the PR
|
||||
in the bug on [the bug tracker](https://bugs.php.net/).
|
||||
|
||||
Pull requests implementing RFCs should be submitted against `master`.
|
||||
|
||||
Pull requests should *never* be submitted against `PHP-x.y.z` branches, as
|
||||
these are only used for release management.
|
||||
|
||||
If your pull request exhibits conflicts with the base branch, please resolve them
|
||||
by using `git rebase` instead of `git merge`.
|
||||
Pull requests to implement RFCs should be submitted against `master`.
|
||||
|
||||
## Filing bugs
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
For the list of people who've put work into PHP, please see
|
||||
|
||||
https://www.php.net/credits.php
|
||||
http://www.php.net/credits.php
|
||||
+24
-31
@@ -37,7 +37,7 @@ MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cli
|
||||
MAINTENANCE: Marcus Börger <helly@php.net>, Edin Kadribasic <edink@php.net>
|
||||
MAINTENANCE: Marcus Boerger <helly@php.net>, Edin Kadribasic <edink@php.net>
|
||||
STATUS: Working
|
||||
SINCE: 4.3.0
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -68,7 +68,7 @@ STATUS: 5.6
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dba
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>,Christopher Jones <sixd@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>,Christopher Jones <sixd@php.net>, Pierre-Alain Joye <pajoye@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
|
||||
@@ -79,13 +79,13 @@ MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysqli
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysqlnd
|
||||
PRIMARY MAINTAINER: Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
PRIMARY MAINTAINER: Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
@@ -99,7 +99,7 @@ EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
COMMENT: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Wez Furlong <wez@php.net>
|
||||
@@ -120,7 +120,7 @@ STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_mysql
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Johannes Schlüter <johannes@php.net>, Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Johannes Schlüter <johannes@php.net>, Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
@@ -150,7 +150,7 @@ STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pgsql
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Yasuo Ohgaki <yohgaki@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Yasuo Ohgaki <yohgaki@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
|
||||
@@ -168,13 +168,13 @@ COMMENT: Integrates SQLite 3 embeddable SQL database engine.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dom
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>, Marcus Börger <helly@php.net>
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>, Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: simplexml
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
@@ -195,12 +195,12 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: libxml
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xmlreader
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net>, Christian Stocker <chregu@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -262,14 +262,8 @@ PRIMARY MAINTAINER: Derick Rethans <derick@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: enchant
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: exif
|
||||
PRIMARY MAINTAINER: Kalle Sommer Nielsen <kalle@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.2
|
||||
@@ -287,7 +281,7 @@ STATUS: Working
|
||||
SINCE: 5.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ftp
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
PRIMARY MAINTAINER: Stefan Esser <sesser@php.net>
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -335,7 +329,7 @@ STATUS: Working
|
||||
SINCE: 5.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>, Douglas Goldstein <cardoe@php.net>, Pierre-Alain Joye <pajoye@php.net>, Côme Bernigaud <mcmic@php.net>
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>, Douglas Goldstein <cardoe@php.net>, Pierre-Alain Joye <pajoye@php.net>, Côme Bernigaud <mcmic@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -344,6 +338,11 @@ PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcrypt
|
||||
PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: opcache
|
||||
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>, Xinchen Hui <laruence@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -367,13 +366,13 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: phar
|
||||
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net>, Marcus Börger <helly@php.net>, Steph Fox <sfox@php.net>
|
||||
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net>, Marcus Börger <helly@php.net>, Steph Fox <sfox@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: posix
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -388,12 +387,12 @@ MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: recode
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: reflection
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Johannes Schlüter <johannes@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Johannes Schlüter <johannes@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -419,14 +418,8 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sodium
|
||||
PRIMARY MAINTAINER: Frank Denis <jedisct1@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 7.2.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: spl
|
||||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Etienne Kneuss <colder@php.net>
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Etienne Kneuss <colder@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0.0
|
||||
|
||||
+2
-2
@@ -115,7 +115,7 @@ clean:
|
||||
find . -name \*.la -o -name \*.a | xargs rm -f
|
||||
find . -name \*.so | xargs rm -f
|
||||
find . -name .libs -a -type d|xargs rm -rf
|
||||
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
|
||||
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_MILTER_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h
|
||||
@@ -137,7 +137,7 @@ prof-clean:
|
||||
find . -name \*.lo -o -name \*.o | xargs rm -f
|
||||
find . -name \*.la -o -name \*.a | xargs rm -f
|
||||
find . -name \*.so | xargs rm -f
|
||||
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
|
||||
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_MILTER_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
|
||||
|
||||
prof-use:
|
||||
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-use all
|
||||
|
||||
+161
-17
@@ -1,44 +1,188 @@
|
||||
(NOTE: you may also want to take a look at the pear package
|
||||
PECL_Gen, a PHP-only alternative for this script that
|
||||
supports way more extension writing tasks and is
|
||||
supposed to replace ext_skel completely in the long run ...)
|
||||
|
||||
WHAT IT IS
|
||||
|
||||
It's a tool for automatically creating the basic framework for a PHP extension.
|
||||
It's a tool for automatically creating the basic framework for a PHP module
|
||||
and writing C code handling arguments passed to your functions from a simple
|
||||
configuration file. See an example at the end of this file.
|
||||
|
||||
HOW TO USE IT
|
||||
|
||||
Very simple. First, change to the ext/ directory of the PHP sources. Then
|
||||
run the following
|
||||
Very simple. First, change to the ext/ directory of the PHP 4 sources. If
|
||||
you just need the basic framework and will be writing all the code in your
|
||||
functions yourself, you can now do
|
||||
|
||||
php ext_skel.php --ext extension_name
|
||||
./ext_skel --extname=module_name
|
||||
|
||||
and everything you need will be placed in directory ext/extension_name.
|
||||
and everything you need is placed in directory module_name.
|
||||
|
||||
[ Note that GNU awk is likely required for this script to work. Debian
|
||||
systems seem to default to using mawk, so you may need to change the
|
||||
#! line in skeleton/create_stubs and the cat $proto | awk line in
|
||||
ext_skel to use gawk explicitly. ]
|
||||
|
||||
If you don't need to test the existence of any external header files,
|
||||
libraries or functions in them, the extension is ready to be compiled in
|
||||
PHP. To compile the extension, run the following:
|
||||
libraries or functions in them, the module is already almost ready to be
|
||||
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
|
||||
change back up to PHP sources top directory, and do
|
||||
|
||||
./buildconf; ./configure --enable-extension_name; make
|
||||
./buildconf; ./configure --enable-module_name; make
|
||||
|
||||
The definition of PHP_extension_NAME_VERSION will be present in the
|
||||
php_extension_name.h and injected into the zend_extension_entry definition. This
|
||||
The definition of PHP_MODULE_NAME_VERSION will be present in the
|
||||
php_module_name.h and injected into the zend_module_entry definition. This
|
||||
is required by the PECL website for the version string conformity checks
|
||||
against package.xml
|
||||
|
||||
But if you already have planned the overall scheme of your module, what
|
||||
functions it will contain, their return types and the arguments they take
|
||||
(a very good idea) and don't want to bother yourself with creating function
|
||||
definitions and handling arguments passed yourself, it's time to create a
|
||||
function definitions file, which you will give as an argument to ext_skel
|
||||
with option
|
||||
|
||||
--proto=filename.
|
||||
|
||||
SOURCE AND HEADER FILE NAME
|
||||
|
||||
The ext_skel.php script generates 'extension_name.c' and 'php_extension_name.h'
|
||||
as the main source and header files. Keep these names.
|
||||
./ext_skel generates 'module_name.c' and 'php_module_name.h' as main source
|
||||
and header files. Keep these names.
|
||||
|
||||
extension functions (User functions) must be named
|
||||
Module functions (User functions) must be named
|
||||
|
||||
extension_name_function()
|
||||
module_name_function()
|
||||
|
||||
When you need to expose extension functions to other extensions, expose functions
|
||||
When you need to expose module functions to other modules, expose functions
|
||||
strictly needed by others. Exposed internal function must be named
|
||||
|
||||
php_extension_name_function()
|
||||
php_module_name_function()
|
||||
|
||||
See also CODING_STANDARDS.
|
||||
|
||||
|
||||
FORMAT OF FUNCTION DEFINITIONS FILE
|
||||
|
||||
All the definitions must be on one line. In it's simplest form, it's just
|
||||
the function name, e.g.
|
||||
|
||||
module_name_function
|
||||
|
||||
but then you'll be left with an almost empty function body without any
|
||||
argument handling.
|
||||
|
||||
Arguments are given in parenthesis after the function name, and are of
|
||||
the form 'argument_type argument_name'. Arguments are separated from each
|
||||
other with a comma and optional space. Argument_type can be one of int,
|
||||
bool, double, float, string, array, object or mixed.
|
||||
|
||||
An optional argument is separated from the previous by an optional space,
|
||||
then '[' and of course comma and optional space, like all the other
|
||||
arguments. You should close a row of optional arguments with same amount of
|
||||
']'s as there where '['s. Currently, it does not harm if you forget to do it
|
||||
or there is a wrong amount of ']'s, but this may change in the future.
|
||||
|
||||
An additional short description may be added after the parameters.
|
||||
If present it will be filled into the 'proto' header comments in the stubs
|
||||
code and the <refpurpose> tag in the XML documentation.
|
||||
|
||||
An example:
|
||||
|
||||
module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]])
|
||||
|
||||
Arguments arg1 and arg2 are required.
|
||||
Arguments arg3 and arg4 are optional.
|
||||
|
||||
If possible, the function definition should also contain it's return type
|
||||
in front of the definition. It's not actually used for any C code generating
|
||||
purposes but PHP in-source documentation instead, and as such, very useful.
|
||||
It can be any of int, double, string, bool, array, object, resource, mixed
|
||||
or void.
|
||||
|
||||
The file must contain nothing else but function definitions, no comments or
|
||||
empty lines.
|
||||
|
||||
OTHER OPTIONS
|
||||
|
||||
Run php ext_skel.php --help to see the available options.
|
||||
--no-help
|
||||
|
||||
By default, ext_skel creates both comments in the source code and a test
|
||||
function to help first time module writers to get started and testing
|
||||
configuring and compiling their module. This option turns off all such things
|
||||
which may just annoy experienced PHP module coders. Especially useful with
|
||||
|
||||
--stubs=file
|
||||
|
||||
which will leave out also all module specific stuff and write just function
|
||||
stubs with function value declarations and passed argument handling, and
|
||||
function entries and definitions at the end of the file, for copying and
|
||||
pasting into an already existing module.
|
||||
|
||||
--xml[=file]
|
||||
|
||||
Creates the basics for phpdoc .xml file.
|
||||
|
||||
--full-xml
|
||||
|
||||
Not implemented yet. When or if there will ever be created a framework for
|
||||
self-contained extensions to use phpdoc system for their documentation, this
|
||||
option enables it on the created xml file.
|
||||
|
||||
CURRENT LIMITATIONS, BUGS AND OTHER ODDITIES
|
||||
|
||||
Only arguments of types int, bool, double, float, string and array are
|
||||
handled. For other types you must write the code yourself. And for type
|
||||
mixed, it wouldn't even be possible to write anything, because only you
|
||||
know what to expect.
|
||||
|
||||
It can't handle correctly, and probably never will, variable list of
|
||||
of arguments. (void foo(int bar [, ...])
|
||||
|
||||
Don't trust the generated code too much. It tries to be useful in most of
|
||||
the situations you might encounter, but automatic code generation will never
|
||||
beat a programmer who knows the real situation at hand. ext_skel is generally
|
||||
best suited for quickly generating a wrapper for c-library functions you
|
||||
might want to have available in PHP too.
|
||||
|
||||
This program doesn't have a --help option. It has --no-help instead.
|
||||
|
||||
EXAMPLE
|
||||
|
||||
The following _one_ line
|
||||
|
||||
bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color])
|
||||
|
||||
will create this function definition for you (note that there are a few
|
||||
question marks to be replaced by you, and you must of course add your own
|
||||
value definitions too):
|
||||
|
||||
/* {{{ proto bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color])
|
||||
*/
|
||||
PHP_FUNCTION(module_name_drawtext)
|
||||
{
|
||||
char *text = NULL;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
int image_id = -1;
|
||||
size_t text_len;
|
||||
int font_id = -1;
|
||||
zend_long x;
|
||||
zend_long y;
|
||||
zend_long color;
|
||||
zval *image = NULL;
|
||||
zval *font = NULL;
|
||||
|
||||
if (zend_parse_parameters(argc, "rsrll|l", &image, &text, &text_len, &font, &x, &y, &color) == FAILURE)
|
||||
return;
|
||||
|
||||
if (image) {
|
||||
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
|
||||
}
|
||||
if (font) {
|
||||
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
|
||||
}
|
||||
|
||||
php_error(E_WARNING, "module_name_drawtext: not yet implemented");
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+8
-16
@@ -38,30 +38,22 @@ Having said that, here are the organizational rules::
|
||||
6. Test your changes before committing them. We mean it. Really.
|
||||
To do so use "make test".
|
||||
|
||||
7. For development use the --enable-debug switch to avoid memory leaks
|
||||
and the --enable-maintainer-zts switch to ensure your code handles
|
||||
TSRM correctly and doesn't break for those who need that.
|
||||
7. For development use the --enable-maintainer-zts switch to ensure your
|
||||
code handles TSRM correctly and doesn't break for those who need that.
|
||||
|
||||
Currently we have the following branches in use::
|
||||
|
||||
master The active development branch.
|
||||
master The active development branch.
|
||||
|
||||
PHP-7.2 Is used to release the PHP 7.2.x series. This is a current
|
||||
PHP-5.6 Is used to release the PHP 5.6.x series. This is a current
|
||||
stable version and is open for bugfixes only.
|
||||
|
||||
PHP-7.1 Is used to release the PHP 7.1.x series. This is a current
|
||||
stable version and is open for bugfixes only.
|
||||
|
||||
PHP-7.0 Is used to release the PHP 7.0.x series. This is an old
|
||||
PHP-5.5 Is used to release the PHP 5.5.x series. This is an old
|
||||
stable version and is open for security fixes only.
|
||||
|
||||
PHP-5.6 Is used to release the PHP 5.6.x series. This is an old
|
||||
PHP-5.4 Is used to release the PHP 5.4.x series. This is an old
|
||||
stable version and is open for security fixes only.
|
||||
|
||||
PHP-5.5 This branch is closed.
|
||||
|
||||
PHP-5.4 This branch is closed.
|
||||
|
||||
PHP-5.3 This branch is closed.
|
||||
|
||||
PHP-5.2 This branch is closed.
|
||||
@@ -77,7 +69,7 @@ The next few rules are more of a technical nature::
|
||||
|
||||
1. All changes should first go to the lowest branch (i.e. 5.6) and then
|
||||
get merged up to all other branches. If a change is not needed for
|
||||
later branches (i.e. fixes for features which were dropped from later
|
||||
later branches (i.e. fixes for features which where dropped from later
|
||||
branches) an empty merge should be done.
|
||||
|
||||
2. All news updates intended for public viewing, such as new features,
|
||||
@@ -113,7 +105,7 @@ The format of the commit messages is pretty simple.
|
||||
An Example from the git project (commit 2b34e486bc):
|
||||
|
||||
pack-objects: Fix compilation with NO_PTHREDS
|
||||
|
||||
|
||||
It looks like commit 99fb6e04 (pack-objects: convert to use
|
||||
parse_options(), 2012-02-01) moved the #ifdef NO_PTHREDS around but
|
||||
hasn't noticed that the 'arg' variable no longer is available.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
|
||||
|
||||
|
||||
API adjustment to the old output control code:
|
||||
|
||||
Everything now resides beneath the php_output namespace,
|
||||
@@ -15,7 +18,7 @@ API adjustment to the old output control code:
|
||||
// php_start_ob_buffer(zhandler, chunk_size, erase);
|
||||
php_output_start_user(zhandler, chunk_size, flags);
|
||||
|
||||
Starting an internal handler without context:
|
||||
Starting an internal handler whithout context:
|
||||
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase);
|
||||
php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags);
|
||||
|
||||
|
||||
+22
-150
@@ -1,7 +1,7 @@
|
||||
1. libmagic (ext/fileinfo) see ext/fileinfo/libmagic/LICENSE
|
||||
2. Oniguruma (ext/mbstring) see ext/mbstring/oniguruma/COPYING
|
||||
3. libmbfl (ext/mbstring) see ext/mbstring/libmbfl/LICENSE
|
||||
4. pcre2lib (ext/pcre)
|
||||
4. pcrelib (ext/pcre) see ext/pcre/pcrelib/LICENCE
|
||||
5. ext/standard crypt
|
||||
6. ext/standard crypt's blowfish implementation
|
||||
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
|
||||
@@ -15,107 +15,6 @@
|
||||
15. main/strlcat
|
||||
16. main/strlcpy
|
||||
17. libgd see ext/gd/libgd/COPYING
|
||||
18. ext/phar portions of tar implementations
|
||||
19. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/COPYING.LIB
|
||||
|
||||
|
||||
4. pcre2lib (ext/pcre)
|
||||
|
||||
PCRE2 LICENCE
|
||||
-------------
|
||||
|
||||
PCRE2 is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as
|
||||
specified below, with one exemption for certain binary redistributions. The
|
||||
documentation for PCRE2, supplied in the "doc" directory, is distributed under
|
||||
the same terms as the software itself. The data in the testdata directory is
|
||||
not copyrighted and is in the public domain.
|
||||
|
||||
The basic library functions are written in C and are freestanding. Also
|
||||
included in the distribution is a just-in-time compiler that can be used to
|
||||
optimize pattern matching. This is an optional feature that can be omitted when
|
||||
the library is built.
|
||||
|
||||
|
||||
THE BASIC LIBRARY FUNCTIONS
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
PCRE2 JUST-IN-TIME COMPILATION SUPPORT
|
||||
--------------------------------------
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
STACK-LESS JUST-IN-TIME COMPILER
|
||||
--------------------------------
|
||||
|
||||
Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
THE "BSD" LICENCE
|
||||
-----------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notices,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notices, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of any
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
|
||||
------------------------------------------
|
||||
|
||||
The second condition in the BSD licence (covering binary redistributions) does
|
||||
not apply all the way down a chain of software. If binary package A includes
|
||||
PCRE2, it must respect the condition, but if package B is software that
|
||||
includes package A, the condition is not imposed on package B unless it uses
|
||||
PCRE2 independently.
|
||||
|
||||
End
|
||||
|
||||
|
||||
5. ext/standard crypt
|
||||
|
||||
@@ -147,7 +46,7 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
6. ext/standard crypt's blowfish implementation
|
||||
|
||||
@@ -193,7 +92,7 @@ http://www.usenix.org/events/usenix99/provos.html
|
||||
Some of the tricks in BF_ROUND might be inspired by Eric Young's
|
||||
Blowfish library (I can't be sure if I would think of something if I
|
||||
hadn't seen his code).
|
||||
|
||||
|
||||
|
||||
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
|
||||
|
||||
@@ -227,7 +126,7 @@ Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
Copyright (C) 2000 - 2003, Richard J. Wagner
|
||||
All rights reserved.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@@ -240,8 +139,8 @@ are met:
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@@ -362,26 +261,26 @@ SUCH DAMAGE.
|
||||
|
||||
12. libxmlrpc ext/xmlrpc
|
||||
|
||||
Copyright 2000 Epinions, Inc.
|
||||
Copyright 2000 Epinions, Inc.
|
||||
|
||||
Subject to the following 3 conditions, Epinions, Inc. permits you, free
|
||||
of charge, to (a) use, copy, distribute, modify, perform and display this
|
||||
software and associated documentation files (the "Software"), and (b)
|
||||
permit others to whom the Software is furnished to do so as well.
|
||||
Subject to the following 3 conditions, Epinions, Inc. permits you, free
|
||||
of charge, to (a) use, copy, distribute, modify, perform and display this
|
||||
software and associated documentation files (the "Software"), and (b)
|
||||
permit others to whom the Software is furnished to do so as well.
|
||||
|
||||
1) The above copyright notice and this permission notice shall be included
|
||||
without modification in all copies or substantial portions of the
|
||||
Software.
|
||||
1) The above copyright notice and this permission notice shall be included
|
||||
without modification in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
|
||||
ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
|
||||
IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE OR NONINFRINGEMENT.
|
||||
2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
|
||||
ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
|
||||
IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE OR NONINFRINGEMENT.
|
||||
|
||||
3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
|
||||
NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
|
||||
3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
|
||||
NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
13. libzip ext/zip
|
||||
@@ -516,30 +415,3 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
18. ext/phar portions of tar implementations
|
||||
|
||||
portions of tar implementations in ext/phar - phar_tar_octal() are based on an
|
||||
implementation by Tim Kientzle from libarchive, licensed with this license:
|
||||
|
||||
Copyright (c) 2003-2007 Tim Kientzle
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+39
-95
@@ -37,7 +37,7 @@ Most developers should have this.
|
||||
Moving extensions from php-src to PECL
|
||||
- Checkout the pecl directory, most likely you want a sparse-root checkout
|
||||
svn co --depth=empty https://svn.php.net/repository/pecl
|
||||
- Create a directory for the extension incl. branch and tag structure,
|
||||
- Create an directory for the extension incl. branch and tag structure,
|
||||
no trunk at this point and commit this to svn
|
||||
cd pecl; mkdir foo foo/tags foo/branches; svn add foo; svn commit
|
||||
- Move the extension from php-src to the new location
|
||||
@@ -50,7 +50,7 @@ maintainers if any:
|
||||
- create the package.xml, commit
|
||||
- release the package
|
||||
|
||||
For Moving extensions from PECL to php-src the svn mv has to be done the other
|
||||
For Moving extensions from PECL to php-src the svn mv has to be tone the other
|
||||
way round.
|
||||
|
||||
Rolling a non stable release (alpha/beta/RC)
|
||||
@@ -65,7 +65,7 @@ credits files in ext/standard.
|
||||
|
||||
4. Checkout the release branch for this release (e.g., PHP-5.4.2) from the main branch.
|
||||
|
||||
5. Bump the version numbers in ``main/php_version.h``, ``configure.ac`` and possibly ``NEWS``.
|
||||
5. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
Do not use abbreviations for alpha and beta. Do not use dashes, you should
|
||||
``#define PHP_VERSION "5.4.22RC1"`` and not ``#define PHP_VERSION "5.4.22-RC1"``
|
||||
|
||||
@@ -79,7 +79,7 @@ Do not use abbreviations for alpha and beta. Do not use dashes, you should
|
||||
9. Tag the repository release branch with the version, e.g.:
|
||||
``git tag -u YOURKEYID php-5.4.2RC2``
|
||||
|
||||
10. Bump the version numbers in ``main/php_version.h``, ``configure.ac`` and ``NEWS``
|
||||
10. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and ``NEWS``
|
||||
in the *main* branch (PHP-5.4 for example) to prepare for the **next** version.
|
||||
F.e. if the RC is "5.4.1RC1" then the new one should be "5.4.2-dev" - regardless if we get
|
||||
a new RC or not. This is to make sure ``version_compare()`` can correctly work.
|
||||
@@ -97,57 +97,27 @@ and build three tarballs (gz, bz2 and xz).
|
||||
and output verification information to be included in announcement email
|
||||
|
||||
14. Copy those tarballs (scp, rsync) to downloads.php.net, in your homedir there should be a
|
||||
directory "public_html/". Copy them into there, so that the system can generate
|
||||
MD5 sums. If you do not have this directory, create it.
|
||||
directory "downloads/". Copy them into there, so that the system can generate
|
||||
MD5 sums. If you do not have this directory, talk to Derick or Dan.
|
||||
|
||||
15. Now the RC can be found on http://downloads.php.net/~yourname,
|
||||
f.e. http://downloads.php.net/~derick/
|
||||
15. Now the RC can be found on http://downloads.php.net/yourname,
|
||||
f.e. http://downloads.php.net/derick/
|
||||
|
||||
16. Once the release has been tagged, contact the release-managers@ distribution list
|
||||
so that Windows binaries can be created. Once those are made, they can be found at
|
||||
http://windows.php.net/download
|
||||
16. Once the release has been tagged, contact the PHP Windows development team
|
||||
(internals-win@lists.php.net) so that Windows binaries can be created. Once
|
||||
those are made, they should be placed into the same directory as the source snapshots.
|
||||
|
||||
Getting the non stable release (alpha/beta/RC) announced
|
||||
--------------------------------------------------------
|
||||
|
||||
1. Update ``qa.git/include/release-qa.php`` with the appropriate information.
|
||||
See the documentation within release-qa.php for more information, but all releases
|
||||
and RCs are configured here. Only $QA_RELEASES needs to be edited.
|
||||
|
||||
Example: When rolling an RC, set the 'rc' with appropriate information for the
|
||||
given version.
|
||||
|
||||
Note: Remember to update the MD5 and sha256 checksum information.
|
||||
|
||||
2. Update ``web/php.git/include/version.inc`` (x=major version number)
|
||||
|
||||
a. ``$PHP_x_RC`` = "5.4.0RC1" (should be set to "false" before)
|
||||
|
||||
b. ``$PHP_x_RC_DATE`` = "06 September 2007"
|
||||
|
||||
3. Add a short notice to phpweb stating that there is a new release, and
|
||||
highlight the major important things (security fixes) and when it is important
|
||||
to upgrade.
|
||||
|
||||
a. Call php bin/createNewsEntry in your local phpweb checkout
|
||||
Use category "releases" for all stable releases.
|
||||
Use category "frontpage" for X.Y.0 non-stable releases only (news only).
|
||||
|
||||
b. Add the content for the news entry. Be sure to include the text:
|
||||
"THIS IS A DEVELOPMENT PREVIEW - DO NOT USE IT IN PRODUCTION!"
|
||||
|
||||
4. Commit and push changes to qa and web
|
||||
|
||||
*Wait for web and qa sites to update with new information before sending announce*
|
||||
|
||||
5. Send **separate** emails **To** ``internals@lists.php.net`` and ``php-general@lists.php.net``
|
||||
1. Send an email **To** ``internals@lists.php.net`` and ``php-general@lists.php.net``
|
||||
lists pointing out "the location of the release" and "the possible release date of
|
||||
either the next RC, or the final release". Include in this information the verification
|
||||
information output by ``gen_verify_stub``.
|
||||
|
||||
6. Send **separate** emails (see example here http://news.php.net/php.pear.qa/5201) **To**
|
||||
2. Send an email (see example here http://news.php.net/php.pear.qa/5201) **To**
|
||||
``php-qa@lists.php.net`` and ``primary-qa-tester@lists.php.net``.
|
||||
This emails are to notify the selected projects about a new release so that they
|
||||
This email is to notify the selected projects about a new release so that they
|
||||
can make sure their projects keep working. Make sure that you have been setup
|
||||
as a moderator for ``primary-qa-tester@lists.php.net`` by having someone (Hannes, Dan,
|
||||
Derick) run the following commands for you:
|
||||
@@ -156,11 +126,33 @@ Derick) run the following commands for you:
|
||||
|
||||
``sudo -u ezmlm ezmlm-sub ~ezmlm/primary-qa-tester/mod moderator-email-address``
|
||||
|
||||
3. Update ``qa.git/include/release-qa.php`` with the appropriate information.
|
||||
See the documentation within release-qa.php for more information, but all releases
|
||||
and RCs are configured here. Only $QA_RELEASES needs to be edited.
|
||||
|
||||
Example: When rolling an RC, set the 'rc' with appropriate information for the
|
||||
given version.
|
||||
|
||||
Note: Remember to update the MD5 checksum information.
|
||||
|
||||
4. Update ``web/php.git/include/version.inc`` (x=major version number)
|
||||
|
||||
a. ``$PHP_x_RC`` = "5.4.0RC1" (should be set to "false" before)
|
||||
|
||||
b. ``$PHP_x_RC_DATE`` = "06 September 2007"
|
||||
|
||||
5. Commit and push those changes:
|
||||
|
||||
a. ``git commit -a && git push origin master``
|
||||
|
||||
6. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the
|
||||
INSTALL and win32/install.txt files which are generated from the PHP manual sources.
|
||||
|
||||
Rolling a stable release
|
||||
------------------------
|
||||
|
||||
1. Checkout your release branch, you should have created when releasing previous RC
|
||||
and bump the version numbers in ``main/php_version.h``, ``configure.ac`` and possibly ``NEWS``.
|
||||
and bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
|
||||
|
||||
2. If a CVE commit needs to be merged to the release, then have it committed to
|
||||
the base branches and merged upwards as usual (f.e commit the CVE fix to 5.3,
|
||||
@@ -184,11 +176,7 @@ credits files in ext/standard.
|
||||
|
||||
9. run: ``PHPROOT=. ./makedist php 5.4.1``, this will export the tag, create configure
|
||||
and build three tarballs (gz, bz2 and xz).
|
||||
Check if the pear files are updated (phar).
|
||||
On some systems the behavior of GNU tar can default to produce POSIX compliant archives
|
||||
with PAX headers. As not every application is compatible with that format, creation of
|
||||
archives with PAX headers should be avoided. When packaging on such a system, the GNU tar
|
||||
can be influenced by defining the environment variable TAR_OPTIONS='--format=gnu'.
|
||||
Check if the pear files are updated (phar).
|
||||
|
||||
10. Generate the GPG signature files for the archives.
|
||||
``gpg -u YOUREMAIL --armor --detach-sign php-X.Y.Z.tar.xxx``
|
||||
@@ -198,8 +186,7 @@ can be influenced by defining the environment variable TAR_OPTIONS='--format=gnu
|
||||
``git submodule init;
|
||||
git submodule update;
|
||||
cd distributions;
|
||||
git fetch;
|
||||
git pull --rebase origin master;
|
||||
git pull origin master;
|
||||
cd ..;
|
||||
git commit distributions;
|
||||
git push;``
|
||||
@@ -328,46 +315,3 @@ the news entry.
|
||||
Please make sure that the mail to php-announce@ is its own completely separate email.
|
||||
This is to make sure that replies to the announcement on php-general@ or internals@
|
||||
will not accidentally hit the php-announce@ mailinglist.
|
||||
|
||||
Forking a new release branch
|
||||
----------------------------
|
||||
|
||||
1. One week prior to cutting X.Y.0beta1, warn internals@ that your version's branch
|
||||
is about to be cut, and that PHP-X.Y will be moving into feature freeze.
|
||||
Try to be specific about when the branch will be cut.
|
||||
Example: http://news.php.net/php.internals/99864
|
||||
|
||||
2. Just prior to cutting X.Y.0beta1, create the new branch locally.
|
||||
Add a commit on master after the branch point clearing the NEWS file, and updating
|
||||
main/php_versions.h and Zend/zend.h to update versions.
|
||||
Example: https://github.com/php/php-src/commit/5230541ef59e0637d5522293a7d099bf18ce6af3
|
||||
Push the new branch and the commit just added to master.
|
||||
|
||||
3. Immediately notify internals@ of the branch cut and advise the new merging order:
|
||||
Example: http://news.php.net/php.internals/99903
|
||||
|
||||
4. Update php-web:git.php and wiki.php.net/vcs/gitworkflow to reflect the new branch:
|
||||
Example: https://github.com/php/web-php/commit/74bcad4c770d95f21b7fbeeedbd76d943bb83f23
|
||||
|
||||
5. Notify nlopess@ to add PHP_X_Y tag to gcov.php.net
|
||||
|
||||
New Release Manager Checklist
|
||||
-----------------------------
|
||||
|
||||
1. Email systems@ to get setup for access to downloads.php.net and to be added to the
|
||||
release-managers@ distribution list.
|
||||
|
||||
2. Create a GPG key for your @php.net address and publish it by editing `include/gpg-keys.inc`
|
||||
in the `web-php` repository, adding the output of `gpg --fingerprint "$USER@php.net"`. Let
|
||||
one or more of the previous RMs sign your key. Publish your public key to pgp.mit.edu with:
|
||||
`gpg --keyserver pgp.mit.edu --send-keys $KEYID`
|
||||
|
||||
3. Request karma to edit main/php_version.h. Possibly karma for other restricted parts of
|
||||
php-src might come in question.
|
||||
|
||||
4. Request karma for web/qa.git and web/php.git for publishing release announcements.
|
||||
|
||||
5. Request moderation access to announce@php.net and primary-qa-tester@lists.php.net lists, to
|
||||
be able to moderate your release announcements. All the announcements should be sent from
|
||||
the @php.net alias.
|
||||
|
||||
+9
-144
@@ -9,7 +9,7 @@ it failed on your system without providing substantial backup information
|
||||
on *why* the test failed on your special setup. Thank you :-)
|
||||
|
||||
|
||||
[Testing Basics]
|
||||
[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
|
||||
@@ -36,7 +36,7 @@ If you are running the run-tests.php script from the command line (as above)
|
||||
you must set the TEST_PHP_EXECUTABLE environment variable to explicitly
|
||||
select the PHP executable that is to be tested, that is, used to run the test scripts.
|
||||
|
||||
If you run the tests using make test, the PHP CLI and CGI executables are
|
||||
If you run the tests using make test, the PHP CLI and CGI executables are
|
||||
automatically set for you. "make test" executes "run-tests.php" script with the CLI binary. Some
|
||||
test scripts such as session must be executed by CGI SAPI. Therefore,
|
||||
you must build PHP with CGI SAPI to perform all tests.
|
||||
@@ -61,8 +61,8 @@ test scripts by extracting all directories named "tests"
|
||||
from the source root and any subdirectories below. If there are files,
|
||||
which have a "phpt" extension, "run-tests.php" looks at the sections
|
||||
in these files, determines whether it should run it, by evaluating
|
||||
the 'SKIPIF' section. If the test is eligible for execution, the 'FILE'
|
||||
section is extracted into a ".php" file (with the same name besides
|
||||
the 'SKIP' section. If the test is eligible for execution, the 'FILE'
|
||||
section is extracted into a ".php" file (with the same name besides
|
||||
the extension) and gets executed.
|
||||
When an argument is given or TESTS environment variable is set, the
|
||||
GLOB is expanded by the shell and any file with extension "*.phpt" is
|
||||
@@ -77,9 +77,9 @@ Examples:
|
||||
|
||||
[Test results]
|
||||
--------------
|
||||
Test results are printed to standard output. If there is a failed test,
|
||||
Test results are printed to standard output. If there is a failed test,
|
||||
the "run-tests.php" script saves the result, the expected result and the
|
||||
code executed to the test script directory. For example, if
|
||||
code executed to the test script directory. For example, if
|
||||
ext/myext/tests/myext.phpt fails to pass, the following files are created:
|
||||
|
||||
ext/myext/tests/myext.php - actual test file executed
|
||||
@@ -151,20 +151,20 @@ advised to test for non-zero, rather then a specific value.
|
||||
|
||||
[Creating new test files]
|
||||
-------------------------
|
||||
Writing test file is very easy if you are used to PHP.
|
||||
Writing test file is very easy if you are used to PHP.
|
||||
See the HOWTO at http://qa.php.net/write-test.php
|
||||
|
||||
|
||||
[How to help us]
|
||||
----------------
|
||||
If you find bug in PHP, you can submit bug report AND test script
|
||||
If you find bug in PHP, you can submit bug report AND test script
|
||||
for us. You don't have to write complete script, just give us test
|
||||
script with following format. Please test the script and make sure
|
||||
you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
|
||||
submit.
|
||||
|
||||
<?php
|
||||
/*
|
||||
/*
|
||||
Bug #12345
|
||||
substr() bug. Do not return expected string.
|
||||
|
||||
@@ -179,138 +179,3 @@ $str = "XYZABCD";
|
||||
echo substr($str,3,7);
|
||||
|
||||
?>
|
||||
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
This is an addendum to README.TESTING with additional information
|
||||
specific to server-tests.php.
|
||||
|
||||
server-tests.php is backward compatible with tests developed for
|
||||
the original run-tests.php script. server-tests is *not* used by
|
||||
'make test'. server-tests was developed to provide support for
|
||||
testing PHP under it's primary environment, HTTP, and can run the
|
||||
PHP tests under any of the SAPI modules that are direct executables,
|
||||
or are accessible via HTTP.
|
||||
|
||||
[New features]
|
||||
----------------
|
||||
* Command line interface:
|
||||
You can run 'php server-tests.php -h' to get all the possible options.
|
||||
* Configuration file:
|
||||
the -c argument will allow you to use a configuration file. This is
|
||||
handy if you are testing multiple environments and need various options
|
||||
depending on the environment.
|
||||
see server-tests-config.php for details.
|
||||
* CGI Emulation:
|
||||
Will emulate a CGI environment when testing with the cgi sapi executable.
|
||||
* HTTP testing:
|
||||
can be configured to run test scripts through an HTTP server running
|
||||
on localhost. localhost is required since either the web server must
|
||||
alias a directory to the php source directory, or the test scripts
|
||||
must be copied to a directory under the web server
|
||||
(see config options TEST_WEB_BASE_URL, TEST_BASE_PATH, and TEST_WEB_EXT)
|
||||
* New sections supported for test files (see below)
|
||||
|
||||
When running tests over http, tests that require ini settings different that what
|
||||
the web server runs under will be skipped. Since the test harness defines a number
|
||||
of ini settings by default, the web server may require special configuration to
|
||||
make testing work.
|
||||
|
||||
[Example Usage]
|
||||
----------------
|
||||
Some (but not all!) examples of usage:
|
||||
|
||||
1. run tests from the php source directory
|
||||
php server-tests.php -p /path/to/php-cli
|
||||
|
||||
2. run tests using cgi emulation
|
||||
php server-tests.php -p /path/to/php-cgi
|
||||
|
||||
3. run tests over http, copying test files into document root
|
||||
php server-tests.php -w -u http://localhost/test -m /path/to/htdocs/test
|
||||
|
||||
4. run tests over http, php sources have been aliased in web server
|
||||
php server-tests.php -w -u http://localhost/test
|
||||
|
||||
5. run tests using configuration file
|
||||
php server-tests.php -c /path/to/server-tests-config.php
|
||||
|
||||
6. run tests using configuration file, but overriding some settings:
|
||||
(config file must be first)
|
||||
php server-tests.php -c /path/to/server-tests-config.php -w -t 3 -d /path/to/testdir
|
||||
|
||||
NOTE: configuration as described in README.TESTING still works.
|
||||
|
||||
[New Test Sections]
|
||||
----------------
|
||||
In addition to the traditional test sections
|
||||
(see http://qa.php.net/write-test.php), several new sections are available
|
||||
under server-tests.
|
||||
|
||||
--POST--
|
||||
This is not a new section, but not multipart posts are supported for testing
|
||||
file uploads, or other types of POST data.
|
||||
|
||||
--CGI--
|
||||
This section takes no value. It merely provides a simple marker for tests
|
||||
that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
|
||||
in the test file.
|
||||
|
||||
--DESCRIPTION--
|
||||
Not used for anything, just a section for documenting the test
|
||||
|
||||
--ENV--
|
||||
This section get's eval()'d to help build an environment for the
|
||||
execution of the test. This can be used to change environment
|
||||
vars that are used for CGI emulation, or simply to set env vars
|
||||
for cli testing. A full example looks like:
|
||||
|
||||
--ENV--
|
||||
return <<<END
|
||||
PATH_TRANSLATED=$filename
|
||||
PATH_INFO=$scriptname
|
||||
SCRIPT_NAME=$scriptname
|
||||
END;
|
||||
|
||||
Some variables are made easily available for use in this section, they
|
||||
include:
|
||||
$filename full native path to file, will become PATH_TRANSLATED
|
||||
$filepath =dirname($filename)
|
||||
$scriptname this is what will become SCRIPT_NAME unless you override it
|
||||
$docroot the equivalent of DOCUMENT_ROOT under Apache
|
||||
$cwd the directory that the test is being initiated from
|
||||
$this->conf all server-tests configuration vars
|
||||
$this->env all environment variables that will get passed to the test
|
||||
|
||||
|
||||
--REQUEST--
|
||||
This section is also eval'd, and is similar in nature to --ENV--. However,
|
||||
this section is used to build the url used in an HTTP request. Valid values
|
||||
to set in this section would include:
|
||||
SCRIPT_NAME The initial part of the request url
|
||||
PATH_INFO The pathinfo part of a request url
|
||||
FRAGMENT The fragment section of a url (after #)
|
||||
QUERY_STRING The query part of a url (after ?)
|
||||
|
||||
--REQUEST--
|
||||
return <<<END
|
||||
PATH_INFO=/path/info
|
||||
END;
|
||||
|
||||
--HEADERS--
|
||||
This section is also eval'd. It is used to provide additional headers sent
|
||||
in an HTTP request, such as content type for multipart posts, cookies, etc.
|
||||
|
||||
--HEADERS--
|
||||
return <<<END
|
||||
Content-Type=multipart/form-data; boundary=---------------------------240723202011929
|
||||
Content-Length=100
|
||||
END;
|
||||
|
||||
--EXPECTHEADERS--
|
||||
This section can be used to define what headers are required to be
|
||||
received back from a request, and is checked in addition to the
|
||||
regular expect sections. For example:
|
||||
|
||||
--EXPECTHEADERS--
|
||||
Status: 404
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
This is an addendum to README.TESTING with additional information
|
||||
specific to server-tests.php.
|
||||
|
||||
server-tests.php is backward compatible with tests developed for
|
||||
the original run-tests.php script. server-tests is *not* used by
|
||||
'make test'. server-tests was developed to provide support for
|
||||
testing PHP under it's primary environment, HTTP, and can run the
|
||||
PHP tests under any of the SAPI modules that are direct executables,
|
||||
or are accessible via HTTP.
|
||||
|
||||
[New features]
|
||||
----------------
|
||||
* Command line interface:
|
||||
You can run 'php server-tests.php -h' to get all the possible options.
|
||||
* Configuration file:
|
||||
the -c argument will allow you to use a configuration file. This is
|
||||
handy if you are testing multiple environments and need various options
|
||||
depending on the environment.
|
||||
see server-tests-config.php for details.
|
||||
* CGI Emulation:
|
||||
Will emulate a CGI environment when testing with the cgi sapi executable.
|
||||
* HTTP testing:
|
||||
can be configured to run test scripts through an HTTP server running
|
||||
on localhost. localhost is required since either the web server must
|
||||
alias a directory to the php source directory, or the test scripts
|
||||
must be copied to a directory under the web server
|
||||
(see config options TEST_WEB_BASE_URL, TEST_BASE_PATH, and TEST_WEB_EXT)
|
||||
* New sections supported for test files (see below)
|
||||
|
||||
When running tests over http, tests that require ini settings different that what
|
||||
the web server runs under will be skipped. Since the test harness defines a number
|
||||
of ini settings by default, the web server may require special configuration to
|
||||
make testing work.
|
||||
|
||||
[Example Usage]
|
||||
----------------
|
||||
Some (but not all!) examples of usage:
|
||||
|
||||
1. run tests from the php source directory
|
||||
php server-tests.php -p /path/to/php-cli
|
||||
|
||||
2. run tests using cgi emulation
|
||||
php server-tests.php -p /path/to/php-cgi
|
||||
|
||||
3. run tests over http, copying test files into document root
|
||||
php server-tests.php -w -u http://localhost/test -m /path/to/htdocs/test
|
||||
|
||||
4. run tests over http, php sources have been aliased in web server
|
||||
php server-tests.php -w -u http://localhost/test
|
||||
|
||||
5. run tests using configuration file
|
||||
php server-tests.php -c /path/to/server-tests-config.php
|
||||
|
||||
6. run tests using configuration file, but overriding some settings:
|
||||
(config file must be first)
|
||||
php server-tests.php -c /path/to/server-tests-config.php -w -t 3 -d /path/to/testdir
|
||||
|
||||
NOTE: configuration as described in README.TESTING still works.
|
||||
|
||||
[New Test Sections]
|
||||
----------------
|
||||
In addition to the traditional test sections
|
||||
(see http://qa.php.net/write-test.php), several new sections are available
|
||||
under server-tests.
|
||||
|
||||
--POST--
|
||||
This is not a new section, but not multipart posts are supported for testing
|
||||
file uploads, or other types of POST data.
|
||||
|
||||
--CGI--
|
||||
This section takes no value. It merely provides a simple marker for tests
|
||||
that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
|
||||
in the test file.
|
||||
|
||||
--DESCRIPTION--
|
||||
Not used for anything, just a section for documenting the test
|
||||
|
||||
--ENV--
|
||||
This section get's eval()'d to help build an environment for the
|
||||
execution of the test. This can be used to change environment
|
||||
vars that are used for CGI emulation, or simply to set env vars
|
||||
for cli testing. A full example looks like:
|
||||
|
||||
--ENV--
|
||||
return <<<END
|
||||
PATH_TRANSLATED=$filename
|
||||
PATH_INFO=$scriptname
|
||||
SCRIPT_NAME=$scriptname
|
||||
END;
|
||||
|
||||
Some variables are made easily available for use in this section, they
|
||||
include:
|
||||
$filename full native path to file, will become PATH_TRANSLATED
|
||||
$filepath =dirname($filename)
|
||||
$scriptname this is what will become SCRIPT_NAME unless you override it
|
||||
$docroot the equivalent of DOCUMENT_ROOT under Apache
|
||||
$cwd the directory that the test is being initiated from
|
||||
$this->conf all server-tests configuration vars
|
||||
$this->env all environment variables that will get passed to the test
|
||||
|
||||
|
||||
--REQUEST--
|
||||
This section is also eval'd, and is similar in nature to --ENV--. However,
|
||||
this section is used to build the url used in an HTTP request. Valid values
|
||||
to set in this section would include:
|
||||
SCRIPT_NAME The initial part of the request url
|
||||
PATH_INFO The pathinfo part of a request url
|
||||
FRAGMENT The fragment section of a url (after #)
|
||||
QUERY_STRING The query part of a url (after ?)
|
||||
|
||||
--REQUEST--
|
||||
return <<<END
|
||||
PATH_INFO=/path/info
|
||||
END;
|
||||
|
||||
--HEADERS--
|
||||
This section is also eval'd. It is used to provide additional headers sent
|
||||
in an HTTP request, such as content type for multipart posts, cookies, etc.
|
||||
|
||||
--HEADERS--
|
||||
return <<<END
|
||||
Content-Type=multipart/form-data; boundary=---------------------------240723202011929
|
||||
Content-Length=100
|
||||
END;
|
||||
|
||||
--EXPECTHEADERS--
|
||||
This section can be used to define what headers are required to be
|
||||
received back from a request, and is checked in addition to the
|
||||
regular expect sections. For example:
|
||||
|
||||
--EXPECTHEADERS--
|
||||
Status: 404
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The Win32 Build System.
|
||||
|
||||
See https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2
|
||||
See http://wiki.php.net/internals/windows/stepbystepbuild
|
||||
|
||||
vim:tw=78:sw=1:ts=1:et
|
||||
|
||||
@@ -86,6 +86,7 @@ PHP_MINFO_FUNCTION(my_input_filter)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
|
||||
php_info_print_table_row( 2, "Revision", "$Id$");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ The PHP Interpreter
|
||||
===================
|
||||
|
||||
This is the github mirror of the official PHP repository located at
|
||||
https://git.php.net.
|
||||
http://git.php.net.
|
||||
|
||||
[](http://travis-ci.org/php/php-src)
|
||||
[](https://ci.appveyor.com/project/php/php-src)
|
||||
@@ -28,7 +28,7 @@ open a ticket at https://bugs.php.net and reference the bug id using #NNNNNN.
|
||||
time. The patch removes this warning
|
||||
|
||||
We do not merge pull requests directly on github. All PRs will be
|
||||
pulled and pushed through https://git.php.net.
|
||||
pulled and pushed through http://git.php.net.
|
||||
|
||||
|
||||
Guidelines for contributors
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
Design
|
||||
======
|
||||
|
||||
Main assumption of the model is that the problem that we are to solve is the
|
||||
problem of the very long class names in PHP libraries. We would not attempt
|
||||
to take autoloader's job or create packaging model - only make names
|
||||
manageable.
|
||||
|
||||
Namespaces are defined the following way:
|
||||
|
||||
Zend/DB/Connection.php:
|
||||
<?php
|
||||
namespace Zend\DB;
|
||||
|
||||
class Connection {
|
||||
}
|
||||
|
||||
function connect() {
|
||||
}
|
||||
?>
|
||||
|
||||
Namespace definition does the following:
|
||||
All class and function names inside are automatically prefixed with
|
||||
namespace name. Inside namespace, local name always takes precedence over
|
||||
global name. Several files may be using the same namespace.
|
||||
The namespace declaration statement must be the very first statement in
|
||||
the file. The only exception is "declare" statement that can be used before.
|
||||
|
||||
Every class and function in a namespace can be referred to by the full name
|
||||
- e.g. Zend\DB\Connection or Zend\DB\connect - at any time.
|
||||
|
||||
<?php
|
||||
require 'Zend/Db/Connection.php';
|
||||
$x = new Zend\DB\Connection;
|
||||
Zend\DB\connect();
|
||||
?>
|
||||
|
||||
Namespace or class name can be imported:
|
||||
|
||||
<?php
|
||||
require 'Zend/Db/Connection.php';
|
||||
use Zend\DB;
|
||||
use Zend\DB\Connection as DbConnection;
|
||||
|
||||
$x = new Zend\DB\Connection();
|
||||
$y = new DB\connection();
|
||||
$z = new DbConnection();
|
||||
DB\connect();
|
||||
?>
|
||||
|
||||
The use statement only defines name aliasing. It may create name alias for
|
||||
namespace or class. The simple form of statement "use A\B\C\D;" is
|
||||
equivalent to "use A\B\C\D as D;". The use statement can be used at any
|
||||
time in the global scope (not inside function/class) and takes effect from
|
||||
the point of definition down to the end of file. It is recommended however to
|
||||
place the use statements at the beginning of the file. The use statements have
|
||||
effect only on the file where they appear.
|
||||
|
||||
The special "empty" namespace (\ prefix) is useful as explicit global
|
||||
namespace qualification. All class and function names started from \
|
||||
interpreted as global.
|
||||
|
||||
<?php
|
||||
namespace A\B\C;
|
||||
|
||||
$con = \mysql_connect(...);
|
||||
?>
|
||||
|
||||
A special constant __NAMESPACE__ contains the name of the current namespace.
|
||||
It can be used to construct fully-qualified names to pass them as callbacks.
|
||||
|
||||
<?php
|
||||
namespace A\B\C;
|
||||
|
||||
function foo() {
|
||||
}
|
||||
|
||||
set_error_handler(__NAMESPACE__ . "\foo");
|
||||
?>
|
||||
|
||||
In global namespace __NAMESPACE__ constant has the value of empty string.
|
||||
|
||||
Names inside namespace are resolved according to the following rules:
|
||||
|
||||
1) all qualified names are translated during compilation according to
|
||||
current import rules. So if we have "use A\B\C" and then "C\D\e()"
|
||||
it is translated to "A\B\C\D\e()".
|
||||
2) unqualified class names translated during compilation according to
|
||||
current import rules. So if we have "use A\B\C" and then "new C()" it
|
||||
is translated to "new A\B\C()".
|
||||
3) inside namespace, calls to unqualified functions that are defined in
|
||||
current namespace (and are known at the time the call is parsed) are
|
||||
interpreted as calls to these namespace functions.
|
||||
4) inside namespace, calls to unqualified functions that are not defined
|
||||
in current namespace are resolved at run-time. The call to function foo()
|
||||
inside namespace (A\B) first tries to find and call function from current
|
||||
namespace A\B\foo() and if it doesn't exist PHP tries to call internal
|
||||
function foo(). Note that using foo() inside namespace you can call only
|
||||
internal PHP functions, however using \foo() you are able to call any
|
||||
function from the global namespace.
|
||||
5) unqualified class names are resolved at run-time. E.q. "new Exception()"
|
||||
first tries to use (and autoload) class from current namespace and in case
|
||||
of failure uses internal PHP class. Note that using "new A" in namespace
|
||||
you can only create class from this namespace or internal PHP class, however
|
||||
using "new \A" you are able to create any class from the global namespace.
|
||||
6) Calls to qualified functions are resolved at run-time. Call to
|
||||
A\B\foo() first tries to call function foo() from namespace A\B, then
|
||||
it tries to find class A\B (__autoload() it if necessary) and call its
|
||||
static method foo()
|
||||
7) qualified class names are interpreted as class from corresponding
|
||||
namespace. So "new A\B\C()" refers to class C from namespace A\B.
|
||||
|
||||
Examples
|
||||
--------
|
||||
<?php
|
||||
namespace A;
|
||||
foo(); // first tries to call "foo" defined in namespace "A"
|
||||
// then calls internal function "foo"
|
||||
\foo(); // calls function "foo" defined in global scope
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
new B(); // first tries to create object of class "B" defined in namespace "A"
|
||||
// then creates object of internal class "B"
|
||||
new \B(); // creates object of class "B" defined in global scope
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
new A(); // first tries to create object of class "A" from namespace "A" (A\A)
|
||||
// then creates object of internal class "A"
|
||||
?>
|
||||
|
||||
<?php
|
||||
namespace A;
|
||||
B\foo(); // first tries to call function "foo" from namespace "A\B"
|
||||
// then calls method "foo" of internal class "B"
|
||||
\B\foo(); // first tries to call function "foo" from namespace "B"
|
||||
// then calls method "foo" of class "B" from global scope
|
||||
?>
|
||||
|
||||
The worst case if class name conflicts with namespace name
|
||||
<?php
|
||||
namespace A;
|
||||
A\foo(); // first tries to call function "foo" from namespace "A\A"
|
||||
// then tries to call method "foo" of class "A" from namespace "A"
|
||||
// then tries to call function "foo" from namespace "A"
|
||||
// then calls method "foo" of internal class "A"
|
||||
\A\foo(); // first tries to call function "foo" from namespace "A"
|
||||
// then calls method "foo" of class "A" from global scope
|
||||
?>
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
* Support for namespace constants?
|
||||
|
||||
* performance problems
|
||||
- calls to internal functions in namespaces are slower, because PHP first
|
||||
looks for such function in current namespace
|
||||
- calls to static methods are slower, because PHP first tries to look
|
||||
for corresponding function in namespace
|
||||
|
||||
* Extend the Reflection API?
|
||||
* Add ReflectionNamespace class
|
||||
+ getName()
|
||||
+ getClasses()
|
||||
+ getFunctions()
|
||||
+ getFiles()
|
||||
* Add getNamespace() methods to ReflectionClass and ReflectionFunction
|
||||
|
||||
* Rename namespaces to packages?
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
- Improve the lock in ts_resource_ex() in order to cover less code.
|
||||
This can probably be done by more careful hash table access
|
||||
+108
-104
@@ -55,9 +55,8 @@ static int resource_types_table_size;
|
||||
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
|
||||
|
||||
/* New thread handlers */
|
||||
static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler = NULL;
|
||||
static tsrm_thread_end_func_t tsrm_new_thread_end_handler = NULL;
|
||||
static tsrm_shutdown_func_t tsrm_shutdown_handler = NULL;
|
||||
static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler;
|
||||
static tsrm_thread_end_func_t tsrm_new_thread_end_handler;
|
||||
|
||||
/* Debug support */
|
||||
int tsrm_error(int level, const char *format, ...);
|
||||
@@ -115,17 +114,20 @@ 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
|
||||
|
||||
TSRM_TLS uint8_t in_main_thread = 0;
|
||||
|
||||
/* Startup TSRM (call once for the entire process) */
|
||||
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
|
||||
{/*{{{*/
|
||||
{
|
||||
#if defined(GNUPTH)
|
||||
pth_init();
|
||||
pth_key_create(&tls_key, 0);
|
||||
@@ -136,11 +138,10 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
|
||||
st_key_create(&tls_key, 0);
|
||||
#elif defined(TSRM_WIN32)
|
||||
tls_key = TlsAlloc();
|
||||
#elif defined(BETHREADS)
|
||||
tls_key = tls_allocate();
|
||||
#endif
|
||||
|
||||
/* ensure singleton */
|
||||
in_main_thread = 1;
|
||||
|
||||
tsrm_error_file = stderr;
|
||||
tsrm_error_set(debug_level, debug_filename);
|
||||
tsrm_tls_table_size = expected_threads;
|
||||
@@ -163,21 +164,18 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
|
||||
|
||||
tsmm_mutex = tsrm_mutex_alloc();
|
||||
|
||||
tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
|
||||
return 1;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown TSRM (call once for the entire process) */
|
||||
TSRM_API void tsrm_shutdown(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!in_main_thread) {
|
||||
/* ensure singleton */
|
||||
return;
|
||||
}
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
|
||||
@@ -220,18 +218,12 @@ TSRM_API void tsrm_shutdown(void)
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsFree(tls_key);
|
||||
#endif
|
||||
if (tsrm_shutdown_handler) {
|
||||
tsrm_shutdown_handler();
|
||||
}
|
||||
tsrm_new_thread_begin_handler = NULL;
|
||||
tsrm_new_thread_end_handler = NULL;
|
||||
tsrm_shutdown_handler = NULL;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
|
||||
{/*{{{*/
|
||||
{
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
|
||||
@@ -244,15 +236,13 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
|
||||
|
||||
/* store the new resource type in the resource sizes table */
|
||||
if (resource_types_table_size < id_count) {
|
||||
tsrm_resource_type *_tmp;
|
||||
_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
|
||||
if (!_tmp) {
|
||||
resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
|
||||
if (!resource_types_table) {
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
|
||||
*rsrc_id = 0;
|
||||
return 0;
|
||||
}
|
||||
resource_types_table = _tmp;
|
||||
resource_types_table_size = id_count;
|
||||
}
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
|
||||
@@ -284,11 +274,11 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
|
||||
return *rsrc_id;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
|
||||
{/*{{{*/
|
||||
{
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
|
||||
@@ -324,16 +314,25 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
||||
{/*{{{*/
|
||||
{
|
||||
THREAD_T thread_id;
|
||||
int hash_value;
|
||||
tsrm_tls_entry *thread_resources;
|
||||
|
||||
#ifdef NETWARE
|
||||
/* The below if loop is added for NetWare to fix an abend while unloading PHP
|
||||
* when an Apache unload command is issued on the system console.
|
||||
* While exiting from PHP, at the end for some reason, this function is called
|
||||
* with tsrm_tls_table = NULL. When this happened, the server abends when
|
||||
* tsrm_tls_table is accessed since it is NULL.
|
||||
*/
|
||||
if(tsrm_tls_table) {
|
||||
#endif
|
||||
if (!th_id) {
|
||||
/* Fast path for looking up the resources for the current
|
||||
* thread. Its used by just about every call to
|
||||
@@ -387,12 +386,15 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
||||
}/*}}}*/
|
||||
#ifdef NETWARE
|
||||
} /* if(tsrm_tls_table) */
|
||||
#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;
|
||||
|
||||
@@ -411,10 +413,10 @@ void tsrm_free_interpreter_context(void *context)
|
||||
free(thread_resources);
|
||||
thread_resources = next;
|
||||
}
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
void *tsrm_set_interpreter_context(void *new_ctx)
|
||||
{/*{{{*/
|
||||
{
|
||||
tsrm_tls_entry *current;
|
||||
|
||||
current = tsrm_tls_get();
|
||||
@@ -427,12 +429,12 @@ void *tsrm_set_interpreter_context(void *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;
|
||||
|
||||
@@ -446,12 +448,12 @@ void *tsrm_new_interpreter_context(void)
|
||||
/* 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)
|
||||
{/*{{{*/
|
||||
{
|
||||
tsrm_tls_entry *thread_resources;
|
||||
int i;
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
@@ -488,12 +490,12 @@ void ts_free_thread(void)
|
||||
thread_resources = thread_resources->next;
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* frees all resources allocated for all threads except current */
|
||||
void ts_free_worker_threads(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
tsrm_tls_entry *thread_resources;
|
||||
int i;
|
||||
THREAD_T thread_id = tsrm_thread_id();
|
||||
@@ -534,12 +536,12 @@ void ts_free_worker_threads(void)
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{/*{{{*/
|
||||
{
|
||||
int i;
|
||||
int j = TSRM_UNSHUFFLE_RSRC_ID(id);
|
||||
|
||||
@@ -568,7 +570,7 @@ void ts_free_id(ts_rsrc_id id)
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -579,22 +581,28 @@ void ts_free_id(ts_rsrc_id id)
|
||||
|
||||
/* Obtain the current thread id */
|
||||
TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
#ifdef TSRM_WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(GNUPTH)
|
||||
return pth_self();
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_self();
|
||||
#elif defined(NSAPI)
|
||||
return systhread_current();
|
||||
#elif defined(PI3WEB)
|
||||
return PIThread_getCurrent();
|
||||
#elif defined(TSRM_ST)
|
||||
return st_thread_self();
|
||||
#elif defined(BETHREADS)
|
||||
return find_thread(NULL);
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a mutex */
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
@@ -605,19 +613,27 @@ TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
#elif defined(PTHREADS)
|
||||
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexp,NULL);
|
||||
#elif defined(NSAPI)
|
||||
mutexp = crit_init();
|
||||
#elif defined(PI3WEB)
|
||||
mutexp = PIPlatform_allocLocalMutex();
|
||||
#elif defined(TSRM_ST)
|
||||
mutexp = st_mutex_new();
|
||||
#elif defined(BETHREADS)
|
||||
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
|
||||
mutexp->ben = 0;
|
||||
mutexp->sem = create_sem(1, "PHP sempahore");
|
||||
#endif
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex created thread: %d\n",mythreadid());
|
||||
#endif
|
||||
return( mutexp );
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/* Free a mutex */
|
||||
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
{/*{{{*/
|
||||
{
|
||||
if (mutexp) {
|
||||
#ifdef TSRM_WIN32
|
||||
DeleteCriticalSection(mutexp);
|
||||
@@ -627,14 +643,21 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
#elif defined(PTHREADS)
|
||||
pthread_mutex_destroy(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_terminate(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
PISync_delete(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
st_mutex_destroy(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
delete_sem(mutexp->sem);
|
||||
free(mutexp);
|
||||
#endif
|
||||
}
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex freed thread: %d\n",mythreadid());
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -642,7 +665,7 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
A return value of 0 indicates success
|
||||
*/
|
||||
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
{/*{{{*/
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
EnterCriticalSection(mutexp);
|
||||
@@ -654,10 +677,19 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
return -1;
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_lock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_enter(mutexp);
|
||||
return 0;
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_lock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_lock(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
if (atomic_add(&mutexp->ben, 1) != 0)
|
||||
return acquire_sem(mutexp->sem);
|
||||
return 0;
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -665,7 +697,7 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
A return value of 0 indicates success
|
||||
*/
|
||||
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
{/*{{{*/
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
LeaveCriticalSection(mutexp);
|
||||
@@ -677,17 +709,26 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
return -1;
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_unlock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_exit(mutexp);
|
||||
return 0;
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_unlock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_unlock(mutexp);
|
||||
#elif defined(BETHREADS)
|
||||
if (atomic_add(&mutexp->ben, -1) != 1)
|
||||
return release_sem(mutexp->sem);
|
||||
return 0;
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
/*
|
||||
Changes the signal mask of the calling thread
|
||||
*/
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||
{/*{{{*/
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
|
||||
/* TODO: add support for other APIs */
|
||||
#ifdef PTHREADS
|
||||
@@ -695,36 +736,28 @@ TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||
#else
|
||||
return sigprocmask(how, set, oldset);
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
|
||||
{/*{{{*/
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_begin_handler;
|
||||
|
||||
tsrm_new_thread_begin_handler = new_thread_begin_handler;
|
||||
return retval;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler)
|
||||
{/*{{{*/
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_end_handler;
|
||||
|
||||
tsrm_new_thread_end_handler = new_thread_end_handler;
|
||||
return retval;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler)
|
||||
{/*{{{*/
|
||||
void *retval = (void *) tsrm_shutdown_handler;
|
||||
|
||||
tsrm_shutdown_handler = shutdown_handler;
|
||||
return retval;
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
/*
|
||||
* Debug support
|
||||
@@ -732,7 +765,7 @@ TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler)
|
||||
|
||||
#if TSRM_DEBUG
|
||||
int tsrm_error(int level, const char *format, ...)
|
||||
{/*{{{*/
|
||||
{
|
||||
if (level<=tsrm_error_level) {
|
||||
va_list args;
|
||||
int size;
|
||||
@@ -747,12 +780,12 @@ int tsrm_error(int level, const char *format, ...)
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}/*}}}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void tsrm_error_set(int level, char *debug_filename)
|
||||
{/*{{{*/
|
||||
{
|
||||
tsrm_error_level = level;
|
||||
|
||||
#if TSRM_DEBUG
|
||||
@@ -769,40 +802,11 @@ void tsrm_error_set(int level, char *debug_filename)
|
||||
tsrm_error_file = stderr;
|
||||
}
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API void *tsrm_get_ls_cache(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
return tsrm_tls_get();
|
||||
}/*}}}*/
|
||||
|
||||
TSRM_API uint8_t tsrm_is_main_thread(void)
|
||||
{/*{{{*/
|
||||
return in_main_thread;
|
||||
}/*}}}*/
|
||||
|
||||
TSRM_API const char *tsrm_api_name(void)
|
||||
{/*{{{*/
|
||||
#if defined(GNUPTH)
|
||||
return "GNU Pth";
|
||||
#elif defined(PTHREADS)
|
||||
return "POSIX Threads";
|
||||
#elif defined(TSRM_ST)
|
||||
return "State Threads";
|
||||
#elif defined(TSRM_WIN32)
|
||||
return "Windows Threads";
|
||||
#else
|
||||
return "Unknown";
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
#endif /* ZTS */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+16
-20
@@ -69,9 +69,22 @@ typedef int ts_rsrc_id;
|
||||
#elif defined(PTHREADS)
|
||||
# define THREAD_T pthread_t
|
||||
# define MUTEX_T pthread_mutex_t *
|
||||
#elif defined(NSAPI)
|
||||
# define THREAD_T SYS_THREAD
|
||||
# define MUTEX_T CRITICAL
|
||||
#elif defined(PI3WEB)
|
||||
# define THREAD_T PIThread *
|
||||
# define MUTEX_T PISync *
|
||||
#elif defined(TSRM_ST)
|
||||
# define THREAD_T st_thread_t
|
||||
# define MUTEX_T st_mutex_t
|
||||
#elif defined(BETHREADS)
|
||||
# define THREAD_T thread_id
|
||||
typedef struct {
|
||||
sem_id sem;
|
||||
int32 ben;
|
||||
} beos_ben;
|
||||
# define MUTEX_T beos_ben *
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
@@ -115,7 +128,6 @@ TSRM_API void ts_free_id(ts_rsrc_id id);
|
||||
|
||||
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
|
||||
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
|
||||
typedef void (*tsrm_shutdown_func_t)(void);
|
||||
|
||||
|
||||
TSRM_API int tsrm_error(int level, const char *format, ...);
|
||||
@@ -133,7 +145,6 @@ TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
|
||||
|
||||
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);
|
||||
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler);
|
||||
|
||||
/* these 3 APIs should only be used by people that fully understand the threading model
|
||||
* used by PHP/Zend and the selected SAPI. */
|
||||
@@ -142,17 +153,11 @@ TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
|
||||
TSRM_API void tsrm_free_interpreter_context(void *context);
|
||||
|
||||
TSRM_API void *tsrm_get_ls_cache(void);
|
||||
TSRM_API uint8_t tsrm_is_main_thread(void);
|
||||
TSRM_API const char *tsrm_api_name(void);
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus > 199711L
|
||||
# define TSRM_TLS thread_local
|
||||
#ifdef TSRM_WIN32
|
||||
# define TSRM_TLS __declspec(thread)
|
||||
#else
|
||||
# ifdef TSRM_WIN32
|
||||
# define TSRM_TLS __declspec(thread)
|
||||
# else
|
||||
# define TSRM_TLS __thread
|
||||
# endif
|
||||
# define TSRM_TLS __thread
|
||||
#endif
|
||||
|
||||
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
||||
@@ -210,12 +215,3 @@ TSRM_API const char *tsrm_api_name(void);
|
||||
#endif /* ZTS */
|
||||
|
||||
#endif /* TSRM_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+3
-3
@@ -30,14 +30,14 @@ $(LT_TARGETS):
|
||||
$(makefile_in_files): $(makefile_am_files)
|
||||
automake -a -i $(AMFLAGS) $(makefile_files)
|
||||
|
||||
aclocal.m4: configure.ac acinclude.m4
|
||||
aclocal.m4: configure.in acinclude.m4
|
||||
aclocal
|
||||
|
||||
$(config_h_in): configure.ac
|
||||
$(config_h_in): configure.in
|
||||
# explicitly remove target since autoheader does not seem to work
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@rm -f $@
|
||||
autoheader
|
||||
|
||||
configure: aclocal.m4 configure.ac
|
||||
configure: aclocal.m4 configure.in
|
||||
autoconf
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl Minimalistic configure.ac for TSRM.
|
||||
dnl Minimalistic configure.in for TSRM.
|
||||
dnl
|
||||
|
||||
AC_INIT(TSRM.c)
|
||||
+45
-3
@@ -1,3 +1,45 @@
|
||||
/* Keep this header for compatibility with external code, it's currently not
|
||||
used anywhere in the core and there are no implementations in TSRM. */
|
||||
#include "win32/readdir.h"
|
||||
#ifndef READDIR_H
|
||||
#define READDIR_H
|
||||
|
||||
|
||||
/*
|
||||
* Structures and types used to implement opendir/readdir/closedir
|
||||
* on Windows 95/NT.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <direct.h>
|
||||
|
||||
/* struct dirent - same as Unix */
|
||||
|
||||
struct dirent {
|
||||
long d_ino; /* inode (always 1 in WIN32) */
|
||||
off_t d_off; /* offset to this dirent */
|
||||
unsigned short d_reclen; /* length of d_name */
|
||||
char d_name[_MAX_FNAME + 1]; /* filename (null terminated) */
|
||||
};
|
||||
|
||||
|
||||
/* typedef DIR - not the same as Unix */
|
||||
typedef struct {
|
||||
HANDLE handle; /* _findfirst/_findnext handle */
|
||||
short offset; /* offset into directory */
|
||||
short finished; /* 1 if there are not more files */
|
||||
WIN32_FIND_DATA fileinfo; /* from _findfirst/_findnext */
|
||||
char *dir; /* the dir we are reading */
|
||||
struct dirent dent; /* the dirent to return */
|
||||
} DIR;
|
||||
|
||||
/* Function prototypes */
|
||||
DIR *opendir(const char *);
|
||||
struct dirent *readdir(DIR *);
|
||||
int readdir_r(DIR *, struct dirent *, struct dirent **);
|
||||
int closedir(DIR *);
|
||||
int rewinddir(DIR *);
|
||||
|
||||
#endif /* READDIR_H */
|
||||
+45
-40
@@ -103,47 +103,52 @@ dnl -threads gcc (HP-UX)
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK],[
|
||||
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_LIBS=$LIBS
|
||||
PTHREADS_ASSIGN_VARS
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$save_LIBS
|
||||
CFLAGS=$save_CFLAGS
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
|
||||
ac_cv_pthreads_cflags=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
|
||||
ac_save=$CFLAGS
|
||||
CFLAGS="$CFLAGS $flag"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
CFLAGS=$ac_save
|
||||
if test "$pthreads_checked" = "yes"; then
|
||||
ac_cv_pthreads_cflags=$flag
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
|
||||
ac_cv_pthreads_lib=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for lib in pthread pthreads c_r; do
|
||||
ac_save=$LIBS
|
||||
LIBS="$LIBS -l$lib"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$ac_save
|
||||
if test "$pthreads_checked" = "yes"; then
|
||||
ac_cv_pthreads_lib=$lib
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
|
||||
if test "$beos_threads" = "1"; then
|
||||
pthreads_working="yes"
|
||||
ac_cv_pthreads_cflags=""
|
||||
else
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_LIBS=$LIBS
|
||||
PTHREADS_ASSIGN_VARS
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$save_LIBS
|
||||
CFLAGS=$save_CFLAGS
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
|
||||
ac_cv_pthreads_cflags=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
|
||||
ac_save=$CFLAGS
|
||||
CFLAGS="$CFLAGS $flag"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
CFLAGS=$ac_save
|
||||
if test "$pthreads_checked" = "yes"; then
|
||||
ac_cv_pthreads_cflags=$flag
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
|
||||
ac_cv_pthreads_lib=
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
for lib in pthread pthreads c_r; do
|
||||
ac_save=$LIBS
|
||||
LIBS="$LIBS -l$lib"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$ac_save
|
||||
if test "$pthreads_checked" = "yes"; then
|
||||
ac_cv_pthreads_lib=$lib
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
|
||||
pthreads_working="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
|
||||
+12
-8
@@ -77,15 +77,19 @@ sinclude(threads.m4)
|
||||
AC_DEFUN([TSRM_CHECK_PTHREADS],[
|
||||
|
||||
PTHREADS_CHECK
|
||||
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
|
||||
|
||||
if test "$beos_threads" = "1"; then
|
||||
AC_DEFINE(BETHREADS, 1, Whether to use native BeOS threads)
|
||||
else
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
|
||||
fi
|
||||
|
||||
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
|
||||
|
||||
AC_MSG_CHECKING(for POSIX threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
|
||||
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
|
||||
|
||||
AC_MSG_CHECKING(for POSIX threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_THREADS_CHECKS],[
|
||||
|
||||
@@ -6,18 +6,10 @@
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_ALLOCA 1
|
||||
#define HAVE_REALPATH 1
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
@@ -25,7 +25,9 @@
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# ifndef NETWARE
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
@@ -69,12 +71,3 @@ char *alloca ();
|
||||
#endif
|
||||
|
||||
#endif /* TSRM_CONFIG_COMMON_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 7 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2018 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 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 |
|
||||
| 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. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
| Anantha Kesari H Y <hyanantha@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef NETWARE
|
||||
|
||||
#ifdef USE_MKFIFO
|
||||
#include <sys/stat.h>
|
||||
#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */
|
||||
#include <nks/fsio.h>
|
||||
#endif
|
||||
|
||||
#include <nks/vm.h>
|
||||
#include <nks/memory.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mktemp.h"
|
||||
|
||||
/* strtok() call in LibC is abending when used in a different address space
|
||||
* -- hence using PHP's version itself for now
|
||||
*/
|
||||
#include "tsrm_strtok_r.h"
|
||||
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
|
||||
|
||||
#define WHITESPACE " \t"
|
||||
#define MAX_ARGS 10
|
||||
|
||||
|
||||
TSRM_API FILE* popen(const char *commandline, const char *type)
|
||||
{
|
||||
char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
|
||||
char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
|
||||
char *filePath = NULL;
|
||||
char *ptr = NULL;
|
||||
int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
|
||||
FILE *stream = NULL;
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
int pipe_handle;
|
||||
int mode = O_RDONLY;
|
||||
#else
|
||||
NXHandle_t pipe_handle;
|
||||
NXMode_t mode = NX_O_RDONLY;
|
||||
#endif
|
||||
NXExecEnvSpec_t envSpec;
|
||||
NXNameSpec_t nameSpec;
|
||||
NXVmId_t newVM = 0;
|
||||
|
||||
/* Check for validity of input parameters */
|
||||
if (!commandline || !type)
|
||||
return NULL;
|
||||
|
||||
/* Get temporary file name */
|
||||
filePath = mktemp(tempName);
|
||||
if (!filePath)
|
||||
return NULL;
|
||||
|
||||
/* Set pipe mode according to type -- for now allow only "r" or "w" */
|
||||
if (strcmp(type, "r") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_RDONLY;
|
||||
#else
|
||||
mode = NX_O_RDONLY;
|
||||
#endif
|
||||
else if (strcmp(type, "w") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_WRONLY;
|
||||
#else
|
||||
mode = NX_O_WRONLY;
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
|
||||
#ifdef USE_PIPE_OPEN
|
||||
pipe_handle = pipe_open(filePath, mode);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#elif defined(USE_MKFIFO)
|
||||
pipe_handle = mkfifo(filePath, mode);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#else
|
||||
/* - NetWare doesn't require first parameter
|
||||
* - Allowing LibC to choose the buffer size for now
|
||||
*/
|
||||
err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
|
||||
if (err)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* Copy the environment variables in preparation for the spawn call */
|
||||
envCount = NXGetEnvCount() + 1; /* add one for NULL */
|
||||
env = (char **) NXMemAlloc(sizeof(char *) * envCount, 0);
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
err = NXCopyEnv(env, envCount);
|
||||
if (err) {
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Separate commandline string into words */
|
||||
ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
command = (char*)malloc(ptrLen + 1);
|
||||
if (!command) {
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (command, ptr);
|
||||
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
while (ptr && (argc < MAX_ARGS)) {
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
argv[argc] = (char*)malloc(ptrLen + 1);
|
||||
if (!argv[argc]) {
|
||||
NXMemFree (env);
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (argv[argc], ptr);
|
||||
argc++;
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
}
|
||||
|
||||
/* Setup the execution environment and spawn new process */
|
||||
envSpec.esFlags = 0; /* Not used */
|
||||
envSpec.esArgc = argc;
|
||||
envSpec.esArgv = (void **) argv;
|
||||
envSpec.esEnv = (void **) env;
|
||||
|
||||
/* envSpec.esStdin.ssType = */
|
||||
envSpec.esStdout.ssType = NX_OBJ_FIFO;
|
||||
envSpec.esStderr.ssType = NX_OBJ_FILE;
|
||||
|
||||
/* 'ssHandle' is not a struct/union/class member */
|
||||
/*
|
||||
envSpec.esStdin.ssHandle =
|
||||
envSpec.esStdout.ssHandle =
|
||||
envSpec.esStderr.ssHandle = -1;
|
||||
*/
|
||||
envSpec.esStdin.ssPathCtx = NULL;
|
||||
envSpec.esStdout.ssPathCtx = NULL;
|
||||
envSpec.esStderr.ssPathCtx = NULL;
|
||||
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
if (mode == O_RDONLY) {
|
||||
#else
|
||||
if (mode == NX_O_RDONLY) {
|
||||
#endif
|
||||
envSpec.esStdin.ssPath = filePath;
|
||||
envSpec.esStdout.ssPath = stdout;
|
||||
} else { /* Write Only */
|
||||
envSpec.esStdin.ssPath = stdin;
|
||||
envSpec.esStdout.ssPath = filePath;
|
||||
}
|
||||
|
||||
envSpec.esStderr.ssPath = stdout;
|
||||
|
||||
nameSpec.ssType = NX_OBJ_FIFO;
|
||||
/* nameSpec.ssHandle = 0; */ /* 'ssHandle' is not a struct/union/class member */
|
||||
nameSpec.ssPathCtx = NULL; /* Not used */
|
||||
nameSpec.ssPath = argv[0];
|
||||
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
|
||||
if (!err)
|
||||
/* Get file pointer corresponding to the pipe (file) opened */
|
||||
stream = fdopen(pipe_handle, type);
|
||||
|
||||
/* Clean-up */
|
||||
if (env)
|
||||
NXMemFree (env);
|
||||
|
||||
if (pipe_handle)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
close(pipe_handle);
|
||||
#else
|
||||
NXClose(pipe_handle);
|
||||
#endif
|
||||
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
TSRM_API int pclose(FILE* stream)
|
||||
{
|
||||
int err = 0;
|
||||
NXHandle_t fd = 0;
|
||||
|
||||
/* Get the process associated with this pipe (file) handle and terminate it */
|
||||
fd = fileno(stream);
|
||||
NXClose (fd);
|
||||
|
||||
err = fclose(stream);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* NETWARE */
|
||||
@@ -12,22 +12,18 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Kalle Sommer Nielsen <kalle@php.net> |
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
| Anantha Kesari H Y <hyanantha@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef HAVE_NICE_H
|
||||
# define HAVE_NICE_H
|
||||
|
||||
PHPAPI int nice(zend_long);
|
||||
#ifndef TSRM_NW_H
|
||||
#define TSRM_NW_H
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
TSRM_API FILE* popen(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE* stream);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+4
-13
@@ -4,7 +4,7 @@
|
||||
#include "tsrm_strtok_r.h"
|
||||
|
||||
static inline int in_character_class(char ch, const char *delim)
|
||||
{/*{{{*/
|
||||
{
|
||||
while (*delim) {
|
||||
if (*delim == ch) {
|
||||
return 1;
|
||||
@@ -12,10 +12,10 @@ static inline int in_character_class(char ch, const char *delim)
|
||||
delim++;
|
||||
}
|
||||
return 0;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last)
|
||||
{/*{{{*/
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL) {
|
||||
@@ -41,7 +41,7 @@ TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last)
|
||||
*last = s + 1;
|
||||
}
|
||||
return token;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -61,12 +61,3 @@ main()
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+217
-197
@@ -42,7 +42,7 @@ static tsrm_win32_globals win32_globals;
|
||||
#endif
|
||||
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
|
||||
{/*{{{*/
|
||||
{
|
||||
#ifdef ZTS
|
||||
TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
@@ -61,10 +61,10 @@ TSRMLS_CACHE_UPDATE();
|
||||
*/
|
||||
globals->impersonation_token = INVALID_HANDLE_VALUE;
|
||||
globals->impersonation_token_sid = NULL;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
static void tsrm_win32_dtor(tsrm_win32_globals *globals)
|
||||
{/*{{{*/
|
||||
{
|
||||
shm_pair *ptr;
|
||||
|
||||
if (globals->process) {
|
||||
@@ -89,48 +89,51 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals)
|
||||
if (globals->impersonation_token_sid) {
|
||||
free(globals->impersonation_token_sid);
|
||||
}
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_startup(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
|
||||
#else
|
||||
tsrm_win32_ctor(&win32_globals);
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_shutdown(void)
|
||||
{/*{{{*/
|
||||
{
|
||||
#ifndef ZTS
|
||||
tsrm_win32_dtor(&win32_globals);
|
||||
#endif
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname, size_t pathname_len, size_t *key_len)
|
||||
{/*{{{*/
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname)
|
||||
{
|
||||
PSID pSid = TWG(impersonation_token_sid);
|
||||
char *ptcSid = NULL;
|
||||
TCHAR *ptcSid = NULL;
|
||||
char *bucket_key = NULL;
|
||||
size_t ptc_sid_len;
|
||||
size_t ptc_sid_len, pathname_len;
|
||||
|
||||
pathname_len = strlen(pathname);
|
||||
|
||||
if (!pSid) {
|
||||
*key_len = pathname_len;
|
||||
return pathname;
|
||||
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pathname_len + 1);
|
||||
if (!bucket_key) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(bucket_key, pathname, pathname_len);
|
||||
return bucket_key;
|
||||
}
|
||||
|
||||
if (!ConvertSidToStringSid(pSid, &ptcSid)) {
|
||||
*key_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ptc_sid_len = strlen(ptcSid);
|
||||
*key_len = pathname_len + ptc_sid_len;
|
||||
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *key_len + 1);
|
||||
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pathname_len + ptc_sid_len + 1);
|
||||
if (!bucket_key) {
|
||||
LocalFree(ptcSid);
|
||||
*key_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -139,11 +142,11 @@ char * tsrm_win32_get_path_sid_key(const char *pathname, size_t pathname_len, si
|
||||
|
||||
LocalFree(ptcSid);
|
||||
return bucket_key;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
PSID tsrm_win32_get_token_sid(HANDLE hToken)
|
||||
{/*{{{*/
|
||||
{
|
||||
DWORD dwLength = 0;
|
||||
PTOKEN_USER pTokenUser = NULL;
|
||||
DWORD sid_len;
|
||||
@@ -190,10 +193,10 @@ Finished:
|
||||
HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser);
|
||||
}
|
||||
return NULL;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
|
||||
{/*{{{*/
|
||||
{
|
||||
time_t t;
|
||||
HANDLE thread_token = NULL;
|
||||
PSID token_sid;
|
||||
@@ -205,177 +208,199 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
|
||||
DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0;
|
||||
BYTE * psec_desc = NULL;
|
||||
BOOL fAccess = FALSE;
|
||||
|
||||
realpath_cache_bucket * bucket = NULL;
|
||||
char real_path[MAXPATHLEN] = {0};
|
||||
|
||||
if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
|
||||
if(tsrm_realpath(pathname, real_path) == NULL) {
|
||||
SET_ERRNO_FROM_WIN32_CODE(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
pathname = real_path;
|
||||
}
|
||||
char * real_path = NULL;
|
||||
|
||||
PHP_WIN32_IOUTIL_INIT_W(pathname)
|
||||
if (!pathw) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Either access call failed, or the mode was asking for a specific check.*/
|
||||
int ret = php_win32_ioutil_access_w(pathw, mode);
|
||||
if (0 > ret || X_OK == mode || F_OK == mode) {
|
||||
if (mode == 1 /*X_OK*/) {
|
||||
DWORD type;
|
||||
int ret;
|
||||
|
||||
ret = GetBinaryTypeW(pathw, &type) ? 0 : -1;
|
||||
|
||||
PHP_WIN32_IOUTIL_CLEANUP_W()
|
||||
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
|
||||
real_path = (char *)malloc(MAXPATHLEN);
|
||||
if(tsrm_realpath(pathname, real_path) == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
pathname = real_path;
|
||||
PHP_WIN32_IOUTIL_REINIT_W(pathname);
|
||||
}
|
||||
|
||||
if(php_win32_ioutil_access(pathname, mode)) {
|
||||
PHP_WIN32_IOUTIL_CLEANUP_W()
|
||||
free(real_path);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* If only existence check is made, return now */
|
||||
if (mode == 0) {
|
||||
PHP_WIN32_IOUTIL_CLEANUP_W()
|
||||
free(real_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only in NTS when impersonate==1 (aka FastCGI) */
|
||||
|
||||
/*
|
||||
AccessCheck() requires an impersonation token. We first get a primary
|
||||
token and then create a duplicate impersonation token. The
|
||||
impersonation token is not actually assigned to the thread, but is
|
||||
used in the call to AccessCheck. Thus, this function itself never
|
||||
impersonates, but does use the identity of the thread. If the thread
|
||||
was impersonating already, this function uses that impersonation context.
|
||||
*/
|
||||
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
|
||||
if (GetLastError() == ERROR_NO_TOKEN) {
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
|
||||
TWG(impersonation_token) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* token_sid will be freed in tsrmwin32_dtor */
|
||||
token_sid = tsrm_win32_get_token_sid(thread_token);
|
||||
if (!token_sid) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
/* Different identity, we need a new impersontated token as well */
|
||||
if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = token_sid;
|
||||
|
||||
/* Duplicate the token as impersonated token */
|
||||
if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
|
||||
goto Finished;
|
||||
}
|
||||
} else {
|
||||
/* we already have it, free it then */
|
||||
free(token_sid);
|
||||
}
|
||||
|
||||
if (CWDG(realpath_cache_size_limit)) {
|
||||
t = time(0);
|
||||
bucket = realpath_cache_lookup(pathname, strlen(pathname), t);
|
||||
if(bucket == NULL && !real_path[0]) {
|
||||
/* We used the pathname directly. Call tsrm_realpath */
|
||||
/* so that entry is created in realpath cache */
|
||||
if(tsrm_realpath(pathname, real_path) != NULL) {
|
||||
pathname = real_path;
|
||||
bucket = realpath_cache_lookup(pathname, strlen(pathname), t);
|
||||
PHP_WIN32_IOUTIL_REINIT_W(pathname);
|
||||
/*
|
||||
AccessCheck() requires an impersonation token. We first get a primary
|
||||
token and then create a duplicate impersonation token. The
|
||||
impersonation token is not actually assigned to the thread, but is
|
||||
used in the call to AccessCheck. Thus, this function itself never
|
||||
impersonates, but does use the identity of the thread. If the thread
|
||||
was impersonating already, this function uses that impersonation context.
|
||||
*/
|
||||
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
|
||||
if (GetLastError() == ERROR_NO_TOKEN) {
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
|
||||
TWG(impersonation_token) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a full access check because access() will only check read-only attribute */
|
||||
if(mode == 0 || mode > 6) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
/* token_sid will be freed in tsrmwin32_dtor */
|
||||
token_sid = tsrm_win32_get_token_sid(thread_token);
|
||||
if (!token_sid) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = NULL;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ;
|
||||
} else if(mode <= 2) {
|
||||
if(bucket != NULL && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_writable;
|
||||
|
||||
/* Different identity, we need a new impersontated token as well */
|
||||
if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
|
||||
if (TWG(impersonation_token_sid)) {
|
||||
free(TWG(impersonation_token_sid));
|
||||
}
|
||||
TWG(impersonation_token_sid) = token_sid;
|
||||
|
||||
/* Duplicate the token as impersonated token */
|
||||
if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
|
||||
goto Finished;
|
||||
}
|
||||
} else {
|
||||
/* we already have it, free it then */
|
||||
free(token_sid);
|
||||
}
|
||||
|
||||
if (CWDG(realpath_cache_size_limit)) {
|
||||
t = time(0);
|
||||
bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
|
||||
if(bucket == NULL && real_path == NULL) {
|
||||
/* We used the pathname directly. Call tsrm_realpath */
|
||||
/* so that entry is created in realpath cache */
|
||||
real_path = (char *)malloc(MAXPATHLEN);
|
||||
if(tsrm_realpath(pathname, real_path) != NULL) {
|
||||
pathname = real_path;
|
||||
bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
|
||||
PHP_WIN32_IOUTIL_REINIT_W(pathname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a full access check because access() will only check read-only attribute */
|
||||
if(mode == 0 || mode > 6) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ;
|
||||
} else if(mode <= 2) {
|
||||
if(bucket != NULL && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_writable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_WRITE;
|
||||
} else if(mode <= 4) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
|
||||
} else { // if(mode <= 6)
|
||||
if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_readable & bucket->is_writable;
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
|
||||
}
|
||||
|
||||
if(TWG(impersonation_token) == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_WRITE;
|
||||
} else if(mode <= 4) {
|
||||
if(bucket != NULL && bucket->is_rvalid) {
|
||||
fAccess = bucket->is_readable;
|
||||
|
||||
/* Get size of security buffer. Call is expected to fail */
|
||||
if(GetFileSecurityW(pathw, sec_info, NULL, 0, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
|
||||
} else { // if(mode <= 6)
|
||||
if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
|
||||
fAccess = bucket->is_readable & bucket->is_writable;
|
||||
|
||||
psec_desc = (BYTE *)malloc(sec_desc_length);
|
||||
if(psec_desc == NULL ||
|
||||
!GetFileSecurityW(pathw, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
|
||||
}
|
||||
|
||||
if(TWG(impersonation_token) == NULL) {
|
||||
goto Finished;
|
||||
}
|
||||
MapGenericMask(&desired_access, &gen_map);
|
||||
|
||||
/* Get size of security buffer. Call is expected to fail */
|
||||
if(GetFileSecurityW(pathw, sec_info, NULL, 0, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
psec_desc = (BYTE *)malloc(sec_desc_length);
|
||||
if(psec_desc == NULL ||
|
||||
!GetFileSecurityW(pathw, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
MapGenericMask(&desired_access, &gen_map);
|
||||
|
||||
if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
|
||||
goto Finished_Impersonate;
|
||||
}
|
||||
|
||||
/* Keep the result in realpath_cache */
|
||||
if(bucket != NULL) {
|
||||
if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
|
||||
goto Finished_Impersonate;
|
||||
}
|
||||
else if(desired_access == FILE_GENERIC_WRITE) {
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
} else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
|
||||
/* Keep the result in realpath_cache */
|
||||
if(bucket != NULL) {
|
||||
if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
}
|
||||
else if(desired_access == FILE_GENERIC_WRITE) {
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
} else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
|
||||
bucket->is_rvalid = 1;
|
||||
bucket->is_readable = fAccess;
|
||||
bucket->is_wvalid = 1;
|
||||
bucket->is_writable = fAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Finished_Impersonate:
|
||||
if(psec_desc != NULL) {
|
||||
free(psec_desc);
|
||||
psec_desc = NULL;
|
||||
}
|
||||
if(psec_desc != NULL) {
|
||||
free(psec_desc);
|
||||
psec_desc = NULL;
|
||||
}
|
||||
|
||||
Finished:
|
||||
if(thread_token != NULL) {
|
||||
CloseHandle(thread_token);
|
||||
}
|
||||
if(thread_token != NULL) {
|
||||
CloseHandle(thread_token);
|
||||
}
|
||||
if(real_path != NULL) {
|
||||
free(real_path);
|
||||
real_path = NULL;
|
||||
}
|
||||
|
||||
PHP_WIN32_IOUTIL_CLEANUP_W()
|
||||
if(fAccess == FALSE) {
|
||||
errno = EACCES;
|
||||
return errno;
|
||||
} else {
|
||||
return 0;
|
||||
PHP_WIN32_IOUTIL_CLEANUP_W()
|
||||
if(fAccess == FALSE) {
|
||||
errno = EACCES;
|
||||
return errno;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
|
||||
static process_pair *process_get(FILE *stream)
|
||||
{/*{{{*/
|
||||
{
|
||||
process_pair *ptr;
|
||||
process_pair *newptr;
|
||||
|
||||
@@ -398,10 +423,10 @@ static process_pair *process_get(FILE *stream)
|
||||
ptr = newptr + TWG(process_size);
|
||||
TWG(process_size)++;
|
||||
return ptr;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
static shm_pair *shm_get(key_t key, void *addr)
|
||||
{/*{{{*/
|
||||
static shm_pair *shm_get(int key, void *addr)
|
||||
{
|
||||
shm_pair *ptr;
|
||||
shm_pair *newptr;
|
||||
|
||||
@@ -430,25 +455,24 @@ static shm_pair *shm_get(key_t key, void *addr)
|
||||
TWG(shm_size)++;
|
||||
memset(ptr, 0, sizeof(*ptr));
|
||||
return ptr;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
static HANDLE dupHandle(HANDLE fh, BOOL inherit)
|
||||
{/*{{{*/
|
||||
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
|
||||
HANDLE copy, self = GetCurrentProcess();
|
||||
if (!DuplicateHandle(self, fh, self, ©, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen(const char *command, const char *type)
|
||||
{/*{{{*/
|
||||
{
|
||||
|
||||
return popen_ex(command, type, NULL, NULL);
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
|
||||
{/*{{{*/
|
||||
{
|
||||
FILE *stream = NULL;
|
||||
int fno, type_len, read, mode;
|
||||
STARTUPINFOW startup;
|
||||
@@ -592,10 +616,10 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
|
||||
proc->prochnd = process.hProcess;
|
||||
proc->stream = stream;
|
||||
return stream;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API int pclose(FILE *stream)
|
||||
{/*{{{*/
|
||||
{
|
||||
DWORD termstat = 0;
|
||||
process_pair *process;
|
||||
|
||||
@@ -612,15 +636,19 @@ TSRM_API int pclose(FILE *stream)
|
||||
CloseHandle(process->prochnd);
|
||||
|
||||
return termstat;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API int shmget(key_t key, size_t size, int flags)
|
||||
{/*{{{*/
|
||||
TSRM_API int shmget(int key, int size, int flags)
|
||||
{
|
||||
shm_pair *shm;
|
||||
char shm_segment[26], shm_info[29];
|
||||
HANDLE shm_handle, info_handle;
|
||||
BOOL created = FALSE;
|
||||
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
|
||||
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
|
||||
|
||||
@@ -629,14 +657,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
|
||||
|
||||
if (!shm_handle && !info_handle) {
|
||||
if (flags & IPC_CREAT) {
|
||||
#if SIZEOF_SIZE_T == 8
|
||||
DWORD high = size >> 32;
|
||||
DWORD low = (DWORD)size;
|
||||
#else
|
||||
DWORD high = 0;
|
||||
DWORD low = size;
|
||||
#endif
|
||||
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment);
|
||||
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
|
||||
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
|
||||
created = TRUE;
|
||||
}
|
||||
@@ -695,10 +716,10 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
|
||||
}
|
||||
|
||||
return key;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API void *shmat(int key, const void *shmaddr, int flags)
|
||||
{/*{{{*/
|
||||
{
|
||||
shm_pair *shm = shm_get(key, NULL);
|
||||
|
||||
if (!shm->segment) {
|
||||
@@ -718,10 +739,10 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags)
|
||||
shm->descriptor->shm_nattch++;
|
||||
|
||||
return shm->addr;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API int shmdt(const void *shmaddr)
|
||||
{/*{{{*/
|
||||
{
|
||||
shm_pair *shm = shm_get(0, (void*)shmaddr);
|
||||
|
||||
if (!shm->segment) {
|
||||
@@ -733,10 +754,9 @@ TSRM_API int shmdt(const void *shmaddr)
|
||||
shm->descriptor->shm_nattch--;
|
||||
|
||||
return UnmapViewOfFile(shm->addr) ? 0 : -1;
|
||||
}/*}}}*/
|
||||
}
|
||||
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
|
||||
{/*{{{*/
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
|
||||
shm_pair *shm = shm_get(key, NULL);
|
||||
|
||||
if (!shm->segment) {
|
||||
@@ -764,7 +784,16 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
#if HAVE_UTIME
|
||||
static zend_always_inline void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */
|
||||
@@ -822,12 +851,3 @@ TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */
|
||||
/* }}} */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
+6
-14
@@ -26,10 +26,9 @@
|
||||
#if HAVE_UTIME
|
||||
# include <sys/utime.h>
|
||||
#endif
|
||||
#include "win32/ipc.h"
|
||||
|
||||
struct ipc_perm {
|
||||
key_t key;
|
||||
int key;
|
||||
unsigned short uid;
|
||||
unsigned short gid;
|
||||
unsigned short cuid;
|
||||
@@ -40,7 +39,7 @@ struct ipc_perm {
|
||||
|
||||
struct shmid_ds {
|
||||
struct ipc_perm shm_perm;
|
||||
size_t shm_segsz;
|
||||
int shm_segsz;
|
||||
time_t shm_atime;
|
||||
time_t shm_dtime;
|
||||
time_t shm_ctime;
|
||||
@@ -95,7 +94,7 @@ TSRMLS_CACHE_EXTERN()
|
||||
#define SHM_RND FILE_MAP_WRITE
|
||||
#define SHM_REMAP FILE_MAP_COPY
|
||||
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname, size_t pathname_len, size_t *key_len);
|
||||
char * tsrm_win32_get_path_sid_key(const char *pathname );
|
||||
|
||||
TSRM_API void tsrm_win32_startup(void);
|
||||
TSRM_API void tsrm_win32_shutdown(void);
|
||||
@@ -106,17 +105,10 @@ TSRM_API int pclose(FILE *stream);
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode);
|
||||
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf);
|
||||
|
||||
TSRM_API int shmget(key_t key, size_t size, int flags);
|
||||
TSRM_API int shmget(int key, int size, int flags);
|
||||
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);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
TSRM_API char *realpath(char *orig_path, char *buffer);
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
PHP 7.3 UPGRADE NOTES
|
||||
PHP 7.1 UPGRADE NOTES
|
||||
|
||||
1. Backward Incompatible Changes
|
||||
2. New Features
|
||||
@@ -19,383 +19,506 @@ PHP 7.3 UPGRADE NOTES
|
||||
1. Backward Incompatible Changes
|
||||
========================================
|
||||
|
||||
Core:
|
||||
. The ext_skel utility has been completely redesigned with new options and
|
||||
some old options removed. This is now written in PHP and has no external
|
||||
dependencies.
|
||||
. Support for BeOS has been dropped.
|
||||
. Exceptions thrown due to automatic conversion of warnings into exceptions
|
||||
in EH_THROW mode (e.g. some DateTime exceptions) no longer populate
|
||||
error_get_last() state. As such, they now work the same way as manually
|
||||
thrown exceptions.
|
||||
. TypeError now reports wrong types as `int` and `bool` instead of `integer`
|
||||
and `boolean`.
|
||||
. Due to the introduction of flexible heredoc/nowdoc syntax (see New Features
|
||||
section), doc strings that contain the ending label inside their body may
|
||||
cause syntax errors or change in interpretation. For example in
|
||||
- Core:
|
||||
. 'void' can no longer be used as the name of a class, interface, or trait.
|
||||
This applies to declarations, class_alias() and use statements.
|
||||
. 'iterable' can no longer be used as the name of a class, interface, or
|
||||
trait. This applies to declarations, class_alias() and use statements.
|
||||
(RFC: https://wiki.php.net/rfc/iterable)
|
||||
. (int), intval() where $base is 10 or unspecified, settype(), decbin(),
|
||||
decoct(), dechex(), integer operators and other conversions now always
|
||||
respect scientific notation in numeric strings.
|
||||
(RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
|
||||
. The ASCII 0x7F Delete control character is no longer permitted in unquoted
|
||||
identifiers in source code.
|
||||
. The following functions may no longer be called dynamically using $func(),
|
||||
call_user_func(), array_map() or similar:
|
||||
. extract()
|
||||
. compact()
|
||||
. get_defined_vars()
|
||||
. func_get_args()
|
||||
. func_get_arg()
|
||||
. func_num_args()
|
||||
. parse_str() with one argument
|
||||
. mb_parse_str() with one argument
|
||||
. assert() with a string argument
|
||||
(RFC: https://wiki.php.net/rfc/forbid_dynamic_scope_introspection)
|
||||
. If the error_log is set to syslog, the PHP error levels are mapped to the
|
||||
syslog error levels. This brings finer differentiation in the error logs
|
||||
in contrary to the previous approach where all the errors are loggged with
|
||||
the notice level only.
|
||||
. Don't call destructors of incompletely constructed objects, even if they
|
||||
are kept referenced. See bug #29368 and Zend/tests/bug29368_1.phpt.
|
||||
. call_user_func() will now consistently throw a warning if a function with
|
||||
reference arguments is called. However, call_user_func() will no longer
|
||||
abort the call in this case.
|
||||
. rand() and srand() are now aliases of mt_rand() and mt_srand().
|
||||
Consequently the output of the following functions has changed:
|
||||
. rand()
|
||||
. shuffle()
|
||||
. str_shuffle()
|
||||
. array_rand()
|
||||
. Fixes to random number generators mean that mt_rand() now produces a
|
||||
different sequence of outputs to previous versions. If you relied on
|
||||
mt_srand() to produce a deterministic sequence, it can be called using
|
||||
mt_srand($seed, MT_RAND_PHP) to produce the old sequences.
|
||||
. URL rewriter has been improved.
|
||||
. Use dedicated buffer for Session module rewrite and User rewrite.
|
||||
. Full path URL rewrite is supported. Allowed domain can be specified.
|
||||
$_SERVER['HTTP_HOST'] is allowed by default when host whitelist is empty.
|
||||
. Use session.trans_sid_tags and session.trans_sid_hosts to control
|
||||
session rewrite.
|
||||
. Use url_rewriter.tags and url_rewriter.hosts to control user rewrite.
|
||||
. <form>'s "action" attribute is used to check if URL rewrite is allowed
|
||||
and listed under hosts whitelist.
|
||||
. <fieldset> is no longer considered as a special tag. <form> is the
|
||||
only tag considered special.
|
||||
. Calling a function with less arguments than mandatory declared ones in
|
||||
signature now issues a Fatal Error (Error Exception) instead of a Warning.
|
||||
(RFC https://wiki.php.net/rfc/too_few_args).
|
||||
. The error message for E_RECOVERABLE errors has been changed from "Catchable
|
||||
fatal error" to "Recoverable fatal error".
|
||||
. The empty index operator (e.g. $str[] = $x) is not supported for strings
|
||||
anymore, and throws a fatal error instead of silently converting to array.
|
||||
. Array elements or object properties that are automatically created during
|
||||
by-reference assignments will now result in a different order. For example
|
||||
|
||||
$array = [];
|
||||
$array["a"] =& $array["b"];
|
||||
$array["b"] = 1;
|
||||
var_dump($array);
|
||||
|
||||
now results in the array ["b" => 1, "a" => 1], while for PHP 7.0 the result
|
||||
was ["a" => 1, "b" => 1].
|
||||
. The allowed_classes element of the $options parameter of unserialize() is
|
||||
now strictly typed, i.e. if anything other than an array or a boolean is
|
||||
given, unserialize() returns FALSE and issues an E_WARNING.
|
||||
. $this, autoglobals, and variables with the same name as a parameter can no
|
||||
longer be bound to a closure via the use construct.
|
||||
|
||||
$str = <<<FOO
|
||||
abcdefg
|
||||
FOO
|
||||
FOO;
|
||||
- JSON:
|
||||
. The serialize_precision is used instead of precision when encoding double
|
||||
values.
|
||||
. An empty key is decoded as an empty property name instead of using _empty_
|
||||
property name when decoding object to stdClass.
|
||||
. When calling json_encode with JSON_UNESCAPED_UNICODE option, U+2028 and
|
||||
U+2029 are escaped.
|
||||
|
||||
the indented occurrence of "FOO" did not previously have any special
|
||||
meaning. Now it will be interpreted as the end of the heredoc string and
|
||||
the following "FOO;" will cause a syntax error. This issue can always be
|
||||
resolved by choosing an ending label that does not occur within the contents
|
||||
of the string.
|
||||
. Array accesses of type $obj["123"], where $obj implements ArrayAccess and
|
||||
"123" is an integral string literal will no longer result in an implicit
|
||||
conversion to integer, i.e., $obj->offsetGet("123") will be called instead
|
||||
of $obj->offsetGet(123). This matches existing behavior for non-literals.
|
||||
The behavior of arrays is not affected in any way, they continue to
|
||||
implicitly convert integeral string keys to integers.
|
||||
. In PHP, static properties are shared between inheriting classes, unless the
|
||||
static property is explicitly overridden in a child class. However, due to
|
||||
an implementation artifact it was possible to separate the static properties
|
||||
by assigning a reference. This loophole has been fixed.
|
||||
- mbstring:
|
||||
. mb_ereg() and mb_eregi() will now set the $regs argument to an empty array,
|
||||
if nothing matched. Formerly, $regs was not modified in that case.
|
||||
|
||||
class Test {
|
||||
public static $x = 0;
|
||||
}
|
||||
class Test2 extends Test { }
|
||||
- OpenSSL:
|
||||
. Dropped sslv2 stream.
|
||||
|
||||
Test2::$x = &$x;
|
||||
$x = 1;
|
||||
- Session:
|
||||
. Session ID is generated from CSPRNG directly. As a result, Session ID length
|
||||
could be any length between 22 and 256. Note: Max size of session ID depends
|
||||
on save handler you are using.
|
||||
. Following INIs are removed
|
||||
. session.hash_function
|
||||
. session.hash_bits_per_character
|
||||
. session.entropy_file
|
||||
. session.entropy_length
|
||||
. New INIs and defaults
|
||||
. session.sid_length (Number of session ID characters - 22 to 256.
|
||||
php.ini-* default: 26 Compiled default: 32)
|
||||
. session.sid_bits_per_character (Bits used per character - 4 to 6.
|
||||
php.ini-* default: 5 Compiled default: 4)
|
||||
. Length of old session ID string is determined as follows
|
||||
. Used hash function's bits.
|
||||
. session.hash_function=0 - MD5 128 bits (This was default)
|
||||
. session.hash_function=1 - SHA1 160 bits
|
||||
. Bits per character. (4, 5 or 6 bits per character)
|
||||
. Examples
|
||||
MD5 and 4 bits = 32 chars, ceil(128/4)=32
|
||||
MD5 and 5 bits = 26 chars, ceil(128/5)=26
|
||||
MD5 and 6 bits = 22 chars, ceil(128/6)=22
|
||||
SHA1 and 4 bits = 40 chars, ceil(160/4)=40
|
||||
SHA1 and 5 bits = 32 chars, ceil(160/5)=32
|
||||
SHA1 and 6 bits = 27 chars, ceil(160/6)=27
|
||||
and so on.
|
||||
. session_start() returns FALSE and no longer initializes $_SESSION when
|
||||
it failed to start session.
|
||||
|
||||
var_dump(Test::$x, Test2::$x);
|
||||
// Previously: int(0), int(1)
|
||||
// Now: int(1), int(1)
|
||||
|
||||
. References returned by array and property accesses are now unwrapped as
|
||||
part of the access. This means that it is no longer possible to modify the
|
||||
reference between the access and the use of the accessed value:
|
||||
|
||||
$arr = [1];
|
||||
$ref =& $arr[0];
|
||||
var_dump($arr[0] + ($arr[0] = 2));
|
||||
// Previously: int(4), Now: int(3)
|
||||
|
||||
This makes the behavior of references and non-references consistent. Please
|
||||
note that reading and writing a value inside a single expression remains
|
||||
undefined behavior and may change again in the future.
|
||||
|
||||
BCMath:
|
||||
. All warnings thrown by BCMath functions are now using PHP's error handling.
|
||||
Formerly some warnings have directly been written to stderr.
|
||||
. bcmul() and bcpow() now return numbers with the requested scale. Formerly,
|
||||
the returned numbers may have omitted trailing decimal zeroes.
|
||||
|
||||
mysqli:
|
||||
. Prepared statements now properly report the fractional seconds for DATETIME/
|
||||
TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
|
||||
microseconds). Formerly, the fractional seconds part was simply omitted from
|
||||
the returned values.
|
||||
|
||||
PDO/MySQL:
|
||||
. Prepared statements now properly report the fractional seconds for DATETIME/
|
||||
TIME/TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using
|
||||
microseconds). Formerly, the fractional seconds part was simply omitted from
|
||||
the returned values.
|
||||
Please note that this only affects the usage of PDO_MYSQL with emulated
|
||||
prepares turned off (e.g. using the native preparation functionality).
|
||||
Statements using connections having PDO::ATTR_EMULATE_PREPARES=true (which
|
||||
is the default) were not affected by the bug fixed and have already been
|
||||
getting the proper fractional seconds values from the engine.
|
||||
|
||||
Reflection:
|
||||
. Reflection export to string now uses `int` and `bool` instead of `integer`
|
||||
and `boolean`.
|
||||
|
||||
SPL:
|
||||
. If an SPL autoloader throws an exception, following autoloaders will not be
|
||||
executed. Previously all autoloaders were executed and exceptions were
|
||||
chained.
|
||||
|
||||
SimpleXML:
|
||||
. Mathematic operations involving SimpleXML objects will now treat the text as
|
||||
an integer or float, whichever is more appropriate. Previously values were
|
||||
treated as integers unconditionally.
|
||||
|
||||
Standard:
|
||||
. Undefined variables passed to compact() will now be reported as a notice.
|
||||
. getimagesize() and related functions now report the mime type of BMP images
|
||||
as image/bmp instead of image/x-ms-bmp, since the former has been registered
|
||||
with the IANA (see RFC 7903).
|
||||
- Reflection:
|
||||
. The behavior of ReflectionMethod::invoke() and ::invokeArgs() has been
|
||||
aligned, which causes slightly different behavior than before for some
|
||||
pathological cases.
|
||||
|
||||
========================================
|
||||
2. New Features
|
||||
========================================
|
||||
|
||||
Core:
|
||||
. Implemented flexible heredoc and nowdoc syntax: The closing marker for doc
|
||||
strings is no longer required to be followed by a semicolon or newline.
|
||||
Additionally the closing marker may be indented, in which case the
|
||||
indentation will be stripped from all lines in the doc string.
|
||||
(RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes)
|
||||
. Array destructuring now supports reference assignments using the syntax
|
||||
[&$a, [$b, &$c]] = $d. The same is also supported for list().
|
||||
(RFC: https://wiki.php.net/rfc/list_reference_assignment)
|
||||
. instanceof now allows literals as the first operand,
|
||||
in which case the result is always FALSE.
|
||||
. A new CompileError exception has been added, from which ParseError inherits.
|
||||
A small number of compilation errors will now throw a CompileError instead
|
||||
of generating a fatal error. Currently this only affects compilation errors
|
||||
that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors
|
||||
may be converted in the future.
|
||||
|
||||
BCMath:
|
||||
. bcscale() can now also be used as getter to retrieve the current scale in use.
|
||||
|
||||
MBString:
|
||||
. Support for full case-mapping and case-folding has been added. Unlike simple
|
||||
case-mapping, full case-mapping may change the length of the string. For
|
||||
example:
|
||||
|
||||
mb_strtoupper("Straße")
|
||||
// Produces STRAßE on PHP 7.2
|
||||
// Produces STRASSE on PHP 7.3
|
||||
|
||||
The different casing mapping and folding modes are available through
|
||||
mb_convert_case():
|
||||
|
||||
. MB_CASE_LOWER (used by mb_strtolower)
|
||||
. MB_CASE_UPPER (used by mb_strtoupper)
|
||||
. MB_CASE_TITLE
|
||||
. MB_CASE_FOLD
|
||||
. MB_CASE_LOWER_SIMPLE
|
||||
. MB_CASE_UPPER_SIMPLE
|
||||
. MB_CASE_TITLE_SIMPLE
|
||||
. MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
|
||||
|
||||
Only unconditional, language agnostic full case-mapping is performed.
|
||||
. Case-insensitive string operations now use case-folding instead of case-
|
||||
mapping during comparisons. This means that more characters will be
|
||||
considered (case insensitively) equal now.
|
||||
. mb_convert_case() with MB_CASE_TITLE now performs title-case conversion
|
||||
based on the Cased and CaseIgnorable derived Unicode properties. In
|
||||
particular this also improves handling of quotes and apostophes.
|
||||
. Data tables have been updated for Unicode 11.
|
||||
. Mbstring now correctly supports strings larger than 2GB.
|
||||
. Performance of the mbstring extension has been significantly improved
|
||||
across the board. The largest improvements are in case conversion functions.
|
||||
|
||||
readline:
|
||||
. Support for the completion_append_character and completion_suppress_append
|
||||
options has been added to readline_info(). These options are only available
|
||||
if PHP is linked against libreadline (rather than libedit).
|
||||
|
||||
Standard:
|
||||
. The -–with-password-argon2[=dir] configure argument now provides support for
|
||||
both Argon2i and Argon2id hashes in the password_hash(), password_verify(),
|
||||
password_get_info(), and password_needs_rehash() functions. Passwords may be
|
||||
hashed and verified using the PASSWORD_ARGON2ID constant.
|
||||
Support for both Argon2i and Argon2id in the password_* functions now requires
|
||||
PHP be linked against libargon2 reference library >= 20161029.
|
||||
(RFC: https://wiki.php.net/rfc/argon2_password_hash_enhancements).
|
||||
|
||||
========================================
|
||||
3. Changes in SAPI modules
|
||||
========================================
|
||||
|
||||
phpdbg:
|
||||
. The unused constants PHPDBG_FILE, PHPDBG_METHOD, PHPDBG_LINENO and
|
||||
PHPDBG_FUNC have been removed.
|
||||
|
||||
========================================
|
||||
4. Deprecated Functionality
|
||||
========================================
|
||||
|
||||
GD:
|
||||
. image2wbmp() has been deprecated.
|
||||
|
||||
Intl:
|
||||
. Usage of the Normalizer::NONE form throws a deprecation warning, if PHP is linked with ICU >= 56.
|
||||
|
||||
========================================
|
||||
5. Changed Functions
|
||||
========================================
|
||||
|
||||
JSON:
|
||||
. A new flag has been added, JSON_THROW_ON_ERROR, which can be used with
|
||||
json_decode() or json_encode() and causes these functions to throw a
|
||||
JsonException upon an error, instead of setting the global error state that
|
||||
is retrieved with json_last_error(). JSON_PARTIAL_OUTPUT_ON_ERROR takes
|
||||
precedence over JSON_THROW_ON_ERROR.
|
||||
(RFC: https://wiki.php.net/rfc/json_throw_on_error)
|
||||
|
||||
Standard:
|
||||
. debug_zval_dump() was changed to display recursive arrays and objects
|
||||
in the same way as var_dump(). Now, it doesn't display them twice.
|
||||
. array_push() and array_unshift() can now also be called with a single
|
||||
argument, which is particularly convenient wrt. the spread operator.
|
||||
|
||||
PCRE:
|
||||
. preg_quote() now also escapes the '#' character.
|
||||
|
||||
========================================
|
||||
6. New Functions
|
||||
========================================
|
||||
|
||||
Core:
|
||||
. Added monotonic timer function hrtime([bool get_as_num]). It returns an
|
||||
array of the form [seconds, nanoseconds] with the timestamp starting at
|
||||
an unspecified point in the past. If the optional argument is passed as
|
||||
true, the return value is an integer on 64-bit systems or float on
|
||||
32-bit systems, representing the nanoseconds. The timestamp is not
|
||||
adjustable and is not related to wall clock or time of day. The timers
|
||||
are available under Linux, FreeBSD, Windows, Mac, SunOS, AIX and their
|
||||
derivatives. If no required timers are provided by a corresponding
|
||||
platform, the function returns false.
|
||||
|
||||
Date:
|
||||
. Added the DateTime::createFromImmutable() method, which mirrors
|
||||
DateTimeImmutable::createFromMutable().
|
||||
|
||||
GMP:
|
||||
. Added gmp_binomial(n, k) for calculating binomial coefficients.
|
||||
. Added gmp_lcm(a, b) for calculating the least common multiple.
|
||||
. Added gmp_perfect_power(a) to check if number is a perfect power.
|
||||
. Added gmp_kronecker(a, b) to compute the Kronecker symbol.
|
||||
|
||||
Intl:
|
||||
. Added void Spoofchecker::setRestrictionLevel(int $level) method, available
|
||||
when linked with ICU >= 58.1. Levels are represented as class constants
|
||||
- Spoofchecker::ASCII
|
||||
- Spoofchecker::HIGHLY_RESTRICTIVE
|
||||
- Spoofchecker::MODERATELY_RESTRICTIVE
|
||||
- Spoofchecker::MINIMALLY_RESTRICTIVE
|
||||
- Spoofchecker::UNRESTRICTIVE
|
||||
- Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE
|
||||
For the detailed documentation on the restriction levels, see
|
||||
URestrictionLevel under
|
||||
http://icu-project.org/apiref/icu4c/uspoof_8h.html
|
||||
. Added Normalizer::getRawDecomposition() and normalizer_get_raw_decomposition(),
|
||||
to retrieve the Decomposition_Mapping property of a character.
|
||||
|
||||
OpenSSL:
|
||||
. Added openssl_pkey_derive that derives a shared secret for DH, ECDH and
|
||||
possibly other future algorithms supported by EVP_PKEY_derive.
|
||||
|
||||
Sockets:
|
||||
. Added functions to import/export the WSAPROTOCOL_INFO info struct. This
|
||||
implementation complements the already supported SCM_RIGHTS as in
|
||||
man 3 cmsg and is Windows specific. For the import/export, the default
|
||||
system securities apply for the SHM reading/writing. The socket becomes
|
||||
invalid, when the last reference to it is closed.
|
||||
- socket_wsaprotocol_info_export(resource $sock, int $pid) - exports the
|
||||
WSAPROTOCOL_INFO structure into shared memory and returns an identifier
|
||||
to be used for the import, or false on failure. The exported ID is
|
||||
only valid for the dedicated PID.
|
||||
- socket_wsaprotocol_info_import(string $id) - returns a duplicated
|
||||
socket as per the passed identifier, or false on failure.
|
||||
- socket_wsaprotocol_info_release(string $id) - releases the shared memory
|
||||
corresponding to the passed identifier.
|
||||
|
||||
Standard:
|
||||
. Added is_countable() function, to check whether a value may be passed to
|
||||
count().
|
||||
(RFC: https://wiki.php.net/rfc/is-countable)
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
========================================
|
||||
|
||||
JSON:
|
||||
. JsonException
|
||||
|
||||
========================================
|
||||
8. Removed Extensions and SAPIs
|
||||
========================================
|
||||
|
||||
========================================
|
||||
9. Other Changes to Extensions
|
||||
========================================
|
||||
|
||||
Curl:
|
||||
. libcurl >= 7.15.5 is now required.
|
||||
|
||||
Filter:
|
||||
. FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which
|
||||
defines the set of allowed thousand separator chars. The default (`"',."`)
|
||||
is fully backward compatible with former PHP versions.
|
||||
|
||||
FTP:
|
||||
. Set default transfer mode to binary
|
||||
|
||||
Intl:
|
||||
. Normalizer::NONE is deprecated, when PHP is linked with ICU >= 56
|
||||
. Introduced Normalizer::FORM_KC_CF as Normalizer::normalize() argument
|
||||
for NFKC_Casefold normalization, available when linked with ICU >= 56
|
||||
|
||||
MBString:
|
||||
. The configuration option --with-libmbfl is no longer available.
|
||||
|
||||
ODBC:
|
||||
. Support for ODBCRouter has been removed.
|
||||
. Support for Birdstep has been removed.
|
||||
|
||||
PCRE:
|
||||
. The PCRE extension has been upgraded to PCRE2, which may cause minor
|
||||
behavioral changes, and augments the existing regular expression syntax.
|
||||
See <https://wiki.php.net/rfc/pcre2-migration> for details.
|
||||
|
||||
ZIP:
|
||||
. Bundled libzip has been dropped,
|
||||
system library is now required.
|
||||
|
||||
========================================
|
||||
10. New Global Constants
|
||||
========================================
|
||||
|
||||
Curl:
|
||||
. CURLOPT_REQUEST_TARGET
|
||||
|
||||
JSON:
|
||||
. JSON_THROW_ON_ERROR
|
||||
|
||||
PGSQL:
|
||||
. Requires Postgres 9.3
|
||||
- PGSQL_DIAG_SCHEMA_NAME
|
||||
- PGSQL_DIAG_TABLE_NAME
|
||||
- PGSQL_DIAG_COLUMN_NAME
|
||||
- PGSQL_DIAG_DATATYPE_NAME
|
||||
- PGSQL_DIAG_CONSTRAINT_NAME
|
||||
. Requires Postgres 9.6
|
||||
- PGSQL_DIAG_SEVERITY_NONLOCALIZED
|
||||
|
||||
Standard:
|
||||
. PASSWORD_ARGON2ID
|
||||
|
||||
========================================
|
||||
11. Changes to INI File Handling
|
||||
========================================
|
||||
|
||||
- birdstep.max_links
|
||||
. This INI directive has been removed.
|
||||
|
||||
- opcache.inherited_hack
|
||||
. This INI directive has been removed. The value has already been ignored
|
||||
since PHP 5.3.0.
|
||||
|
||||
- syslog.facility
|
||||
- New INI to set syslog facility which specifies what type of program is
|
||||
logging the message. It is used only when error_log is set to syslog.
|
||||
|
||||
- syslog.ident
|
||||
. New INI to set syslog ident string which is prepended to every message. It
|
||||
is used only when error_log is set syslog.
|
||||
|
||||
========================================
|
||||
12. Windows Support
|
||||
========================================
|
||||
|
||||
- Core
|
||||
. File descriptors are opened in shared read/write/delete mode by default.
|
||||
This effectively maps the UNIX semantics and allows to delete files with
|
||||
handles in use. It is not 100% same, some platform differences still
|
||||
persist. After the deletion, the filename entry is blocked, until all
|
||||
the opened handles to it are closed.
|
||||
. Added void return type, which requires that a function not return a value.
|
||||
(RFC: https://wiki.php.net/rfc/void_return_type)
|
||||
. Added iterable pseudo-type accepting any array or object implementing
|
||||
Traversable.
|
||||
(RFC: https://wiki.php.net/rfc/iterable)
|
||||
. String offset access now supports negative references, which will be
|
||||
counted from the end of the string.
|
||||
(RFC: https://wiki.php.net/rfc/negative-string-offsets)
|
||||
. Added a form of the list() construct where keys can be specified.
|
||||
(RFC: https://wiki.php.net/rfc/list_keys)
|
||||
. Added [] = as alternative construct to list() =.
|
||||
(RFC: https://wiki.php.net/rfc/short_list_syntax)
|
||||
. Number operators taking numeric strings now emit "A non well formed numeric
|
||||
value encountered" E_NOTICEs for leading-numeric strings, and "A
|
||||
non-numeric value encountered" E_WARNINGs for non-numeric strings.
|
||||
This always applies to the +, -, *, /, **, %, << and >> operators, and
|
||||
their assignment counterparts +=, -=, *=, /=, **=, %=, <<= and >>=.
|
||||
For the bitwise operators |, & and ^, and their assignment counterparts
|
||||
|=, &= and ^=, this only applies where only one operand is a string.
|
||||
Note that this never applies to the bitwise NOT operator, ~, which does not
|
||||
handle numeric strings, nor to the increment and decrement operators
|
||||
++ and --, which have a unique approach to handling numeric strings.
|
||||
(RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic)
|
||||
. Closure::fromCallable (RFC: https://wiki.php.net/rfc/closurefromcallable)
|
||||
. Added support for class constant visibility modifiers.
|
||||
(RFC: https://wiki.php.net/rfc/class_const_visibility)
|
||||
. TypeError messages for arg_info type checks will now say "must be ...
|
||||
or null", or "must ... or be null" where the parameter or return type
|
||||
accepts null. arg_info type checks are used by all userland functions with
|
||||
type declarations, and some internal functions. Both nullable type
|
||||
declarations (?int) and parameters with default values of null
|
||||
(int $foo = NULL) are considered to "accept null" for this purpose.
|
||||
. The simple syntax for variable parsing inside of string literals now
|
||||
supports negative offsets.
|
||||
|
||||
========================================
|
||||
3. Changes in SAPI modules
|
||||
========================================
|
||||
- apache2handler:
|
||||
. Implemented per module logging.
|
||||
. Implemented error level mapping between PHP and Apache for the error logs.
|
||||
|
||||
========================================
|
||||
4. Deprecated Functionality
|
||||
========================================
|
||||
|
||||
- 'e' option of mb_ereg_replace() and mb_eregi_replace().
|
||||
- ext/mcrypt is now fully deprecated.
|
||||
|
||||
========================================
|
||||
5. Changed Functions
|
||||
========================================
|
||||
- get_headers() has an extra parameter which allows passing a custom stream
|
||||
context.
|
||||
- The first $varname argument for getenv() is no longer mandatory, the
|
||||
current environment variables will be returned as an associative array
|
||||
when omitted.
|
||||
- json_encode() accepts new option JSON_UNESCAPED_LINE_TERMINATORS that
|
||||
disables escaping of U+2028 and U+2029 characters when
|
||||
JSON_UNESCAPED_UNICODE is supplied.
|
||||
- long2ip() accepts integer as parameter now
|
||||
- openssl_encrypt and openssl_decrypt have extra parameters for handling
|
||||
authenticated encryption (tag, aad, tag_length) and decryption (tag, aad).
|
||||
- pg_last_notice() accepts optional long parameter to specify operation.
|
||||
PGSQL_NOTICE_LAST - Get last notice (Default)
|
||||
PGSQL_NOTICE_ALL - Get all stored notices
|
||||
PGSQL_NOTICE_CLEAR - Remove all stored notices
|
||||
It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls.
|
||||
It returned FALSE for empty notice previously.
|
||||
- pg_fetch_all() accepts 2nd optional result type parameter like
|
||||
pg_fetch_row().
|
||||
- pg_select() accepts 4th optional result type parameter like pg_fetch_row().
|
||||
- parse_url() is more restrictive now and supports RFC3986.
|
||||
- unpack() accepts an additional optional $offset argument. '@' format code
|
||||
(that specifes an absolute position) is applyed to input data after
|
||||
the $offset argument.
|
||||
- strpos(), stripos(), substr_count(), grapheme_strpos(), grapheme_stripos(),
|
||||
grapheme_extract(), iconv_strpos(), mb_strimwidth(), mb_ereg_search_setpos(),
|
||||
mb_strpos() and mb_stripos() now accept negative string offsets.
|
||||
- substr_count() and mb_strimwidth() additionally also accept negative length.
|
||||
- file_get_contents() accepts a negative seek offset if the stream is seekable.
|
||||
- tempnam() throws a notice when failing back to the system temp dir.
|
||||
- getopt() has an extra by-ref parameter : optind
|
||||
- mb_ereg() and mb_ereg_replace() reject illegal byte sequences.
|
||||
- FILTER_FLAG_EMAIL_UNICODE can be used with filter_var() for email validation
|
||||
according to RFC 6531.
|
||||
- output_reset_rewrite_vars() no longer reset session URL rewrite vars.
|
||||
- the lasinsertid() in pdo_pgsql extension triggers an error, when no nextval()
|
||||
were called in in the current session.
|
||||
- fopen()
|
||||
Since 7.1.2, mode 'e' was added, which sets the close-on-exec flag
|
||||
on the opened file descriptor. This mode is only available in PHP compiled on
|
||||
POSIX.1-2008 conform systems.
|
||||
|
||||
|
||||
========================================
|
||||
6. New Functions
|
||||
========================================
|
||||
- Core:
|
||||
. Added sapi_windows_cp_set(), sapi_windows_cp_get(), sapi_windows_cp_is_utf8(),
|
||||
sapi_windows_cp_conv() for codepage handling.
|
||||
|
||||
- cURL:
|
||||
. Added curl_multi_errno() and curl_share_errno() to return the last error
|
||||
number of curl_multi and curl_share resources.
|
||||
. Added curl_share_strerror() to convert error code to error message text
|
||||
describing the error.
|
||||
|
||||
- Hash:
|
||||
. In PHP 7.1.2: Added hash_hkdf() function, which implements the HMAC-based
|
||||
Key Derivation Function (HKDF) algorithm according to RFC 5869. The
|
||||
implementation combines the Extract and Expand steps.
|
||||
|
||||
- pcntl:
|
||||
. Added pcntl_signal_get_handler() that returns the current signal handler
|
||||
for a particular signal.
|
||||
|
||||
- Session:
|
||||
. Added session_gc() that performs session data garbage collection.
|
||||
https://wiki.php.net/rfc/session-gc
|
||||
. Added session_create_id() for creating custom session ID.
|
||||
https://wiki.php.net/rfc/session-create-id
|
||||
|
||||
- Standard:
|
||||
. Added is_iterable() that determines if a value will be accepted by the new
|
||||
iterable pseudo-type.
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
========================================
|
||||
|
||||
========================================
|
||||
8. Removed Extensions and SAPIs
|
||||
========================================
|
||||
|
||||
========================================
|
||||
9. Other Changes to Extensions
|
||||
========================================
|
||||
|
||||
- Date:
|
||||
. Invalid serialization data for a DateTime or DatePeriod object will now
|
||||
throw an instance of Error from __wakeup() or __set_state() instead of
|
||||
resulting in a fatal error.
|
||||
. Timezone initialization failure from serialized data will now throw an
|
||||
instance of Error from __wakeup() or __set_state() instead of resulting in
|
||||
a fatal error.
|
||||
. DateTime and DateTimeImmutable now properly incorporate microseconds when
|
||||
constructed from the current time, either explicitly or with a relative
|
||||
string (e.g. "first day of next month"). This means that naive comparisons
|
||||
of two newly created instances will now more likely return FALSE instead of
|
||||
TRUE:
|
||||
new DateTime() == new DateTime();
|
||||
|
||||
- DBA:
|
||||
. Data modification functions (e.g.: dba_insert()) now throw an instance of
|
||||
Error instead of triggering a catchable fatal error if the key does not
|
||||
contain exactly two elements.
|
||||
|
||||
- DOM:
|
||||
. Invalid schema or RelaxNG validation contexts will throw an instance of
|
||||
Error instead of resulting in a fatal error.
|
||||
. Attempting to register a node class that does not extend the appropriate
|
||||
base class will now throw an instance of Error instead of resulting in a
|
||||
fatal error.
|
||||
. Attempting to read an invalid or write to a readonly property will throw
|
||||
an instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- GD:
|
||||
. Changed the default of the ini setting gd.jpeg_ignore_warning to 1.
|
||||
|
||||
- IMAP:
|
||||
. An email address longer than 16385 bytes will throw an instance of Error
|
||||
instead of resulting in a fatal error.
|
||||
|
||||
- Intl:
|
||||
. Failure to call the parent constructor in a class extending Collator
|
||||
before invoking the parent methods will throw an instance of Error
|
||||
instead of resulting in a recoverable fatal error.
|
||||
. Cloning a Transliterator object may will now throw an instance of Error
|
||||
instead of resulting in a fatal error if cloning the internal
|
||||
transliterator fails.
|
||||
|
||||
- LDAP:
|
||||
. Providing an unknown modification type to ldap_batch_modify() will now
|
||||
throw an instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- Mbstring:
|
||||
. mb_ereg() and mb_eregi() will now throw an instance of ParseError if an
|
||||
invalid PHP expression is provided and the 'e' option is used.
|
||||
|
||||
- Mcrypt:
|
||||
. mcrypt_encrypt() and mcrypt_decrypt() will throw an instance of Error
|
||||
instead of resulting in a fatal error if mcrypt cannot be initialized.
|
||||
|
||||
- Mysqli:
|
||||
. Attempting to read an invalid or write to a readonly property will throw
|
||||
an instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- PDO_Firebird
|
||||
As of PHP 7.1.2, the fetched data for integer fields is aware of the Firebird
|
||||
datatypes. Previously all integers was fetched as strings, starting with
|
||||
aforementioned PHP version integer fields are translated to the PHP integer
|
||||
datatype. The 64-bit integers are still fetched as strings in 32-bit PHP
|
||||
builds.
|
||||
|
||||
- Reflection:
|
||||
. Failure to retrieve a reflection object or retrieve an object property
|
||||
will now throw an instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- Session:
|
||||
. Custom session handlers that do not return strings for session IDs will
|
||||
now throw an instance of Error instead of resulting in a fatal error
|
||||
when a function is called that must generate a session ID.
|
||||
. Only CSPRNG is used to generate session ID.
|
||||
|
||||
- SimpleXML:
|
||||
. Creating an unnamed or duplicate attribute will throw an instance of Error
|
||||
instead of resulting in a fatal error.
|
||||
|
||||
- SPL:
|
||||
. Attempting to clone an SplDirectory object will throw an instance of Error
|
||||
instead of resulting in a fatal error.
|
||||
. Calling ArrayIterator::append() when iterating over an object will throw an
|
||||
instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- SQLite3:
|
||||
. Upgraded bundled SQLite lib to 3.13.0
|
||||
|
||||
- Standard:
|
||||
. assert() will throw a ParseError when evaluating a string given as the first
|
||||
argument if the PHP code is invalid instead of resulting in a catchable
|
||||
fatal error.
|
||||
. Calling forward_static_call() outside of a class scope will now throw an
|
||||
instance of Error instead of resulting in a fatal error.
|
||||
|
||||
- Tidy:
|
||||
. Creating a tidyNode manually will now throw an instance of Error instead of
|
||||
resulting in a fatal error.
|
||||
|
||||
- WDDX:
|
||||
. A circular reference when serializing will now throw an instance of Error
|
||||
instead of resulting in a fatal error.
|
||||
|
||||
- XML-RPC:
|
||||
. A circular reference when serializing will now throw an instance of Error
|
||||
instead of resulting in a fatal error.
|
||||
|
||||
- Zip:
|
||||
. ZipArchive::addGlob() will throw an instance of Error instead of resulting
|
||||
in a fatal error if glob support is not available.
|
||||
|
||||
========================================
|
||||
10. New Global Constants
|
||||
========================================
|
||||
|
||||
- Core:
|
||||
. PHP_FD_SETSIZE
|
||||
|
||||
- JSON:
|
||||
. JSON_UNESCAPED_LINE_TERMINATORS
|
||||
|
||||
- Pgsql:
|
||||
PGSQL_NOTICE_LAST
|
||||
PGSQL_NOTICE_ALL
|
||||
PGSQL_NOTICE_CLEAR
|
||||
|
||||
- Standard:
|
||||
. IMAGETYPE_WEBP
|
||||
|
||||
========================================
|
||||
11. Changes to INI File Handling
|
||||
========================================
|
||||
|
||||
- serialize_precision
|
||||
. If the value is set to -1, then the dtoa mode 0 is used. The value -1
|
||||
is now used by default.
|
||||
|
||||
- precision
|
||||
. If the value is set to -1, then the dtoa mode 0 is used. No changes
|
||||
in default value which is still 14.
|
||||
|
||||
- realpath_cache_size
|
||||
. Set to 4096k by default
|
||||
|
||||
========================================
|
||||
12. Windows Support
|
||||
========================================
|
||||
|
||||
- Core:
|
||||
. Support for long and UTF-8 path;
|
||||
|
||||
If a web application is UTF-8 conform, no further action is required. For
|
||||
applications depending on paths in non UTF-8 encodings for I/O, an explicit
|
||||
INI directive has to be set. The encoding INI settings check relies on the
|
||||
order in the core:
|
||||
- internal_encoding
|
||||
- default_charset
|
||||
- zend.multibyte
|
||||
|
||||
Several functions for codepage handling were itroduced:
|
||||
- sapi_windows_cp_set() to set the default codepage
|
||||
- sapi_windows_cp_get() to retrieve the current codepage
|
||||
- sapi_windows_cp_is_utf8()
|
||||
- sapi_windows_cp_conv() to convert between codepages, using iconv()
|
||||
compatible signature
|
||||
These functions are thread safe.
|
||||
|
||||
The console output codepage is adjusted depending on the encoding used in
|
||||
PHP. Depending on the concrete system OEM codepage, the visible output
|
||||
might or might be not correct. For example, in the default cmd.exe and on
|
||||
a system with the OEM codepage 437, outputs in codepages 1251, 1252, 1253
|
||||
and some others can be shown correctly when using UTF-8. On the same system,
|
||||
chars in codepage like 20932 probably won't be shown correctly. This refers
|
||||
to the particular system rules for codepage, font compatibility and the
|
||||
particular console program used. PHP automatically sets the console codepage
|
||||
according to the encoding rules from php.ini. Using alternative consoles
|
||||
instead of cmd.exe directly might bring better experience in some cases.
|
||||
|
||||
Nevertheless be aware, runtime codepage switch after the request start
|
||||
might bring unexpected side effects on CLI. The preferrable way is php.ini,
|
||||
When PHP CLI is used in a console emulator, that doesn't support Unicode,
|
||||
it might possibly be required, to avoid changing the console codepage. The
|
||||
best way to achieve it is by setting the default or internal encoding to
|
||||
correspond the ANSI codepage. Another method is to set the INI directives
|
||||
output_encoding and input_encoding to the required codepage, in which case
|
||||
however the difference between internal and I/O codepage is likely to cause
|
||||
mojibake. In rare cases, if PHP happens to crash gracefully, the original
|
||||
console codepage might be not restored. In this case, the chcp command
|
||||
can be used, to restore it manually.
|
||||
|
||||
Special awareness for the DBCS systems - the codepage switch on runtime
|
||||
using ini_set() is likely to cause display issues. The difference to the
|
||||
non DBCS systems is, that the extended characters require two console cells
|
||||
to be displayed. In certain case, only the mapping of the characters into
|
||||
the glyph set of the font could happen, no actual font change. This is the
|
||||
nature of DBCS systems, the most simple way to prevent display issues is
|
||||
to avoid usage of ini_set() for the codepage change.
|
||||
|
||||
As a result of UTF-8 support in the streams, PHP scripts are not limited
|
||||
to ASCII or ANSI filenames anymore. This is supported out of the box on
|
||||
CLI. For other SAPI, the documentation for the corresponding server
|
||||
is useful.
|
||||
|
||||
Long paths support is transparent. Paths longer than 260 bytes get
|
||||
automatically prefixed with \\?\. The max path length is limited to
|
||||
2048 bytes. Be aware, that the path segment limit (basename length) still
|
||||
persists.
|
||||
|
||||
For the best portability, it is strongely recommended to handle filenames,
|
||||
I/O and other related topics UTF-8. Additionally, for the console applications,
|
||||
the usage of a TrueType font is preferrable and the usage of ini_set() for
|
||||
the codepage change is discouraged.
|
||||
|
||||
. Support for ftok()
|
||||
|
||||
- FCGI
|
||||
. PHP_FCGI_CHILDREN is respected. If this environment variable is defined,
|
||||
the first php-fcgi.exe process will exec the specified number of children.
|
||||
Those will share the same TCP socket.
|
||||
|
||||
- readline:
|
||||
. The readline extension is supported through the WinEditLine library
|
||||
(http://mingweditline.sourceforge.net/). Thereby, the interactive CLI
|
||||
shell is supported as well (php.exe -a).
|
||||
|
||||
It is well known, but nevertheless is worth mentioning again, that
|
||||
the readline extension is not thread safe and will never be. Thus,
|
||||
the usage of it with any true thread safe SAPI (like Apache mod_winnt) is
|
||||
strongely discouraged.
|
||||
|
||||
========================================
|
||||
13. Other Changes
|
||||
|
||||
+55
-127
@@ -1,142 +1,79 @@
|
||||
PHP 7.3 INTERNALS UPGRADE NOTES
|
||||
PHP 7.1 INTERNALS UPGRADE NOTES
|
||||
|
||||
0. Wiki Examples
|
||||
1. Internal API changes
|
||||
a. array_init() and array_init_size()
|
||||
b. Run-time constant operand addressing
|
||||
c. Array/Object recursion protection
|
||||
d. HASH_FLAG_PERSISTENT
|
||||
e. AST and IS_CONSTANT
|
||||
f. GC_REFCOUNT()
|
||||
g. zend_get_parameters()
|
||||
h. zend_register_persistent_resource()
|
||||
i. RAND_RANGE()
|
||||
j. cast_object() with _IS_NUMBER
|
||||
k. zend_fcall_info_cache.initialized
|
||||
l. php_hrtime_current()
|
||||
m. zend_cpu_supports()
|
||||
n. IS_TYPE_COPYABLE
|
||||
o. IS_UNUSED
|
||||
p. VM instruction operands (FETCH_CLASS, FETCH_CONSTANT, CATCH)
|
||||
q. sapi_cli_single_write()
|
||||
r. php_url
|
||||
s. zend_function.reserved[]
|
||||
t. zif_handler
|
||||
e. Codepage handling on Windows
|
||||
f. Path handling on Windows
|
||||
g. SAPI logging
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
b. Windows build system changes
|
||||
|
||||
|
||||
3. Module changes
|
||||
|
||||
================
|
||||
0. Wiki Examples
|
||||
================
|
||||
|
||||
The wiki contains multiple examples and further explanations of the internal
|
||||
changes. See: https://wiki.php.net/phpng-upgrading
|
||||
|
||||
|
||||
========================
|
||||
1. Internal API changes
|
||||
========================
|
||||
|
||||
a. array_init() and array_init_size() are not functions anymore.
|
||||
They don't return any values.
|
||||
e. Codepage handling on Windows
|
||||
|
||||
A set of new APIs was introduced, which allows to handle codepage
|
||||
conversions. The corresponding prototypes and macros are contained
|
||||
in win32/codepage.h.
|
||||
|
||||
b. In 64-bit builds PHP-7.2 and below used relative run-time constant operand
|
||||
addressing. E.g. opline->op1.constant kept an offset from start of literals
|
||||
table - op_array->literals. To speedup access op_array->literals was cached
|
||||
in execute_data->literals. So the resulting address calculated as
|
||||
EX(literals) + opline->op1.constant.
|
||||
Functions with php_win32_cp_* signatures provide handling for various
|
||||
codepage aspects. Primarily they are in use at various places in the
|
||||
I/O utils code and directly in the core where necessary, providing
|
||||
conversions to/from UTF-16. Arbitrary conversions between codepages
|
||||
are possible as well, whereby UTF-16 will be always an intermediate
|
||||
state in this case.
|
||||
|
||||
Now at run-time literals allocated close to opcodes, and addressed
|
||||
relatively from current opline. This eliminates load of EX(literals) on
|
||||
each constant access as well as EX(literals) initialization on each call.
|
||||
For input length arguments, the macro PHP_WIN32_CP_IGNORE_LEN can be
|
||||
passed, then the API will calculate the length. For output length
|
||||
arguments, the macro PHP_WIN32_CP_IGNORE_LEN_P can be passed, then
|
||||
the API won't set the output length.
|
||||
|
||||
As result some related macros were removed (ZEND_EX_USE_LITERALS,
|
||||
EX_LOAD_LITERALS, EX_LITERALS, RT_CONSTANT_EX, EX_CONSTANT) or changed
|
||||
(RT_CONSTANT, ZEND_PASS_TWO_UPDATE_CONSTANT, ZEND_PASS_TWO_UNDO_CONSTANT).
|
||||
This change way affect only some "system" extensions. EX_LITERALS,
|
||||
RT_CONSTANT_EX, EX_CONSTANT should be substituted by RT_CONSTANT than now
|
||||
use "opline" (instead of "op_array") as first argument.
|
||||
The mapping between encodings and codepages is provided by the predefined
|
||||
array of data contained in win32/cp_enc_map.c. To change the data,
|
||||
a generator win32/cp_enc_map_gen.c needs to be edited and run.
|
||||
|
||||
c. Protection from recursion during processing circular data structures was
|
||||
refactored. HashTable.nApplyCount and IS_OBJ_APPLY_COUNT are replaced by
|
||||
single flag GC_PROTECTED. Corresponding macros Z_OBJ_APPLY_COUNT,
|
||||
Z_OBJ_INC_APPLY_COUNT, Z_OBJ_DEC_APPLY_COUNT, ZEND_HASH_GET_APPLY_COUNT,
|
||||
ZEND_HASH_INC_APPLY_COUNT, ZEND_HASH_DEC_APPLY_COUNT are replaced with
|
||||
GC_IS_RECURSIVE, GC_PROTECT_RECURSION, GC_UNPROTECT_RECURSION,
|
||||
Z_IS_RECURSIVE, Z_PROTECT_RECURSION, Z_UNPROTECT_RECURSION.
|
||||
f. Path handling on Windows
|
||||
|
||||
HASH_FLAG_APPLY_PROTECTION flag and ZEND_HASH_APPLY_PROTECTION() macro
|
||||
are removed. All mutable arrays should use recursion protection.
|
||||
Corresponding checks should be replaced by Z_REFCOUNTED() or
|
||||
!(GC_GLAGS(p) & GC_IMMUTABLE).
|
||||
A set of new APIs was introduced, which allows to handle UTF-8 paths. The
|
||||
corresponding prototypes and macros are contained in win32/ioutil.h.
|
||||
|
||||
d. HASH_FLAG_PERSISTENT renamed into IS_ARRAY_PERSISTENT and moved into
|
||||
GC_FLAGS (to be consistent with IS_STR_PERSISTENT).
|
||||
Functions with php_win32_ioutil_* signatures provide POSIX I/O analogues.
|
||||
These functions are integrated in various places across the code base to
|
||||
support Unicode filenames. While accepting char * arguments, internally
|
||||
the conversion to wchar_t * happens. Internally almost no ANSI APIs are
|
||||
used, but directly their wide equivalents. The string conversion rules
|
||||
correspond to those already present in the core and depend on the current
|
||||
encoding settings. Doing so allows to move away from the ANSI Windows API
|
||||
with its dependency on the system OEM/ANSI codepage.
|
||||
|
||||
e. zend_ast_ref structure is changed to use only one allocation.
|
||||
zend_ast_copy() now returns zend_ast_ref (instead of zend_asr).
|
||||
zend_ast_destroy_and_free() is removed. ZVAL_NEW_AST() is replaced
|
||||
by ZVAL_AST().
|
||||
Thanks to the wide API usage, the long paths are now supported as well. The
|
||||
PHP_WIN32_IOUTIL_MAXPATHLEN macro is defined to 2048 bytes and will override
|
||||
the MAXPATHLEN in files where the header is included.
|
||||
|
||||
IS_CONSTANT type and Z_CONST_FLAGS() are removed. Now constants are always
|
||||
represented using IS_CONSTANT_AST (ZEND_AST_CONSTANT kind). AST node
|
||||
attributes are used instead of constant flags. IS_TYPE_CONSTANT flag is
|
||||
removed, but Z_CONSTANT() macro is kept for compatibility.
|
||||
The most optimal use case for scripts is utilizing UTF-8 for any I/O
|
||||
related functions. UTF-8 filenames are supported on any system disregarding
|
||||
the system OEM/ANSI codepage.
|
||||
|
||||
f. GC_REFCOUNT() is turned into inline function and can't be modified direcly.
|
||||
All reference-counting operations should be done through corresponding
|
||||
macros GC_SET_REFCOUNT(), GC_ADDREF() and GC_DELREF().
|
||||
g. SAPI logging
|
||||
The log_message callback in the SAPI struct was extended with the severity
|
||||
argument. This allows SAPI modules to implement mapping between PHP and
|
||||
corresponding server error levels. A reference mapping implementation
|
||||
can be found in apache2handler.
|
||||
|
||||
GC_REFCOUNT(p)++ should be changed into GC_ADDREF(p),
|
||||
GC_REFCOUNT(p)-- into GC_DELREF(p),
|
||||
GC_REFCOUNT(p) = 1 into GC_SET_REFCOUNT(p, 1).
|
||||
|
||||
g. The zend_get_parameters() and zend_get_parameters_ex() functions were
|
||||
removed. Instead zend_parse_parameters() should be used.
|
||||
|
||||
h. New functions zend_register_persistent_resource() or
|
||||
zend_register_persistent_resource_ex() should beused to register
|
||||
persistent resources, instead of manual insertion into EG(persistent_list).
|
||||
|
||||
i. The RANGE_RANGE() macro has been removed. php_mt_rand_range() should be
|
||||
used instead.
|
||||
|
||||
j. The cast_object() object handler now also accepts the _IS_NUMBER type. The
|
||||
handler should return either an integer or float value in this case,
|
||||
whichever is more appropriate.
|
||||
|
||||
k. zend_fcall_info_cache.initialized is removed. zend_fcall_info_cache is
|
||||
initialized if zend_fcall_info_cache.function_handler is set.
|
||||
|
||||
l. php_hrtime_current() delivers the number of nanoseconds since an uncertain
|
||||
point in the past.
|
||||
|
||||
m. zend_cpu_supports() determines if a feature is supported by current cpu.
|
||||
Also serial inline zend_cpu_supports_xxx() are added, which is designed for
|
||||
ifunc resolver function, as resolver function should not depend on any
|
||||
external function.
|
||||
|
||||
n. IS_TYPE_COPYABLE flag is removed. IS_STRING zvals didn't need to be
|
||||
duplication by zval_copy_ctor(), ZVAL_DUP() and SEPARATE_ZVAL*() macros.
|
||||
Interned strings didn't set IS_TYPE_COPYALE, so they aren't affected at
|
||||
all. Now instead of checking for IS_TYPE_COPYABLE, engine checks for
|
||||
IS_ARRAY type (it may be IS_TYPE_REFCOUNTED or not). All the related
|
||||
macros: Z_COPYABLE..., Z_IMMUTABLE... are kept for compatibility.
|
||||
|
||||
o. IS_UNUSED became zero and can't be used as a bitmask (there were no such
|
||||
usages in PHP sources).
|
||||
|
||||
p. Operands of few VM instructions were changed
|
||||
- FETCH_CLASS op1<fetch-flags>, op2<name>, result<var>
|
||||
- FETCH_CONSTANT op1<fetch-flags>, op2<name>, result<tmp>
|
||||
- CATCH ext<last-flag>, op1<name>, op2<jump_addr>, result<cv>
|
||||
|
||||
q. sapi_cli_single_write() now returns ssize_t instead of size_t.
|
||||
|
||||
r. fields of php_url struct change from char * to zend_string *
|
||||
|
||||
s. Special purpose zend_functions marked by ZEND_ACC_CALL_VIA_TRAMPOLINE or
|
||||
ZEND_ACC_FAKE_CLOSURE flags use reserved[0] for internal purpose.
|
||||
Third party extensions must not modify reserved[] fields of these functions.
|
||||
|
||||
t. For internal functions the typedef zif_handler has been introduced. It is
|
||||
recommended to use this from now on, instead of defining own handler types.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
@@ -145,17 +82,8 @@ PHP 7.3 INTERNALS UPGRADE NOTES
|
||||
a. Unix build system changes
|
||||
|
||||
b. Windows build system changes
|
||||
- ZEND_WIN32_FORCE_INLINE doesn't affect C++ anymore. zend_always_inline is
|
||||
still usable in C++, but anything else inlining related is up to
|
||||
compiler.
|
||||
- ZEND_WIN32_KEEP_INLINE was removed, it was only needed for C++
|
||||
convenience and is now default behavior with C++.
|
||||
- New configure option --enable-native-intrinsics accepts a list of the
|
||||
intrinsic optimizations to enable. It affects both the code generation
|
||||
and the explicit optimizations guarded by preprocessor macros.
|
||||
- The configure option --with-codegen-arch accepts only ia32 as a value.
|
||||
Use it, to produce builds suitable for older processors without SSE2 or
|
||||
even SSE support.
|
||||
Static analysis with clang and Cppcheck is supported by passing "clang" or
|
||||
"cppcheck" keyword to the --with-analyzer configure option.
|
||||
|
||||
========================
|
||||
3. Module changes
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ libZend_la_SOURCES=\
|
||||
zend_default_classes.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
|
||||
zend_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c zend_cpuinfo.c
|
||||
zend_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c
|
||||
|
||||
libZend_la_CFLAGS = -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
|
||||
libZend_la_LDFLAGS =
|
||||
|
||||
@@ -100,3 +100,9 @@ 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().
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
Revamped object model using object handles
|
||||
===========================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
In the Zend Engine 1.0 (and its predecessor the PHP 3 scripting
|
||||
engine) the object model's design is that instantiated objects are
|
||||
language values. This means that when programmers are performing
|
||||
operations, such variable assignment and passing parameters to
|
||||
functions, objects are handled very similarly to the way other
|
||||
primitive types are handled such as integers and strings.
|
||||
Semantically this means that the whole object is being copied. The
|
||||
approach Java takes is different where one refers to objects by handle
|
||||
and not by value (one can think of a handle as an objects' ID).
|
||||
|
||||
Need
|
||||
----
|
||||
|
||||
Unfortunately, the approach taken up to now has severely limited the
|
||||
Zend Engine's object oriented model, both feature and simplicity
|
||||
wise. One of the main problems with the former approach is that object
|
||||
instantiation and duplication is very hard to control, a problem which
|
||||
can not only lead to inefficient development but also often to strange
|
||||
run-time behavior. Changing the object model to a handle oriented
|
||||
model will allow the addressing of many needs such as destructors,
|
||||
de-referencing method return values, tight control of object
|
||||
duplication and more.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The proposed object model is very much influenced by the Java
|
||||
model. In general, when you create a new object you will be getting a
|
||||
handle to the object instead of the object itself. When this handle is
|
||||
sent to functions, assigned and copied it is only the handle which is
|
||||
copied/sent/assigned. The object itself is never copied nor
|
||||
duplicated. This results in all handles of this object to always point
|
||||
at the same object making it a very consistent solution and saving
|
||||
unnecessary duplication and confusing behavior.
|
||||
|
||||
Functionality
|
||||
-------------
|
||||
|
||||
After this change the basic use of objects will be almost identical to
|
||||
previous versions of the scripting engine. However, you won't bump
|
||||
into awkward and confusing copying & destructing of objects. In order
|
||||
to create and use a new object instance you will do the following:
|
||||
$object = new MyClass(); $object->method();
|
||||
|
||||
The previous code will assign $object the handle of a new instance of
|
||||
the class MyClass and call one of its methods.
|
||||
|
||||
|
||||
Consider the following code:
|
||||
|
||||
1 class MyClass
|
||||
2 {
|
||||
3 function setMember($value)
|
||||
4 {
|
||||
5 $this->member = $value;
|
||||
6 }
|
||||
7
|
||||
8 function getMember()
|
||||
9 {
|
||||
10 return $this->member;
|
||||
11 }
|
||||
12 }
|
||||
13
|
||||
14 function foo($obj)
|
||||
15 {
|
||||
16 $obj->setMember("foo");
|
||||
17 }
|
||||
18
|
||||
19 $object = new MyClass();
|
||||
20 $object->setMember("bar");
|
||||
21 foo($object);
|
||||
22 print $object->getMember();
|
||||
|
||||
Without the new Java-like handles, at line 20 the objects' data member
|
||||
member is set to the string value of "bar". Because of the internal
|
||||
representation of objects in the Zend Engine 1.0, the object is marked
|
||||
as a reference, and when it is sent by value to the function foo, it
|
||||
is duplicated (!). Therefore, the call to foo() on line 21 will
|
||||
result in the $obj->setMember("foo") call being called on a duplicate
|
||||
of $object. Line 22 will then result in "bar" being printed.
|
||||
|
||||
This is how the scripting engine has worked until today. Most
|
||||
developers are probably unaware of the fact that they aren't always
|
||||
talking to the same object but often duplicates; others may have
|
||||
realized this can usually be solved by always passing objects by
|
||||
reference (unless a replica is actually desired, which is uncommon).
|
||||
|
||||
The new object model will allow for a much more intuitive
|
||||
implementation of the code. On line 21, the object's handle (ID) is
|
||||
passed to foo() by value. Inside foo(), the object is fetched
|
||||
according to this handle and, therefore, the setMember() method is
|
||||
called on the originally instantiated object and not a copy. Line 22
|
||||
will therefore result in "foo" being printed. This approach gives
|
||||
developers tighter control of when objects are created and duplicated.
|
||||
An additional not-as-important benefit is that the object handle will
|
||||
be passed to foo() by value, which most probably will also save
|
||||
unnecessary duplication of the value containing the ID itself and thus
|
||||
additionally improving run-time performance.
|
||||
|
||||
This was just a simple description of why the new object model solves
|
||||
awkward behavior and makes object handling much easier, intuitive and
|
||||
efficient. The importance of this change goes far beyond what is
|
||||
mentioned in this section as you will see in further sections which
|
||||
describe new features with a majority of them being based on this
|
||||
change.
|
||||
|
||||
Compatibility Notes
|
||||
--------------------
|
||||
|
||||
Many PHP programmers aren't even aware of the copying quirks of the
|
||||
current object model and, therefore, there is a relatively good chance
|
||||
that the amount of PHP applications that will work out of the box or
|
||||
after a very small amount of modifications would be high.
|
||||
|
||||
To simplify migration, version 2.0 will support an optional
|
||||
'auto-clone' feature, which will perform a cloning of the object
|
||||
whenever it would have been copied in version 1.0. Optionally, it
|
||||
will also be possible to request that the engine will emit an E_NOTICE
|
||||
message whenever such an automatic clone occurs, in order to allow
|
||||
developers to gradually migrate to the version 2.0-style behavior
|
||||
(without automatic clones).
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The new object model is not dependent on other features. Many of the
|
||||
other Zend Engine 2.0 features, such as the $foo->bar()->barbara()
|
||||
syntax, destructors and others completely rely on this new object
|
||||
model.
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
Title: Zend 2.0 Namespaces
|
||||
Version: $Id$
|
||||
Status: declined
|
||||
Maintainer: Stig S. Bakken <ssb@php.net>
|
||||
Created: 2001-09-08
|
||||
Modified: 2001-09-08
|
||||
|
||||
|
||||
1. Background/Need
|
||||
==================
|
||||
|
||||
PHP and Zend 1.0 have come to a point where a lot of reusable code is
|
||||
being written; from simple functions and classes to entire application
|
||||
frameworks. It is becoming increasingly difficult to avoid symbol
|
||||
name collisions with the current scoping methods.
|
||||
|
||||
The symbol scopes available in Zend 1.0 are the global scope, the
|
||||
class scope and the function scope. All scopes but classes may
|
||||
contain variables, only the class and global scopes may contain
|
||||
functions, while only the global scope may contain constants and
|
||||
classes. This means that all of Zend 1.0's scoping methods are
|
||||
inherently limited for solving symbol name collision problems.
|
||||
|
||||
|
||||
2. Overview
|
||||
===========
|
||||
|
||||
Namespaces in Zend 2.0 provide a way to manage the symbol collision
|
||||
problem by making it possible to define multiple symbol tables able to
|
||||
contain all types of symbols. Zend will get the notion of a current
|
||||
namespace, defaulting to the current global one. The current name
|
||||
space may be changed on a file-by-file basis. Symbols in other name
|
||||
spaces than the current one may be referenced using a new namespace
|
||||
operator. It will be possible to "import" symbols from one namespace
|
||||
into another.
|
||||
|
||||
|
||||
3. Functionality
|
||||
================
|
||||
|
||||
3.1. Namespace Syntax
|
||||
=====================
|
||||
|
||||
The namespace operator ":" is used to refer to symbols in other
|
||||
namespaces than the current one:
|
||||
|
||||
Class: Namespace:class
|
||||
Function: Namespace:function
|
||||
Static method: Namespace:class::method
|
||||
Variable: $Namespace:variable
|
||||
Constant: Namespace:CONSTANT
|
||||
Class variable: $Namespace:class::variable
|
||||
|
||||
To refer to symbols in the global namespace, symbols are prefixed with
|
||||
only the namespace operator:
|
||||
|
||||
Class: :class
|
||||
Function: :function
|
||||
Static method: :class::method
|
||||
Variable: $:variable
|
||||
Constant: :CONSTANT
|
||||
Class variable: $:class::variable
|
||||
|
||||
Note: $:variable will effectively be just another syntax for
|
||||
$GLOBALS['variable'].
|
||||
|
||||
A namespace may have a name containing a ":", it is always the last
|
||||
":" character in the symbol qualifier that is the actual namespace
|
||||
operator:
|
||||
|
||||
Class: Name:Space:class
|
||||
Function: Name:Space:function
|
||||
Static method: Name:Space:class::method
|
||||
Variable: $Name:Space:variable
|
||||
Constant: Name:Space:CONSTANT
|
||||
Class variable: $Name:Space:class::variable
|
||||
|
||||
(Here, the ":" between "Name" and "Space" is part of the name, it is
|
||||
the one after "Space" that is the namespace operator.)
|
||||
|
||||
|
||||
3.2. Defining Namespaces
|
||||
========================
|
||||
|
||||
Individual files may define a namespace that will apply to the entire
|
||||
file. If no "namespace" operator occurs in the file, it will be in
|
||||
the global namespace:
|
||||
|
||||
1 namespace HTML;
|
||||
2
|
||||
3 class Form {
|
||||
4 function Form() {
|
||||
5 // constructor
|
||||
6 }
|
||||
7 // ...
|
||||
8 }
|
||||
|
||||
Or with the "nested" name syntax:
|
||||
|
||||
1 namespace HTML:Form;
|
||||
2
|
||||
3 class Image {
|
||||
4 var $src;
|
||||
5 function Image($src) {
|
||||
6 $this->src = $src;
|
||||
7 }
|
||||
8 // ...
|
||||
9 }
|
||||
|
||||
Code executed within the "HTML" namespace may refer to the Form class
|
||||
as just "Form". Code executed from within other namespaces has to
|
||||
refer to it as "HTML:Form". The "namespace" statement must occur
|
||||
before any other statements in the file.
|
||||
|
||||
# [ssb 2001-09-08]:
|
||||
# Should it be possible to "add" symbols to a namespace by including a
|
||||
# second file with the same namespace statement?
|
||||
|
||||
|
||||
3.3. Importing Symbols
|
||||
======================
|
||||
|
||||
It is possible to import symbols from another namespace into the
|
||||
current one with the "import" statement:
|
||||
|
||||
import * from HTML; // all symbols
|
||||
|
||||
import Form from HTML; // single symbols
|
||||
|
||||
import Form,Table from HTML; // multiple symbols
|
||||
|
||||
There is a potential for name clashes between symols of different
|
||||
types that have the same qualifier syntax. These are resolved in this
|
||||
order: class, function, constant.
|
||||
|
||||
Optionally, the symbol type may be explicitly given to import (as
|
||||
"class", "function", "variable" or "constant"):
|
||||
|
||||
import class Form from HTML;
|
||||
|
||||
And finally, you may import all symbols of a given type:
|
||||
|
||||
import constant * from HTML:Table;
|
||||
|
||||
The namespace with its symbols must already be defined before using
|
||||
"import".
|
||||
|
||||
|
||||
4. Compatibility Notes
|
||||
======================
|
||||
|
||||
Old code that does not take advantage of namespaces will run without
|
||||
modifications.
|
||||
|
||||
|
||||
5. Dependencies
|
||||
===============
|
||||
|
||||
The class variable syntax depends on this class variables being
|
||||
implemented in the new ZE2 object model.
|
||||
|
||||
|
||||
6. Acknowledgements
|
||||
===================
|
||||
|
||||
Andi Gutmans <andi@zend.com> and Zeev Suraski <zeev@zend.com> for
|
||||
initial ZE2 namespaces proposal
|
||||
|
||||
Dean Hall <php@apt7.com> for the initial symbol qualification syntax
|
||||
@@ -0,0 +1,72 @@
|
||||
Title: Loose type requirements for functions
|
||||
Version: $Id$
|
||||
Status: draft
|
||||
Maintainer: Brian Moon <brianm@dealnews.com>
|
||||
Created: 2001-09-17
|
||||
Modified: 2001-09-17
|
||||
|
||||
|
||||
1. Background/Need
|
||||
==================
|
||||
|
||||
Many internal functions of PHP will reject parameters because of their
|
||||
type (the array and variable function come to mind). For userland
|
||||
this is not an easy task as there is no uniform way to do it. An
|
||||
addition to the engine for requiring loose types would allow
|
||||
developers to know that the data passed to their functions are of the
|
||||
correct type and reduce the need for duplicating the same code in
|
||||
every function to check for the type of data.
|
||||
|
||||
|
||||
2. Overview
|
||||
===========
|
||||
|
||||
Loose typing mostly means evaluating the contents of the variable and
|
||||
not the type of the variable itself. The requirements for this would
|
||||
and should work much like several of the is_* functions do now.
|
||||
|
||||
The typing of parameters would be optional and those not typed would
|
||||
simply continue to be treated as they are now.
|
||||
|
||||
3. Functionality
|
||||
================
|
||||
|
||||
3.1. Allowed Types
|
||||
==================
|
||||
|
||||
Only loose types should be needed to ensure the data is usable by the
|
||||
function. Duplicating the functionallity of is_scalar, is_resource,
|
||||
is_array and is_object should give developers all the information they
|
||||
need to use a variable correctly.
|
||||
|
||||
3.2. Syntax
|
||||
===========
|
||||
|
||||
The current function syntax should be expanded to allow typing of
|
||||
variables inline in a C style.
|
||||
|
||||
function foo ($var){
|
||||
}
|
||||
|
||||
could be changed to require an array such as:
|
||||
|
||||
function foo (array $var){
|
||||
}
|
||||
|
||||
3.3. Errors
|
||||
===========
|
||||
|
||||
Mis-matches in type should be reported as fatal errors and should halt
|
||||
the execution of a script as that function cannot be run and code
|
||||
following could not reliably run.
|
||||
|
||||
|
||||
4. Compatibility Notes
|
||||
======================
|
||||
|
||||
Old code that does not take advantage of this will run without
|
||||
modifications.
|
||||
|
||||
|
||||
|
||||
|
||||
+1166
File diff suppressed because it is too large.
Load diff
-137
@@ -466,140 +466,3 @@ else
|
||||
HAVE_GCC_GLOBAL_REGS=no
|
||||
fi
|
||||
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
|
||||
|
||||
dnl
|
||||
dnl Check if atof() accepts NAN
|
||||
dnl
|
||||
AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[
|
||||
AC_TRY_RUN([
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#else
|
||||
#define zend_isnan(a) 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return zend_isnan(atof("NAN")) ? 0 : 1;
|
||||
}
|
||||
],[
|
||||
ac_cv_atof_accept_nan=yes
|
||||
],[
|
||||
ac_cv_atof_accept_nan=no
|
||||
],[
|
||||
ac_cv_atof_accept_nan=no
|
||||
])])
|
||||
if test "$ac_cv_atof_accept_nan" = "yes"; then
|
||||
AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if atof() accepts INF
|
||||
dnl
|
||||
AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[
|
||||
AC_TRY_RUN([
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_ISINF
|
||||
#define zend_isinf(a) isinf(a)
|
||||
#elif defined(INFINITY)
|
||||
/* Might not work, but is required by ISO C99 */
|
||||
#define zend_isinf(a) (((a)==INFINITY)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
|
||||
#else
|
||||
#define zend_isinf(a) 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1;
|
||||
}
|
||||
],[
|
||||
ac_cv_atof_accept_inf=yes
|
||||
],[
|
||||
ac_cv_atof_accept_inf=no
|
||||
],[
|
||||
ac_cv_atof_accept_inf=no
|
||||
])])
|
||||
if test "$ac_cv_atof_accept_inf" = "yes"; then
|
||||
AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if HUGE_VAL == INF
|
||||
dnl
|
||||
AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[
|
||||
AC_TRY_RUN([
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_ISINF
|
||||
#define zend_isinf(a) isinf(a)
|
||||
#elif defined(INFINITY)
|
||||
/* Might not work, but is required by ISO C99 */
|
||||
#define zend_isinf(a) (((a)==INFINITY)?1:0)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
|
||||
#else
|
||||
#define zend_isinf(a) 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return zend_isinf(HUGE_VAL) ? 0 : 1;
|
||||
}
|
||||
],[
|
||||
ac_cv_huge_val_inf=yes
|
||||
],[
|
||||
ac_cv_huge_val_inf=no
|
||||
],[
|
||||
ac_cv_huge_val_inf=yes
|
||||
])])
|
||||
dnl This is the most probable fallback so we assume yes in case of cross compile.
|
||||
if test "$ac_cv_huge_val_inf" = "yes"; then
|
||||
AC_DEFINE([HAVE_HUGE_VAL_INF], 1, [whether HUGE_VAL == INF])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if HUGE_VAL + -HUGEVAL == NAN
|
||||
dnl
|
||||
AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[
|
||||
AC_TRY_RUN([
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#else
|
||||
#define zend_isnan(a) 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
#if defined(__sparc__) && !(__GNUC__ >= 3)
|
||||
/* prevent bug #27830 */
|
||||
return 1;
|
||||
#else
|
||||
return zend_isnan(HUGE_VAL + -HUGE_VAL) ? 0 : 1;
|
||||
#endif
|
||||
}
|
||||
],[
|
||||
ac_cv_huge_val_nan=yes
|
||||
],[
|
||||
ac_cv_huge_val_nan=no
|
||||
],[
|
||||
ac_cv_huge_val_nan=yes
|
||||
])])
|
||||
dnl This is the most probable fallback so we assume yes in case of cross compile.
|
||||
if test "$ac_cv_huge_val_nan" = "yes"; then
|
||||
AC_DEFINE([HAVE_HUGE_VAL_NAN], 1, [whether HUGE_VAL + -HUGEVAL == NAN])
|
||||
fi
|
||||
+1
-1
@@ -107,7 +107,7 @@ int main(void)
|
||||
], [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, 1, [Define if processor uses big-endian word])
|
||||
AC_DEFINE(WORDS_BIGENDIAN, [], [Define if processor uses big-endian word])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
+7
-7
@@ -345,22 +345,22 @@ function strcat($n) {
|
||||
|
||||
/*****/
|
||||
|
||||
function gethrtime()
|
||||
function getmicrotime()
|
||||
{
|
||||
$hrtime = hrtime();
|
||||
return (($hrtime[0]*1000000000 + $hrtime[1]) / 1000000000);
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return gethrtime();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name)
|
||||
{
|
||||
global $total;
|
||||
$end = gethrtime();
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$total += $end-$start;
|
||||
$num = number_format($end-$start,3);
|
||||
@@ -368,7 +368,7 @@ function end_test($start, $name)
|
||||
|
||||
echo $name.$pad.$num."\n";
|
||||
ob_start();
|
||||
return gethrtime();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
@@ -418,5 +418,5 @@ sieve(30);
|
||||
$t = end_test($t, "sieve(30)");
|
||||
strcat(200000);
|
||||
$t = end_test($t, "strcat(200000)");
|
||||
total();
|
||||
total($t0, "Total");
|
||||
?>
|
||||
+3
-3
@@ -30,14 +30,14 @@ $(LT_TARGETS):
|
||||
$(makefile_in_files): $(makefile_am_files)
|
||||
automake -a -i $(AMFLAGS) $(makefile_files)
|
||||
|
||||
aclocal.m4: configure.ac acinclude.m4
|
||||
aclocal.m4: configure.in acinclude.m4
|
||||
aclocal
|
||||
|
||||
$(config_h_in): configure.ac
|
||||
$(config_h_in): configure.in
|
||||
# explicitly remove target since autoheader does not seem to work
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@rm -f $@
|
||||
autoheader
|
||||
|
||||
configure: aclocal.m4 configure.ac
|
||||
configure: aclocal.m4 configure.in
|
||||
autoconf
|
||||
@@ -24,6 +24,9 @@ AH_TOP([
|
||||
|
||||
#undef uint
|
||||
#undef ulong
|
||||
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
])
|
||||
|
||||
AH_BOTTOM([
|
||||
@@ -59,6 +62,13 @@ 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_DECL_ISNAN 1
|
||||
#define HAVE_DECL_ISINF 1
|
||||
#define HAVE_DECL_ISFINITE 1
|
||||
#endif
|
||||
|
||||
#ifndef zend_isnan
|
||||
#if HAVE_DECL_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
@@ -92,6 +102,12 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
|
||||
#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
|
||||
])
|
||||
|
||||
dnl We want this one before the checks, so the checks can modify CFLAGS.
|
||||
@@ -238,23 +238,23 @@ function empty_loop($n) {
|
||||
}
|
||||
}
|
||||
|
||||
function gethrtime()
|
||||
function getmicrotime()
|
||||
{
|
||||
$hrtime = hrtime();
|
||||
return (($hrtime[0]*1000000000 + $hrtime[1]) / 1000000000);
|
||||
$t = gettimeofday();
|
||||
return ($t['sec'] + $t['usec'] / 1000000);
|
||||
}
|
||||
|
||||
function start_test()
|
||||
{
|
||||
ob_start();
|
||||
return gethrtime();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function end_test($start, $name, $overhead = null)
|
||||
{
|
||||
global $total;
|
||||
global $last_time;
|
||||
$end = gethrtime();
|
||||
$end = getmicrotime();
|
||||
ob_end_clean();
|
||||
$last_time = $end-$start;
|
||||
$total += $last_time;
|
||||
@@ -267,7 +267,7 @@ function end_test($start, $name, $overhead = null)
|
||||
echo $name.$pad.$num." ".$num2."\n";
|
||||
}
|
||||
ob_start();
|
||||
return gethrtime();
|
||||
return getmicrotime();
|
||||
}
|
||||
|
||||
function total()
|
||||
|
||||
@@ -25,8 +25,6 @@ echo "Done\n";
|
||||
Warning: each() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Deprecated: The each() function is deprecated. This message will be suppressed on further calls in %s on line %d
|
||||
|
||||
Warning: Variable passed to each() is not an array or object in %s on line %d
|
||||
NULL
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ Warning: define() expects at least 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
bool(true)
|
||||
|
||||
Warning: define() expects parameter 3 to be bool, array given in %s on line %d
|
||||
Warning: define() expects parameter 3 to be boolean, array given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: define() expects parameter 1 to be string, array given in %s on line %d
|
||||
|
||||
@@ -7,10 +7,6 @@ class foo {
|
||||
function bar () {
|
||||
var_dump(get_class());
|
||||
}
|
||||
function testNull ()
|
||||
{
|
||||
var_dump(get_class(null));
|
||||
}
|
||||
}
|
||||
|
||||
class foo2 extends foo {
|
||||
@@ -31,8 +27,6 @@ var_dump(get_class("qwerty"));
|
||||
var_dump(get_class($f1));
|
||||
var_dump(get_class($f2));
|
||||
|
||||
$f1->testNull();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
@@ -51,7 +45,4 @@ Warning: get_class() expects parameter 1 to be object, string given in %s on lin
|
||||
bool(false)
|
||||
string(3) "foo"
|
||||
string(4) "foo2"
|
||||
|
||||
Warning: get_class() expects parameter 1 to be object, null given in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
+1
-1
@@ -41,7 +41,7 @@ var_dump(get_parent_class(1));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(false)
|
||||
string(3) "foo"
|
||||
|
||||
+4
-4
@@ -37,15 +37,15 @@ NULL
|
||||
Notice: Undefined variable: b in %s on line %d
|
||||
int(1)
|
||||
|
||||
Notice: Trying to get property '1' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
NULL
|
||||
|
||||
Notice: Trying to get property '1' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
NULL
|
||||
|
||||
Notice: Undefined variable: c in %s on line %d
|
||||
|
||||
Notice: Trying to get property '1' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
|
||||
Notice: Trying to get property '' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
NULL
|
||||
+1
-1
@@ -18,7 +18,7 @@ print "ok\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Trying to get property 'a' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
ok
|
||||
|
||||
Warning: Creating default object from empty value in %s on line %d
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ Notice: Undefined variable: arr in %s on line %d
|
||||
|
||||
Notice: Undefined variable: arr in %s on line %d
|
||||
|
||||
Notice: Trying to get property 'foo' of non-object in %s on line %d
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
|
||||
Warning: Creating default object from empty value in %s on line %d
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -8,6 +8,6 @@ abstract class TestClass
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
|
||||
===DONE===
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Allow abstract function override
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class A { abstract function bar($x); }
|
||||
abstract class B extends A { abstract function bar($x); }
|
||||
|
||||
echo "DONE";
|
||||
?>
|
||||
--EXPECT--
|
||||
DONE
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Allow abstract function override
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class A { abstract function bar($x); }
|
||||
abstract class B extends A { abstract function bar($x, $y = 0); }
|
||||
|
||||
echo "DONE";
|
||||
?>
|
||||
--EXPECT--
|
||||
DONE
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Allow abstract function override
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class A { abstract function bar($x, $y = 0); }
|
||||
abstract class B extends A { abstract function bar($x); }
|
||||
|
||||
echo "DONE";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of B::bar($x) must be compatible with A::bar($x, $y = 0) in %s
|
||||
@@ -32,7 +32,7 @@ echo $a->func1(),"\n";
|
||||
echo $a->func2(),"\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
var1 value
|
||||
var2 value
|
||||
in func1
|
||||
|
||||
@@ -15,7 +15,7 @@ call_user_func(array($c, 'none'));
|
||||
call_user_func(array($c, 'prot'));
|
||||
call_user_func(array($c, 'priv'));
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
In __call() for method none()
|
||||
In __call() for method prot()
|
||||
In __call() for method priv()
|
||||
@@ -29,7 +29,7 @@ var_dump($c);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
|
||||
@@ -20,11 +20,11 @@ var_dump($c);
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Object of class stdClass could not be converted to number in %sadd_002.php on line %d
|
||||
Notice: Object of class stdClass could not be converted to int in %sadd_002.php on line %d
|
||||
|
||||
Exception: Unsupported operand types
|
||||
|
||||
Notice: Object of class stdClass could not be converted to number in %s on line %d
|
||||
Notice: Object of class stdClass could not be converted to int in %s on line %d
|
||||
|
||||
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
|
||||
Stack trace:
|
||||
|
||||
@@ -20,11 +20,11 @@ var_dump($c);
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d
|
||||
Notice: Object of class stdClass could not be converted to int in %sadd_003.php on line %d
|
||||
|
||||
Exception: Unsupported operand types
|
||||
|
||||
Notice: Object of class stdClass could not be converted to number in %s on line %d
|
||||
Notice: Object of class stdClass could not be converted to int in %s on line %d
|
||||
|
||||
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
|
||||
Stack trace:
|
||||
|
||||
@@ -16,7 +16,7 @@ var_dump($c);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
float(2834756759.1231)
|
||||
float(2834756759.1231)
|
||||
Done
|
||||
@@ -30,7 +30,7 @@ var_dump($s);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(3) "020"
|
||||
string(4) "pead"
|
||||
string(4) "pead"
|
||||
|
||||
@@ -15,7 +15,7 @@ $a = new class extends A implements B {
|
||||
};
|
||||
|
||||
var_dump($a instanceof A, $a instanceof B);
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
@@ -10,6 +10,6 @@ $foo = function() {
|
||||
$closure = Closure::bind($foo, $class, $class);
|
||||
var_dump($closure());
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
object(class@anonymous)#1 (0) {
|
||||
}
|
||||
@@ -12,5 +12,5 @@ $class = new class() {
|
||||
};
|
||||
var_dump($class->run());
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(10) "Running..."
|
||||
@@ -12,43 +12,24 @@ for ($i = 0; $i < 10; $i++) {
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
--EXPECT--
|
||||
int(0)
|
||||
int(0)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(1)
|
||||
int(1)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(2)
|
||||
int(2)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(3)
|
||||
int(3)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(4)
|
||||
int(4)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(5)
|
||||
int(5)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(6)
|
||||
int(6)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(7)
|
||||
int(7)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(8)
|
||||
int(8)
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
int(9)
|
||||
int(9)
|
||||
@@ -11,9 +11,6 @@ var_dump($arr[$test(1)]);
|
||||
var_dump($arr[$test(0)]() == $arr);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
--EXPECT--
|
||||
int(2)
|
||||
bool(true)
|
||||
@@ -11,6 +11,5 @@ try {
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function create_function() is deprecated in %s on line %d
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -50,7 +50,7 @@ test2($a, $b, $c, $d, ...$array);
|
||||
var_dump($a, $b, $c, $d, $array);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(2)
|
||||
|
||||
@@ -19,6 +19,6 @@ try {
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(36) "Cannot unpack array with string keys"
|
||||
string(42) "Cannot unpack Traversable with string keys"
|
||||
@@ -14,4 +14,4 @@ class Sub extends Base {
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
@@ -19,6 +19,5 @@ class test {
|
||||
new test;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: assert(): Calling assert() with a string argument is deprecated in %s on line %d
|
||||
--EXPECT--
|
||||
int(1)
|
||||
@@ -8,5 +8,5 @@ assert.exception=1
|
||||
assert(true);
|
||||
var_dump(true);
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
@@ -20,7 +20,7 @@ assert(0 && ($a = function () {
|
||||
yield from $x;
|
||||
}));
|
||||
|
||||
assert(0 && ($a = function &(array &$a, ?X $b = null) use ($c,&$d) : ?X {
|
||||
assert(0 && ($a = function &(array &$a, X $b = null) use ($c,&$d) : X {
|
||||
abstract class A extends B implements C, D {
|
||||
const X = 12;
|
||||
const Y = self::X, Z = "aaa";
|
||||
@@ -161,7 +161,7 @@ Warning: assert(): assert(0 && ($a = function () {
|
||||
yield from $x;
|
||||
})) failed in %sexpect_015.php on line %d
|
||||
|
||||
Warning: assert(): assert(0 && ($a = function &(array &$a, ?X $b = null) use($c, &$d): ?X {
|
||||
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null) use($c, &$d): X {
|
||||
abstract class A extends B implements C, D {
|
||||
const X = 12;
|
||||
const Y = self::X, Z = 'aaa';
|
||||
|
||||
@@ -12,7 +12,7 @@ var_dump(\assert(true));
|
||||
var_dump(assert(false));
|
||||
var_dump(assert(true));
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
@@ -15,7 +15,5 @@ test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: assert(): Calling assert() with a string argument is deprecated in %s on line %d
|
||||
|
||||
Notice: Object of class stdClass could not be converted to number in %s on line %d
|
||||
Notice: Object of class stdClass could not be converted to int in %s on line %d
|
||||
int(2)
|
||||
@@ -49,8 +49,8 @@ NULL
|
||||
Warning: Cannot use a scalar value as an array in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Attempt to assign property 'foo' of non-object in %s on line %d
|
||||
Warning: Attempt to assign property of non-object in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Attempt to assign property 'foo' of non-object in %s on line %d
|
||||
Warning: Attempt to assign property of non-object in %s on line %d
|
||||
NULL
|
||||
@@ -1,25 +0,0 @@
|
||||
--TEST--
|
||||
If the LHS of ref-assign ERRORs, that takes precendence over the "only variables" notice
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function val() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
$str = "foo";
|
||||
$var = 24;
|
||||
var_dump($str->foo =& $var);
|
||||
var_dump($str);
|
||||
var_dump($str->foo =& val());
|
||||
var_dump($str);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Attempt to modify property 'foo' of non-object in %s on line %d
|
||||
NULL
|
||||
string(3) "foo"
|
||||
|
||||
Warning: Attempt to modify property 'foo' of non-object in %s on line %d
|
||||
NULL
|
||||
string(3) "foo"
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Cannot assign by reference to overloaded object, even if __get() returns by-ref
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
private $x;
|
||||
public function &__get($name) {
|
||||
return $this->x;
|
||||
}
|
||||
}
|
||||
|
||||
$test = new Test;
|
||||
$y = 5;
|
||||
$test->x =& $y;
|
||||
var_dump($test->x);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -12,7 +12,7 @@ var_dump($var1);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
int(2)
|
||||
int(2)
|
||||
Done
|
||||
@@ -12,7 +12,7 @@ var_dump($var1);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(1) "g"
|
||||
string(1) "g"
|
||||
Done
|
||||
@@ -12,7 +12,7 @@ var_dump($var1);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
NULL
|
||||
NULL
|
||||
Done
|
||||
@@ -15,7 +15,7 @@ var_dump($var2);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(5) "space"
|
||||
string(5) "space"
|
||||
string(5) "space"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #19859 (__call() does not catch call_user_func_array() calls)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class test
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #20240 (order of destructor calls)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -2,6 +2,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');
|
||||
?>
|
||||
--FILE--
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
--TEST--
|
||||
Bug #21888 (protected property and protected method of the same name)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class mom {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #22725 (A derived class can call a parent's protected method that calls a private method)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #22836 (returning references to NULL)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function &f()
|
||||
@@ -13,7 +15,7 @@ for ($i = 0; $i < 8; $i++) {
|
||||
$h =& f();
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
string(3) "foo"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
Bug #24436 (isset()/empty() produce errors with non-existent variables in classes)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--INI--
|
||||
error_reporting=2047
|
||||
--FILE--
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--TEST--
|
||||
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--
|
||||
<?php
|
||||
class SiteClass {
|
||||
|
||||
Loaded 100 of 7973 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user