Compare commits

..
Author SHA1 Message Date
Derick Rethans 0ee491bfbe Update versions for PHP 7.4.15RC1 2021-01-19 14:44:32 +00:00
Derick Rethans e8a89c49db Update NEWS for PHP 7.4.15RC1 2021-01-19 14:44:32 +00:00
sj-i 5d31ee302d Fixed bug #42560
Check open_basedir after the fallback to the system's temporary
directory in tempnam().

In order to preserve the current behavior of upload_tmp_dir
(do not check explicitly specified dir, but check fallback),
new flags are added to check open_basedir for explicit dir
and for fallback.

Closes GH-6526.
2021-01-19 11:41:58 +01:00
Christoph M. BeckerandAnna Filina 68f5289e9e Fix #69279: Compressed ZIP Phar extractTo() creates garbage files
When extracting compressed files from an uncompressed Phar, we must not
use the direct file pointer, but rather get an uncompressed file
pointer.

We also add a test to show that deflated and stored entries are
properly extracted.

This also fixes #79912, which appears to be a duplicate of #69279.

Co-authored-by: Anna Filina <afilina@gmail.com>

Closes GH-6599.
2021-01-19 10:28:54 +01:00
Christoph M. Becker 38ad37ad43 Fix #80595: Resetting POSTFIELDS to empty array breaks request
This is mainly to work around https://github.com/curl/curl/issues/6455,
but not building the mime structure for empty hashtables is a general
performance optimization, so we do not restrict it to affected cURL
versions (7.56.0 to 7.75.0).

The minor change to bug79033.phpt is unexpected, but should not matter
in practice.

Closes GH-6606.
2021-01-18 10:57:56 +01:00
Christoph M. Becker 25103c37aa Revert "Fix #76813: Access violation near NULL on source operand"
This reverts commit 5e15c9c41f, since
re2c default rules are only available as of re2c 0.13.7.
2021-01-11 13:21:12 +01:00
Christoph M. Becker 9450893dc6 Avoid modifying the return value of readline_completion_function()
The internal function `_readline_command_generator()` modifies the
internal array pointer of `readline_completion_function()`'s return
value.  We therefore separate the array, what also avoids failing
assertions regarding the array refcount.

Closes GH-6582.
2021-01-07 13:46:09 +01:00
Christoph M. Becker d1b1c04398 Fix #77565: Incorrect locator detection in ZIP-based phars
We must not assume that the first end of central dir signature in a ZIP
archive actually designates the end of central directory record, since
the data in the archive may contain arbitrary byte patterns.  Thus, we
better search from the end of the data, what is also slightly more
efficient.

There is, however, no way to detect the end of central directory
signature by searching from the end of the ZIP archive with absolute
certainty, since the signature could be part of the trailing comment.
To mitigate, we check that the comment length fits to the found
position, but that might still not be the correct position in rare
cases.

Closes GH-6507.
2021-01-05 23:40:24 +01:00
Christoph M. Becker 5c963731e2 Fix memory leak in Phar::webPhar() on Windows
Closes GH-6574.
2021-01-05 14:21:35 +01:00
Dylan K. Taylor 6b631f073d gdbinit: use ____print_str to print htable keys
I noticed this problem while dumping the contents of EG(function_table),
where keys for closures start with a null byte. printf interprets this
as a zero-length string and emits nothing. This allows the key to be
rendered properly in readable form.

Closes GH-6577.
2021-01-05 10:11:56 +01:00
Nikita Popov 46d6daea7a Disable non-cron travis jobs
This was already done for PHP-8.0 and master, do it for PHP-7.4
as well.
2021-01-04 10:52:37 +01:00
Stanislav Malyshev e65932060a [ci skip] Update NEWS 2021-01-04 01:46:32 -08:00
Stanislav Malyshev ec589a27da Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  [ci skip] Fix order
2021-01-04 01:46:11 -08:00
Stanislav Malyshev 65d7ade684 [ci skip] Fix order 2021-01-04 01:45:15 -08:00
Stanislav Malyshev 2498385dd9 Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  [ci skip] Unpdate NEWS
2021-01-04 01:44:18 -08:00
Stanislav Malyshev 8967e66559 [ci skip] Unpdate NEWS 2021-01-04 01:43:45 -08:00
Stanislav Malyshev 434c2b1bdb Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix #77423: parse_url() will deliver a wrong host to user
2021-01-01 21:29:08 -08:00
Stanislav Malyshev 128fca4037 Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2:
  Fix #77423: parse_url() will deliver a wrong host to user
2021-01-01 21:06:07 -08:00
Christoph M. Becker 2d3d72412a Fix #77423: parse_url() will deliver a wrong host to user
To avoid that `parse_url()` returns an erroneous host, which would be
valid for `FILTER_VALIDATE_URL`, we make sure that only userinfo which
is valid according to RFC 3986 is treated as such.

For consistency with the existing url parsing code, we use ctype
functions, although that is not necessarily correct.
2021-01-01 20:08:01 -08:00
haszi 0db6f5267c Replace sort() function calls with ksort() in basic ksort test
Closes GH-6541.
2020-12-27 18:30:58 +01:00
Adam SeitzandChristoph M. Becker 70dfbe0068 Fix #80384: limit read buffer size
In the case of a stream with no filters, php_stream_fill_read_buffer
only reads stream->chunk_size into the read buffer. If the stream has
filters attached, it could unnecessarily buffer a large amount of data.

With this change, php_stream_fill_read_buffer only proceeds until either
the requested size or stream->chunk_size is available in the read buffer.

Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>

Closes GH-6444.
2020-12-23 13:49:56 +01:00
Derick Rethans b043759cb4 Fixed bug #80376 (last day of the month causes runway cpu usage) 2020-12-21 10:30:40 +00:00
Nikita Popov bc166844e3 MySQLnd: Support cursors in store/get result
This fixes two related issues:

1. When a PS with cursor is used in store_result/get_result,
   perform a COM_FETCH with maximum number of rows rather than
   silently switching to an unbuffered result set (in the case of
   store_result) or erroring (in the case of get_result).
   In the future, we might want to make get_result unbuffered for
   PS with cursors, as using cursors with buffered result sets
   doesn't really make sense. Unlike store_result, get_result
   isn't very explicit about what kind of result set is desired.
2. If the client did not request a cursor, but the server reports
   that a cursor exists, ignore this and treat the PS as if it
   has no cursor (i.e. to not use COM_FETCH). It appears to be a
   server side bug that a cursor used inside an SP will be reported
   to the client, even though the client cannot use the cursor.

Fixes bug #64638, bug #72862, bug #77935.

Closes GH-6518.
2020-12-18 10:19:13 +01:00
Nikita Popov 315f3f8dc9 Fixed bug #67983
We need to check the BIT case first, otherwise it will get skipped
in INT_AND_FLOAT_NATIVE mode.
2020-12-16 10:52:27 +01:00
Nikita Popov 118ff03335 Fix bug #80523
Don't truncate the file length to unsigned int...

I have no idea whether that fully fixes the problem because the
process gets OOM killed before finishing, but at least the
immediate parse error is gone now.
2020-12-16 10:20:20 +01:00
Derick Rethans 078cdd8f76 Prepare for 7.4.15 2020-12-15 14:13:29 +00:00
Christoph M. Becker a53d67ceac Fix #77322: PharData::addEmptyDir('/') Possible integer overflow
`phar_path_check()` already strips a leading slash, so we must not
attempt to strip the trailing slash from an now empty directory name.

Closes GH-6508.
2020-12-15 11:44:53 +01:00
Christoph M. Becker c0a1c2c5ee Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  7.3.27 is next
2020-12-15 11:30:46 +01:00
Christoph M. Becker 40d9e3ab86 7.3.27 is next 2020-12-15 11:28:01 +01:00
Calvin Buckley 54248b18fe IBM i PASE doesn't support ITIMER_PROF
Like Cygwin, this platform needs to use a real-time timer.

This was based on a patch by @kadler, but it didn't handle unsetting
the timer, so the timeout would continue to be active, triggering
`hard_timeout` unexpectedly. The patch is fixed to handle unsetting.

Closes GH-6503.
2020-12-15 10:15:28 +01:00
Christoph M. Becker 10c9d615de Drop pdo_mysql_prepare_load_data.phpt
Like the test title and some comments in this test describe, this test
was supposed to have `::prepare()` failing because `LOAD DATA INFILE`
would not be supported as prepared statement, and then the test checks
whether follow-up queries would succeed.  However, `LOAD DATA INFILE`
is supported for prepared statements at least on Windows with mysqlnd,
so the test does no longer test what it is supposed to do.  Therefore,
we drop it.

Closes GH-6509.
2020-12-14 18:26:12 +01:00
Jakub Zelenka a221e17b41 Fix bug #69625: FPM returns 200 status on request without SCRIPT_FILENAME 2020-12-13 18:39:48 +00:00
Nikita Popov e450621f5e Fixed bug #76815
When we receive an error while reading a result set, we should
assume that no more result sets are available. libmysqlclient
implements the same behavior.
2020-12-10 11:23:41 +01:00
Nikita Popov 4922049213 Fixed bug #71145
Consume any additional result sets when running INIT_COMMAND.
2020-12-10 10:28:10 +01:00
Nikita Popov f3d5877845 Backport fix for bug #70066
Given the number of duplicates this bug report had, it seems
worthwhile to fix this on PHP-7.4 as well.

Cherry-pick of 106e7e4bca.
2020-12-10 09:58:47 +01:00
Nikita Popov 44b234a9bc Fixed bug #78154
Handle errors during next_result in exec.
2020-12-09 12:46:47 +01:00
Christoph M. Becker 20e75329f2 Fix #48725: Support for flushing in zlib stream
When `php_zlib_deflate_filter()` is called with `PSFS_FLAG_FLUSH_INC`
but without new buckets being available (e.g. because a user calls
`rewind()` after writing to the stream), we have to make sure that any
pending data are flushed.  This could basically be done like in the
attached patch[1], but that could cause unnessary flushes, which can be
harmful for compression, and adds unnecessary flush markers to the
stream.  Thus, we use the `php_zlib_filter_data.finished` field, which
has not been used for `zlib.deflate` filters, and properly keep track
of the need to flush.

[1] <https://bugs.php.net/patch-display.php?bug_id=48725&patch=zlib-filter-flush-fix.patch&revision=latest>

Closes GH-6019.
2020-12-08 12:23:24 +01:00
Christoph M. Becker 65f5573bc8 Fix #77069: stream filter loses final block of data
Reading from a stream may return greater than zero, but nonetheless the
stream's EOF flag may have been set.  We have to cater to this
condition by setting the close flag for filters.

We also have to cater to that change in the zlib.inflate filter:

If `inflate()` is called with flush mode `Z_FINISH`, but the output
buffer is not large enough to inflate all available data, it fails with
`Z_BUF_ERROR`.  However, `Z_BUF_ERROR` is not fatal; in fact, the zlib
manual states: "If deflate returns with Z_OK or Z_BUF_ERROR, this
function must be called again with Z_FINISH and more output space
(updated avail_out) but no more input data, until it returns with
Z_STREAM_END or an error."  Hence, we do so.

Closes GH-6001.
2020-12-08 11:47:49 +01:00
Nikita Popov bd093ad861 Fixed bug #63185 2020-12-08 11:30:54 +01:00
Dharman a83cc03c13 Fixed bug #80458
If there is no result set (e.g. for upsert queries), still allow
fetching to occur without error, i.e. treat it the same way as
an empty result set.

This normalizes behavior between native and emulated prepared
statements and addresses a regression in PHP 7.4.13.
2020-12-04 16:59:47 +01:00
Christoph M. Becker 8588ae7215 Fix #75102: PharData says invalid checksum for valid tar
Apparently, there are broken tarballs out there which are actually in
ustar format, but did not write the `ustar` marker.  Since popular tar
tools like GNU tar and 7zip have no issues dealing with such tarballs,
Phar should also be more resilient.

Thus, when the first checksum check of a tarball in (presumed) in old-
style format fails, we check whether the checksum would be suitable for
ustar format; if so, we treat the tarball as being in ustar format.

Closes GH-6479.
2020-12-04 13:02:29 +01:00
Paul Crovella 8f8e6f95af Upload coverage data to codecov.io
Closes GH-6486.
2020-12-03 12:04:50 +01:00
Nikita Popov 0f6c41c6f8 Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix mysqli_expire_password test for mariadb
2020-12-03 11:01:57 +01:00
Daniel Black 0697a64f7e Fix mysqli_expire_password test for mariadb
In MariaDB-10.4.3 EXPIRE passwords where supported for
MariaDB. This only behaves like MySQL when the system
variable disconnect_on_expired_passwords=1.

MariaDB if there was no password it could not be considered
expired. So the test is adjusted to use actual passwords.
(MariaDB commit a94b20a8e0d9e64eeaabdaaa7a3e03fcdb8a686e)

The error codes produced my MariaDB are different
however still conforming to the SQL specification.

Closes GH-6480.
2020-12-03 10:56:00 +01:00
Daniel Black 5d5c1cea5f fix mysqli_stmt_get_result_metadata_fetch_field test for mariadb
MariaDB extended the default decimal field to 39 characters
instead of MySQL's 31 characters.

This small change allows the test to pass on MySQL and MariaDB.

Closes GH-6484.
2020-12-03 10:45:11 +01:00
Peter Kokot d386ed1e6b Backport fix for bug #78750
Cherry-picks
fe2afef36f
and
86e2b7bb70.
2020-12-03 10:07:09 +01:00
Nikita Popov f2833ca1be Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fixed bug #80457
2020-12-02 11:29:06 +01:00
Nikita Popov d6fcaf5da4 Fixed bug #80457
On x32 sizeof(size_t) != sizeof(zend_long), so we need to be
careful with sign extension here.

Patch by bruno dot premont at restena dot lu.
2020-12-02 11:26:10 +01:00
Christoph M. Becker c283f53b24 Fix #73809: Phar Zip parse crash - mmap fail
Phar signatures practically are of limited size; for the MD5 and SHA
hashes the size is fixed (at most 64 bytes for SHA512); for OpenSSL
public keys there is no size limit in theory, but "64 KiB ought to be
good enough for anybody".  So we check for that limit, to avoid fatal
errors due to out of memory conditions.

Since it is neither possible to have the signature compressed in the
ZIP archive, nor is it possible to manually add a signature via Phar,
we use ZipArchive to create a suitable archive for the test on the fly.

Closes GH-6474.
2020-12-01 16:58:19 +01:00
Nikita Popov ecee3f1209 Next attempt to fix bug #80368
Apparently treating LibreSSL as OpenSSL 1.1 is not just something
we did in our code, it's something that upstream LibreSSL claims,
despite not actually being compatible. Duh.

Check for EVP_CIPH_OCB_MODE instead, which should reliably
determine support...
2020-11-30 15:15:59 +01:00
Christoph M. Becker 5e15c9c41f Fix #76813: Access violation near NULL on source operand
We avoid `YYCURSOR` becoming `NULL` by initializing `YYMARKER`, and add
a default rule for `<NORMAL>` where we catch unexpected input.

We also fix the only superficially related issue regarding empty input
followed by `T_SEPARATOR` and command, which caused another segfault.

Closes GH-6464.
2020-11-30 12:29:24 +01:00
Jakub Zelenka b855907f54 Merge branch 'PHP-7.3' into PHP-7.4 2020-11-27 16:33:47 +00:00
Jakub Zelenka 685708160e Fix test for bug62890 to not depend on system cert store 2020-11-27 16:32:43 +00:00
Nikita Popov 3430d856ac Fix build for non-x86 2020-11-27 17:04:17 +01:00
Nikita Popov 4e30ab33d8 Fix AVX detection
Our CPU detection code currently only checks whether hardware
support for AVX exists. However, we also need to check for operating
system support for XSAVE, as well as whether XCR0 has the SSE and
AVX bits set.

If this is not the case, unset the AVX and AVX2 bits in the cpuinfo
structure.

Hopefully this resolves our issues with CPU support detection.

Closes GH-6460.
2020-11-27 14:49:31 +01:00
Christoph M. Becker 07c5efbd76 Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix mysqli_get_client_stats test
2020-11-27 11:50:59 +01:00
Daniel Black 4a10037cb4 Fix mysqli_get_client_stats test
MySQL removed RENAME DATABASE in 18300001c1dbbfddf9a0adcbaeea68956102bdd0
(Sept 2007, 5.1.23). As this briefest existance is very insignificant lets remove it.

It also breaks when testing against MariaDB.

As the alternate path in this test covers all supported MySQL and MariaDB
versions and a signifant portion of unsupported versions lets keep it simple.

Closes GH-6459.
2020-11-27 11:43:34 +01:00
Nikita Popov 0f579fd7c8 Fixed bug #80368
We assume that usually LibreSSL supports everything OpenSSL 1.1 does.
In this instance, this is not the case.
2020-11-27 10:57:19 +01:00
Nikita Popov 5240f8391f Fixed bug #80425
Rename the methods in MessageFormatAdapter to make sure they don't
clash with anything defined by icu itself, which may be a problem
if icu is linked statically.
2020-11-27 10:02:00 +01:00
Nikita Popov ea372e7463 Fix bug #80402: Don't strip -lpthread
The current behavior has been introduced 20 years ago in
f9e375f493 as part of a larger change.
It's not clear to me why special treatement of -lpthread is necessary
here.
2020-11-26 11:54:20 +01:00
Nikita Popov 2fb12be84c Fixed bug #80411
References to null-serializations are stored as null, and as such
are part of the reference count.

Reminds me that we really need to deprecate the mess that is
Serializable.
2020-11-25 17:23:42 +01:00
Dharman 233f507fe6 Fixed error reporting in mysqli_stmt::__construct
For the sake of simplicity, I've synchronized the implementation
with PHP 8, which means null values are also accepted.

Closes GH-6454.
2020-11-25 16:27:41 +01:00
Nikita Popov e3e67b721f Reindent more mysqli tests
Due to a bug in the tidy script, most tests did not actually get
reindented...
2020-11-25 16:07:16 +01:00
Nikita Popov 97d192b444 Reindent ext/mysqli tests
Reindent ext/mysqli tests on PHP-7.4, so they match with the
indentation on PHP-8.0. Otherwise merging test changes across
branches is very unpleasant.
2020-11-25 15:57:11 +01:00
Nikita Popov 706241f82d Fix usage of casted string in ReflectionParameter ctor
Fixes oss-fuzz #27755.
2020-11-24 16:42:16 +01:00
Nikita Popov d016434ad3 Fixed bug #80393
Handle macos versions that don't start with 10.* in libtool.

Patch by kir dot morozov at gmail dot com.
2020-11-24 15:26:40 +01:00
Christoph M. Becker 39f95f5614 Fix #77961: finfo_open crafted magic parsing SIGABRT
libmagic may abort the running process, which is not desirable for PHP;
we raise a fatal error instead.

Closes GH-6437.
2020-11-24 14:01:15 +01:00
Christoph M. Becker 5f9c82d514 Fix #80366: Return Value of zend_fstat() not Checked
In the somewhat unlikely case that `zend_fstat()` fails, we must not
proceed executing the function, but return `false` instead.

Patch based on the patch contributed by sagpant at microsoft dot com.

Closes GH-6432.
2020-11-24 13:09:16 +01:00
Nikita Popov fa713ec17b Fixed bug #80362: Running dtrace scripts can cause php to crash
Patch by al at coralnet dot name.
2020-11-24 13:01:51 +01:00
Christoph M. Becker 221345a013 Fix #77594: ob_tidyhandler is never reset
We reset to original INI value on request shutdown.

Closes GH-6425.
2020-11-22 14:02:29 +01:00
Benjamin Morel ed949a1973 Fix typos in php.ini files
Closes GH-6441.

[ci skip]
2020-11-20 16:50:29 +01:00
Christoph M. Becker 881e43a03c Fix #72964: White space not unfolded for CC/Bcc headers
`\r\n` does only terminate a header, if not followed by `\t` or ` `.
We have to cater to that when determining the end position of the
respective headers.

Closes GH-6420.
2020-11-19 19:25:03 +01:00
Christoph M. Becker c2b1182879 Fix #80345: PHPIZE configuration has outdated PHP_RELEASE_VERSION
We must not redefine the version "constants" for phpize builds, because
these have already generated in phpize.js, from where we pass these
variables forward to configure.js.

We also add `PHP_EXTRA_VERSION` and `PHP_VERSION_STRING` to the files
for completeness.

Closes GH-6419.
2020-11-19 16:23:20 +01:00
Nikita Popov 99a8ec6e24 Short-circuit get_gc for currently running generator 2020-11-18 12:45:29 +01:00
Darek Slusarczyk 79a606bd95 Fix #80312: change default engine from MyISAM to InnoDB in tests
Change mysqli and pdo_mysql tests configuration to use by default
InnoDB instead of MyISAM.

Closes GH-6405.
2020-11-17 13:15:15 +01:00
Nikita Popov df7417d127 Fix incorrectly optimized out live range
For x ? y : z style structures, the live range starts at z, but
may also hold the value of y. Make sure that the refcounting check
takes this into account, by checking the type of a potential phi
user.
2020-11-17 10:19:57 +01:00
Christoph M. Becker 78773890f6 Fix #74558: Can't rebind closure returned by Closure::fromCallable()
Failure to rebind such closures is not necessarily related to them
being created by `ReflectionFunctionAbstract::getClosure()`, so we fix
the error message.

Closes GH-6424.
2020-11-16 14:31:06 +01:00
Nikita Popov eda7492604 Handle errors during next_result() 2020-11-11 16:02:52 +01:00
Derick Rethans c1f8dd4a33 PHP-7.4 is now for 7.4.14 2020-11-10 17:58:21 +00:00
13784 changed files with 432199 additions and 511397 deletions

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
version: "{branch}.build.{build}"
image: Visual Studio 2019
image: Visual Studio 2017
branches:
except:
@@ -24,7 +24,7 @@ environment:
PHP_BUILD_OBJ_DIR: c:\obj
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0
PHP_BUILD_CRT: vs16
PHP_BUILD_CRT: vc15
# ext and env setup for tests
#MYSQL_TEST_PASSWD: Password12!
#MYSQL_TEST_USER: root
+17 -4
View File
@@ -252,13 +252,16 @@ define ____printzv_contents
____printzv &$zvalue->value.ref->val $arg1
end
if $type == 11
printf "CONSTANT_AST"
printf "const: %s", $zvalue->value.str->val
end
if $type == 12
printf "CONSTANT_AST"
end
if $type == 13
printf "indirect: "
____printzv $zvalue->value.zv $arg1
end
if $type == 13
if $type == 14
printf "pointer: %p", $zvalue->value.ptr
end
if $type == 15
@@ -268,9 +271,18 @@ define ____printzv_contents
printf "_BOOL"
end
if $type == 17
printf "CALLABLE"
end
if $type == 18
printf "ITERABLE"
end
if $type == 19
printf "VOID"
end
if $type == 20
printf "_NUMBER"
end
if $type > 17
if $type > 20
printf "unknown type %d", $type
end
printf "\n"
@@ -340,7 +352,8 @@ define ____print_ht
end
printf "[%d] ", $i
if $p->key
printf "%s => ", $p->key->val
____print_str $p->key->val $p->key->len
printf " => "
else
printf "%d => ", $p->h
end
+14 -16
View File
@@ -80,15 +80,22 @@ include/
libs/
modules/
# Used by build/gen_stub.php
build/PHP-Parser-*
# ------------------------------------------------------------------------------
# Configuration headers generated by the PHP build system
# ------------------------------------------------------------------------------
config.h
config.h.in
/ext/date/lib/timelib_config.h
/ext/iconv/php_have_bsd_iconv.h
/ext/iconv/php_have_glibc_iconv.h
/ext/iconv/php_have_ibm_iconv.h
/ext/iconv/php_have_iconv.h
/ext/iconv/php_have_libiconv.h
/ext/iconv/php_iconv_aliased_libiconv.h
/ext/iconv/php_iconv_broken_ignore.h
/ext/iconv/php_iconv_supports_errno.h
/ext/iconv/php_php_iconv_h_path.h
/ext/iconv/php_php_iconv_impl.h
/main/build-defs.h
/main/php_config.h.in
/main/php_config.h
@@ -109,7 +116,7 @@ config.h.in
# ------------------------------------------------------------------------------
# SAPIs specific ignores
# ------------------------------------------------------------------------------
/sapi/apache2handler/libphp.module
/sapi/apache2handler/libphp7.module
/sapi/fpm/fpm/php-cgi
/sapi/fpm/init.d.php-fpm
/sapi/fpm/php-fpm.conf
@@ -161,14 +168,8 @@ php
/Zend/zend_language_parser.output
# ------------------------------------------------------------------------------
# Extensions files
# Extensions files additionally generated by `cd ext/name && phpize && ./configure`
# ------------------------------------------------------------------------------
# Miscellaneous extensions files
/ext/opcache/jit/zend_jit_x86.c
/ext/opcache/minilua
# Generated by `cd ext/name && phpize && ./configure`
/ext/*/build/
/ext/*/configure.ac
/ext/*/run-tests.php
@@ -181,7 +182,7 @@ php
/configure.bat
/configure.js
# Generated by `/configure.(bat|js)` (architecture dependent)
# Generated by `/configure.(bat|js)` (architecture dependend)
/config.nice.bat
# NTS debug build x86
@@ -199,7 +200,7 @@ php
# Generated by x64 compiler, includes Debug, Debug_TS, Release, Release_TS
/x64/
# Miscellaneous files generated by Windows build system
# Miscellaneous files generated by Windows build sytem
/main/config.w32.h
/win32/build/deplister.exe
/win32/build/deplister.obj
@@ -237,9 +238,6 @@ php
# Test results generated by `./run-tests.php`
php_test_results_*.txt
# Temporary test information generated by `./run-tests.php`
/run-test-info.php
# Temporary POST data placeholder files generated by `./run-tests.php`
phpt.*
+9 -10
View File
@@ -1,9 +1,9 @@
git:
quiet: true
dist: bionic
dist: xenial
language: c
os: linux
sudo: required
addons:
apt:
packages:
@@ -68,15 +68,14 @@ env:
jobs:
include:
- env: ENABLE_ZTS=0 ENABLE_DEBUG=0
- env: ENABLE_MAINTAINER_ZTS=0 ENABLE_DEBUG=0
arch: amd64
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1
arch: amd64
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 ARM64=1
arch: arm64
if: type = cron
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 S390X=1
arch: s390x
- env: ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1
arch: amd64
if: type = cron
- env: ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 ARM64=1
arch: arm64
if: type = cron
before_script:
@@ -95,7 +94,7 @@ before_script:
script:
# ARM64 CI reports nproc=32, which is excessive.
- if [ -z "$ARM64" ]; then export JOBS=$(nproc); else export JOBS=16; fi
- ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120 -j$JOBS
- ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d opcache.protect_memory=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 -j$JOBS
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
after_success:
+30 -8
View File
@@ -272,16 +272,16 @@ use these rules.
1. Extensions should be well tested using `*.phpt` tests. Read about that at
[qa.php.net](https://qa.php.net/write-test.php) documentation.
## Folding hooks
## Documentation and folding hooks
Use `{{{` symbols for the folding mode in Emacs and vim (`set fdm=marker`).
Folding is very useful when dealing with large files because you can scroll
through the file quickly and just unfold the function you wish to work on.
The `}}}` at the end of each function marks the end of the fold, and should
be on a separate line.
In order to make sure that the online documentation stays in line with the code,
each user-level function should have its user-level function prototype before it
along with a brief one-line description of what the function does. It would look
like this:
```c
/* {{{ Returns the absolute value of the number */
/* {{{ proto int abs(int number)
Returns the absolute value of the number */
PHP_FUNCTION(abs)
{
...
@@ -289,6 +289,27 @@ PHP_FUNCTION(abs)
/* }}} */
```
The `{{{` symbols are the default folding symbols for the folding mode in Emacs
and vim (`set fdm=marker`). Folding is very useful when dealing with large files
because you can scroll through the file quickly and just unfold the function you
wish to work on. The `}}}` at the end of each function marks the end of the
fold, and should be on a separate line.
The `proto` keyword there is just a helper for the `doc/genfuncsummary` script
which generates a full function summary. Having this keyword in front of the
function prototypes allows us to put folds elsewhere in the code without
messing up the function summary.
Optional arguments are written like this:
```c
/* {{{ proto object imap_header(int stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
Returns a header object with the defined parameters */
```
And yes, please keep the prototype on a single line, even if that line is
massive.
## New and experimental functions
To reduce the problems normally associated with the first public implementation
@@ -313,7 +334,8 @@ purposes, these will only be documented by the most current name, with the
aliases listed in the documentation for the parent function. For ease of
reference, user-functions with completely different names, that alias to the
same function (such as `highlight_file` and `show_source`), will be separately
documented.
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
+9 -4
View File
@@ -197,6 +197,9 @@ locations.
└─ tokenizer/
├─ tokenizer_data.c # Generated by `ext/tokenizer/tokenizer_data_gen.sh`
└─ ...
└─ xmlrpc/
├─ libxmlrpc/ # Forked and maintained in php-src
└─ ...
└─ zend_test # For testing internal APIs. Not needed for regular builds.
└─ ...
└─ zip/ # Bundled https://github.com/pierrejoye/php_zip
@@ -259,8 +262,8 @@ included.
- Run `make test` to check your change doesn't break other features.
- Rebuild PHP with `--enable-debug` which will show some kinds of memory errors
and check the PHP and web server error logs after running your PHP tests.
- Rebuild PHP with `--enable-zts` to check your change compiles and operates
correctly in a thread safe PHP.
- Rebuild PHP with `--enable-maintainer-zts` to check your change compiles on
multi-threaded web servers.
- Review the change once more just before submitting it.
## What happens after submitting contribution?
@@ -320,8 +323,8 @@ Having said that, here are the organizational rules:
`make test`.
7. For development use the `--enable-debug` switch to avoid memory leaks and the
`--enable-zts` switch to ensure your code handles TSRM correctly and doesn't
break for those who need that.
`--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:
@@ -406,6 +409,8 @@ New source code files should include the following header block:
```c
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
+21 -21
View File
@@ -37,7 +37,7 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: cli
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>, Edin Kadribasic <edink@php.net>
MAINTENANCE: Xinchen Hui <laruence@php.net> (2013 - 2020)
MAINTENANCE: Unknown
STATUS: Working
SINCE: 4.3.0
-------------------------------------------------------------------------------
@@ -60,7 +60,7 @@ SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: phpdbg
PRIMARY MAINTAINER: Joe Watkins <krakjoe@php.net>, Bob Weinand <bwoebi@php.net>
MAINTENANCE: Unknown
MAINTENANCE: Unkown
STATUS: 5.6
-------------------------------------------------------------------------------
@@ -166,7 +166,7 @@ COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less hav
-------------------------------------------------------------------------------
EXTENSION: sqlite3
PRIMARY MAINTAINER: Scott MacVicar <scottmac@php.net> (2008 - 2011)
Christoph M. Becker <cmb@php.net> (2016 - 2020)
Christoph M. Becker <cmb@php.net> (2016 - 2018)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
@@ -214,6 +214,11 @@ PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2004 - 2010)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xmlrpc
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Orphaned
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: xmlwriter
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2004 - 2010)
Pierre-Alain Joye <pajoye@php.net> (2005-2009)
@@ -250,7 +255,6 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: com_dotnet
PRIMARY MAINTAINER: Wez Furlong <wez@php.net> (2003 - 2005)
Christoph M. Becker <cmb@php.net> (2018 - 2020)
MAINTENANCE: Maintained
STATUS: Windows
SINCE: 5.0
@@ -293,7 +297,7 @@ SINCE: 7.4.0
-------------------------------------------------------------------------------
EXTENSION: fileinfo
PRIMARY MAINTAINER: Derick Rethans <derick@php.net> (2004 - 2008)
Anatol Belski <ab@php.net> (2012 - 2020)
Anatol Belski <ab@php.net> (2012 - 2019)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
@@ -313,7 +317,7 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gd
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2002 - 2016)
Christoph M. Becker <cmb@php.net> (2015 - 2020)
Christoph M. Becker <cmb@php.net> (2015 - 2018)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -323,9 +327,9 @@ MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gmp
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2000 - 2019)
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2000 - 2018)
Antony Dovgal <tony2001@php.net> (2005 - 2010)
Nikita Popov <nikic@php.net> (2013 - 2020)
Nikita Popov <nikic@php.net> (2013 - 2019)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.4
@@ -344,7 +348,7 @@ MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: intl
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2008 - 2019)
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net> (2008 - 2018)
Anatol Belski <ab@php.net> (2017 - 2018)
MAINTENANCE: Maintained
STATUS: Working
@@ -354,7 +358,6 @@ EXTENSION: imap
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org> (1999 - 2004)
Ilia Alshanetsky <iliaa@php.net> (2002 - 2010)
Pierre-Alain Joye <pajoye@php.net> (2008 - 2010)
Bishop Bettini <bishop@php.net> (2018 - 2019)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -374,14 +377,14 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mbstring
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net> (2001 - 2013)
Nikita Popov <nikic@php.net> (2017 - 2020)
Nikita Popov <nikic@php.net> (2017 - 2019)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: opcache
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@php.net> (2013 - 2018)
Xinchen Hui <laruence@php.net> (2013 - 2020)
Nikita Popov <nikic@php.net> (2016 - 2020)
Xinchen Hui <laruence@php.net> (2013 - 2018)
Nikita Popov <nikic@php.net> (2016 - 2019)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.5.0
@@ -409,7 +412,6 @@ EXTENSION: phar
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net> (2008 - 2009)
Marcus Börger <helly@php.net> (2008 - 2008)
Steph Fox <sfox@php.net> (2008 - 2008)
Bishop Bettini <bishop@php.net> (2018 - 2019)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
@@ -426,14 +428,13 @@ STATUS: Working
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: readline
PRIMARY MAINTAINER: Unknown
PRIMARY MAINTAINER: Unkown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: reflection
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
Johannes Schlüter <johannes@php.net> (2006 - 2014)
Nikita Popov <nikic@php.net> (2019 - 2020)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -476,17 +477,17 @@ STATUS: Working
SINCE: 5.0.0
-------------------------------------------------------------------------------
EXTENSION: sysvmsg
PRIMARY MAINTAINER: Unknown
PRIMARY MAINTAINER: Unkown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sysvsem
PRIMARY MAINTAINER: Unknown
PRIMARY MAINTAINER: Unkown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sysvshm
PRIMARY MAINTAINER: Unknown
PRIMARY MAINTAINER: Unkown
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
@@ -499,13 +500,12 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tokenizer
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (2002 - 2002)
Nikita Popov <nikic@php.net> (2013 - 2020)
Nikita Popov <nikic@php.net> (2013 - 2019)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: zip
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Remi Collet <remi@php.net> (2013-2020)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
+2261 -348
View File
File diff suppressed because it is too large. Load diff
+41 -15
View File
@@ -7,14 +7,15 @@
7. ext/standard/scanf
8. ext/standard/strnatcmp.c
9. ext/standard/uuencode
10. main/snprintf.c
11. main/strlcat
12. main/strlcpy
13. libgd (ext/gd)
14. ext/phar portions of tar implementations
15. ext/phar/zip.c portion extracted from libzip
16. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/LICENSE
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
10. libxmlrpc ext/xmlrpc
11. main/snprintf.c
12. main/strlcat
13. main/strlcpy
14. libgd (ext/gd)
15. ext/phar portions of tar implementations
16. ext/phar/zip.c portion extracted from libzip
17. libbcmath (ext/bcmath) see ext/bcmath/libbcmath/LICENSE
18. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
3. pcre2lib (ext/pcre)
@@ -354,7 +355,32 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
10. main/snprintf.c
10. libxmlrpc ext/xmlrpc
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.
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.
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.
11. main/snprintf.c
Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -429,8 +455,8 @@ SIO stdio-replacement strx_* functions by Panos Tsirigotis
<panos@alumni.cs.colorado.edu> for xinetd.
11. main/strlcat
12. main/strlcpy
12. main/strlcat
13. main/strlcpy
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
@@ -458,7 +484,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13. libgd (ext/gd)
14. libgd (ext/gd)
* Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under
@@ -528,7 +554,7 @@ Avenue Software Corporation for their prior contributions.
END OF COPYRIGHT STATEMENT
14. ext/phar portions of tar implementations
15. 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:
@@ -557,7 +583,7 @@ implementation by Tim Kientzle from libarchive, licensed with this license:
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15. ext/phar/zip.c portion extracted from libzip
16. ext/phar/zip.c portion extracted from libzip
zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
@@ -591,7 +617,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
18. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
The OpenLDAP Public License
Version 2.8, 17 August 2003
+14 -22
View File
@@ -11,13 +11,12 @@
PHP is a popular general-purpose scripting language that is especially suited to
web development. Fast, flexible and pragmatic, PHP powers everything from your
blog to the most popular websites in the world. PHP is distributed under the
[PHP License v3.01](LICENSE).
blog to the most popular websites in the world. PHP is distributed under the PHP
License v3.01.
[![Build status](https://travis-ci.org/php/php-src.svg?branch=master)](https://travis-ci.org/php/php-src)
[![Build status](https://ci.appveyor.com/api/projects/status/meyur6fviaxgdwdy/branch/master?svg=true)](https://ci.appveyor.com/project/php/php-src)
[![Build Status](https://dev.azure.com/phpazuredevops/php/_apis/build/status/php.php-src?branchName=master)](https://dev.azure.com/phpazuredevops/php/_build/latest?definitionId=1&branchName=master)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php)
[![Build status](https://ci.appveyor.com/api/projects/status/meyur6fviaxgdwdy?svg=true)](https://ci.appveyor.com/project/php/php-src)
[![Build Status](https://dev.azure.com/phpazuredevops/php/_apis/build/status/php.php-src?branchName=PHP-7.4)](https://dev.azure.com/phpazuredevops/php/_build/latest?definitionId=1&branchName=PHP-7.4)
## Documentation
@@ -39,31 +38,24 @@ For other systems, see the [installation chapter](https://php.net/install).
*For Windows, see [Build your own PHP on Windows](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2).*
For a minimal PHP build from Git, you will need autoconf, bison, and re2c. For
a default build, you will additionally need libxml2 and libsqlite3. On Ubuntu,
you can install these using:
sudo apt install -y pkg-config build-essential autoconf bison re2c \
libxml2-dev libsqlite3-dev
Generate configure:
PHP uses autotools on Unix systems to configure the build:
./buildconf
./configure [options]
Configure your build. `--enable-debug` is recommended for development, see
`./configure --help` for a full list of options.
*See `./configure -h` for configuration options.*
# For development
./configure --enable-debug
# For production
./configure
make [options]
Build PHP. To speed up the build, specify the maximum number of jobs using `-j`:
*See `make -h` for make options.*
The `-j` option shall set the maximum number of jobs `make` can use for the
build:
make -j4
The number of jobs should usually match the number of available cores, which
can be determined using `nproc`.
Shall run `make` with a maximum of 4 concurrent jobs: Generally the maximum
number of jobs should not exceed the number of cores available.
## Testing PHP source code
+155 -53
View File
@@ -17,11 +17,11 @@
#include <stdio.h>
#include <stdarg.h>
#if ZEND_DEBUG
#ifdef ZEND_DEBUG
# include <assert.h>
# define TSRM_ASSERT(c) assert(c)
# define TSRM_ASSERT assert
#else
# define TSRM_ASSERT(c)
# define TSRM_ASSERT
#endif
typedef struct _tsrm_tls_entry tsrm_tls_entry;
@@ -74,7 +74,7 @@ int tsrm_error(int level, const char *format, ...);
static int tsrm_error_level;
static FILE *tsrm_error_file;
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
#define TSRM_ERROR(args) tsrm_error args
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
{ \
@@ -102,26 +102,49 @@ static FILE *tsrm_error_file;
}
#endif
#ifdef TSRM_WIN32
static DWORD tls_key;
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
# define tsrm_tls_get() TlsGetValue(tls_key)
#else
#if defined(GNUPTH)
static pth_key_t tls_key;
# define tsrm_tls_set(what) pth_key_setdata(tls_key, (void*)(what))
# define tsrm_tls_get() pth_key_getdata(tls_key)
#elif defined(PTHREADS)
/* Thread local storage */
static pthread_key_t tls_key;
# define tsrm_tls_set(what) pthread_setspecific(tls_key, (void*)(what))
# define tsrm_tls_get() pthread_getspecific(tls_key)
#elif defined(TSRM_ST)
static int tls_key;
# define tsrm_tls_set(what) st_thread_setspecific(tls_key, (void*)(what))
# define tsrm_tls_get() st_thread_getspecific(tls_key)
#elif defined(TSRM_WIN32)
static DWORD tls_key;
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
# define tsrm_tls_get() TlsGetValue(tls_key)
#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;
TSRM_TLS uint8_t is_thread_shutdown = 0;
/* Startup TSRM (call once for the entire process) */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename)
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
{/*{{{*/
#ifdef TSRM_WIN32
#if defined(GNUPTH)
pth_init();
pth_key_create(&tls_key, 0);
#elif defined(PTHREADS)
pthread_key_create( &tls_key, 0 );
#elif defined(TSRM_ST)
st_init();
st_key_create(&tls_key, 0);
#elif defined(TSRM_WIN32)
tls_key = TlsAlloc();
#else
pthread_key_create(&tls_key, 0);
#endif
/* ensure singleton */
@@ -209,11 +232,13 @@ TSRM_API void tsrm_shutdown(void)
if (tsrm_error_file!=stderr) {
fclose(tsrm_error_file);
}
#ifdef TSRM_WIN32
TlsFree(tls_key);
#else
#if defined(GNUPTH)
pth_kill();
#elif defined(PTHREADS)
pthread_setspecific(tls_key, 0);
pthread_key_delete(tls_key);
#elif defined(TSRM_WIN32)
TlsFree(tls_key);
#endif
if (tsrm_shutdown_handler) {
tsrm_shutdown_handler();
@@ -228,11 +253,11 @@ TSRM_API void tsrm_shutdown(void)
/* {{{ */
/* environ lock api */
TSRM_API void tsrm_env_lock(void) {
TSRM_API void tsrm_env_lock() {
tsrm_mutex_lock(tsrm_env_mutex);
}
TSRM_API void tsrm_env_unlock(void) {
TSRM_API void tsrm_env_unlock() {
tsrm_mutex_unlock(tsrm_env_mutex);
} /* }}} */
@@ -469,6 +494,67 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
}/*}}}*/
/* frees an interpreter context. You are responsible for making sure that
* it is not linked into the TSRM hash, and not marked as the current interpreter */
void tsrm_free_interpreter_context(void *context)
{/*{{{*/
tsrm_tls_entry *next, *thread_resources = (tsrm_tls_entry*)context;
int i;
while (thread_resources) {
next = thread_resources->next;
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
}
}
for (i=0; i<thread_resources->count; i++) {
if (!resource_types_table[i].fast_offset) {
free(thread_resources->storage[i]);
}
}
free(thread_resources->storage);
free(thread_resources);
thread_resources = next;
}
}/*}}}*/
void *tsrm_set_interpreter_context(void *new_ctx)
{/*{{{*/
tsrm_tls_entry *current;
current = tsrm_tls_get();
/* TODO: unlink current from the global linked list, and replace it
* it with the new context, protected by mutex where/if appropriate */
/* Set thread local storage to this new thread resources structure */
tsrm_tls_set(new_ctx);
/* return old context, so caller can restore it when they're done */
return current;
}/*}}}*/
/* allocates a new interpreter context */
void *tsrm_new_interpreter_context(void)
{/*{{{*/
tsrm_tls_entry *new_ctx, *current;
THREAD_T thread_id;
thread_id = tsrm_thread_id();
tsrm_mutex_lock(tsmm_mutex);
current = tsrm_tls_get();
allocate_new_resource(&new_ctx, thread_id);
/* switch back to the context that was in use prior to our creation
* of the new one */
return tsrm_set_interpreter_context(current);
}/*}}}*/
/* frees all resources allocated for the current thread */
void ts_free_thread(void)
@@ -551,6 +637,8 @@ void ts_free_id(ts_rsrc_id id)
}/*}}}*/
/*
* Utility Functions
*/
@@ -560,8 +648,12 @@ TSRM_API THREAD_T tsrm_thread_id(void)
{/*{{{*/
#ifdef TSRM_WIN32
return GetCurrentThreadId();
#else
#elif defined(GNUPTH)
return pth_self();
#elif defined(PTHREADS)
return pthread_self();
#elif defined(TSRM_ST)
return st_thread_self();
#endif
}/*}}}*/
@@ -573,9 +665,14 @@ TSRM_API MUTEX_T tsrm_mutex_alloc(void)
#ifdef TSRM_WIN32
mutexp = malloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(mutexp);
#else
#elif defined(GNUPTH)
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
pth_mutex_init(mutexp);
#elif defined(PTHREADS)
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mutexp,NULL);
#elif defined(TSRM_ST)
mutexp = st_mutex_new();
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
@@ -591,9 +688,13 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
#ifdef TSRM_WIN32
DeleteCriticalSection(mutexp);
free(mutexp);
#else
#elif defined(GNUPTH)
free(mutexp);
#elif defined(PTHREADS)
pthread_mutex_destroy(mutexp);
free(mutexp);
#elif defined(TSRM_ST)
st_mutex_destroy(mutexp);
#endif
}
#ifdef THR_DEBUG
@@ -612,8 +713,15 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
#ifdef TSRM_WIN32
EnterCriticalSection(mutexp);
return 0;
#else
#elif defined(GNUPTH)
if (pth_mutex_acquire(mutexp, 0, NULL)) {
return 0;
}
return -1;
#elif defined(PTHREADS)
return pthread_mutex_lock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_lock(mutexp);
#endif
}/*}}}*/
@@ -628,8 +736,15 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
#ifdef TSRM_WIN32
LeaveCriticalSection(mutexp);
return 0;
#else
#elif defined(GNUPTH)
if (pth_mutex_release(mutexp)) {
return 0;
}
return -1;
#elif defined(PTHREADS)
return pthread_mutex_unlock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_unlock(mutexp);
#endif
}/*}}}*/
@@ -640,8 +755,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
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()));
return pthread_sigmask(how, set, oldset);
/* TODO: add support for other APIs */
#ifdef PTHREADS
return pthread_sigmask(how, set, oldset);
#else
return sigprocmask(how, set, oldset);
#endif
}/*}}}*/
#endif
@@ -677,7 +796,7 @@ TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler)
* Debug support
*/
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
int tsrm_error(int level, const char *format, ...)
{/*{{{*/
if (level<=tsrm_error_level) {
@@ -698,11 +817,11 @@ int tsrm_error(int level, const char *format, ...)
#endif
void tsrm_error_set(int level, const char *debug_filename)
void tsrm_error_set(int level, char *debug_filename)
{/*{{{*/
tsrm_error_level = level;
#ifdef TSRM_DEBUG
#if TSRM_DEBUG
if (tsrm_error_file!=stderr) { /* close files opened earlier */
fclose(tsrm_error_file);
}
@@ -723,29 +842,6 @@ TSRM_API void *tsrm_get_ls_cache(void)
return tsrm_tls_get();
}/*}}}*/
/* Returns offset of tsrm_ls_cache slot from Thread Control Block address */
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
{/*{{{*/
#if defined(__APPLE__) && defined(__x86_64__)
// TODO: Implement support for fast JIT ZTS code ???
return 0;
#elif defined(__x86_64__) && defined(__GNUC__)
size_t ret;
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret));
return ret;
#elif defined(__i386__) && defined(__GNUC__)
size_t ret;
asm ("leal _tsrm_ls_cache@ntpoff,%0"
: "=r" (ret));
return ret;
#else
return 0;
#endif
}/*}}}*/
TSRM_API uint8_t tsrm_is_main_thread(void)
{/*{{{*/
return in_main_thread;
@@ -758,10 +854,16 @@ TSRM_API uint8_t tsrm_is_shutdown(void)
TSRM_API const char *tsrm_api_name(void)
{/*{{{*/
#ifdef TSRM_WIN32
#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 "POSIX Threads";
return "Unknown";
#endif
}/*}}}*/
+45 -21
View File
@@ -44,8 +44,14 @@ typedef uintptr_t tsrm_uintptr_t;
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
# define WIN32_LEAN_AND_MEAN
# endif
#else
# include <windows.h>
# include <shellapi.h>
#elif defined(GNUPTH)
# include <pth.h>
#elif defined(PTHREADS)
# include <pthread.h>
#elif defined(TSRM_ST)
# include <st.h>
#endif
#if SIZEOF_SIZE_T == 4
@@ -62,9 +68,15 @@ typedef int ts_rsrc_id;
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#else
#elif defined(GNUPTH)
# define THREAD_T pth_t
# define MUTEX_T pth_mutex_t *
#elif defined(PTHREADS)
# define THREAD_T pthread_t
# define MUTEX_T pthread_mutex_t *
#elif defined(TSRM_ST)
# define THREAD_T st_thread_t
# define MUTEX_T st_mutex_t
#endif
#include <signal.h>
@@ -79,12 +91,12 @@ extern "C" {
#endif
/* startup/shutdown */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename);
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
TSRM_API void tsrm_shutdown(void);
/* environ lock API */
TSRM_API void tsrm_env_lock(void);
TSRM_API void tsrm_env_unlock(void);
TSRM_API void tsrm_env_lock();
TSRM_API void tsrm_env_unlock();
/* 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);
@@ -115,7 +127,7 @@ typedef void (*tsrm_shutdown_func_t)(void);
TSRM_API int tsrm_error(int level, const char *format, ...);
TSRM_API void tsrm_error_set(int level, const char *debug_filename);
TSRM_API void tsrm_error_set(int level, char *debug_filename);
/* utility functions */
TSRM_API THREAD_T tsrm_thread_id(void);
@@ -131,8 +143,13 @@ TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_th
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. */
TSRM_API void *tsrm_new_interpreter_context(void);
TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
TSRM_API void tsrm_free_interpreter_context(void *context);
TSRM_API void *tsrm_get_ls_cache(void);
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
TSRM_API uint8_t tsrm_is_main_thread(void);
TSRM_API uint8_t tsrm_is_shutdown(void);
TSRM_API const char *tsrm_api_name(void);
@@ -143,21 +160,11 @@ TSRM_API const char *tsrm_api_name(void);
# define TSRM_TLS __thread
#endif
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
#if !__has_attribute(tls_model)
# define TSRM_TLS_MODEL_ATTR
#elif __PIC__
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
#else
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec")))
#endif
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache()
#define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element)
#define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element)
@@ -167,11 +174,18 @@ TSRM_API const char *tsrm_api_name(void);
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element)
#define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset)))
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL;
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#define TSRMLS_CACHE _tsrm_ls_cache
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#define TSRMLS_FETCH()
#ifdef __cplusplus
}
#endif
@@ -181,6 +195,10 @@ TSRM_API const char *tsrm_api_name(void);
#define tsrm_env_lock()
#define tsrm_env_unlock()
#define TSRMLS_FETCH()
#define TSRMLS_FETCH_FROM_CTX(ctx)
#define TSRMLS_SET_CTX(ctx)
#define TSRMG_STATIC(id, type, element)
#define TSRMLS_CACHE_EXTERN()
#define TSRMLS_CACHE_DEFINE()
@@ -189,6 +207,12 @@ TSRM_API const char *tsrm_api_name(void);
#define TSRM_TLS
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#endif /* ZTS */
#endif /* TSRM_H */
+74
View File
@@ -1,5 +1,43 @@
dnl This file contains TSRM specific autoconf macros.
dnl
dnl TSRM_CHECK_PTH
dnl
AC_DEFUN([TSRM_CHECK_PTH],[
AC_MSG_CHECKING(for GNU Pth)
PTH_PREFIX="`$1 --prefix`"
if test -z "$PTH_PREFIX"; then
AC_MSG_RESULT(Please check your Pth installation)
fi
CPPFLAGS="$CPPFLAGS `$1 --cflags`"
LDFLAGS="$LDFLAGS `$1 --ldflags`"
LIBS="$LIBS `$1 --libs`"
AC_DEFINE(GNUPTH, 1, [Whether you use GNU Pth])
AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
])
dnl
dnl TSRM_CHECK_ST
dnl
AC_DEFUN([TSRM_CHECK_ST],[
if test -r "$1/include/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1/include"
LDFLAGS="$LDFLAGS -L$1/lib"
elif test -r "$1/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1"
LDFLAGS="$LDFLAGS -L$1"
fi
AC_CHECK_HEADERS(st.h,[],[
AC_MSG_ERROR([Sorry[,] I was unable to locate the State Threads header file. Please specify the prefix using --with-tsrm-st=/prefix])
])
LIBS="$LIBS -lst"
AC_MSG_CHECKING(for SGI's State Threads)
AC_MSG_RESULT(yes)
AC_DEFINE(TSRM_ST, 1, [ ])
])
dnl
dnl TSRM_CHECK_PTHREADS
dnl
@@ -15,3 +53,39 @@ AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
])
dnl
dnl TSRM_THREADS_CHECKS
dnl
dnl For the thread implementations, we always use --with-* to maintain
dnl consistency.
dnl
AC_DEFUN([TSRM_THREADS_CHECKS],[
AC_ARG_WITH([tsrm-pth],
[AS_HELP_STRING([[--with-tsrm-pth[=pth-config]]],
[Use GNU Pth])],
[TSRM_PTH=$withval],
[TSRM_PTH=no])
AC_ARG_WITH([tsrm-st],
[AS_HELP_STRING([--with-tsrm-st],
[Use SGI's State Threads])],
[TSRM_ST=$withval],
[TSRM_ST=no])
AC_ARG_WITH([tsrm-pthreads],
[AS_HELP_STRING([--with-tsrm-pthreads],
[Use POSIX threads (default)])],
[TSRM_PTHREADS=$withval],
[TSRM_PTHREADS=yes])
test "$TSRM_PTH" = "yes" && TSRM_PTH=pth-config
if test "$TSRM_PTH" != "no"; then
TSRM_CHECK_PTH($TSRM_PTH)
elif test "$TSRM_ST" != "no"; then
TSRM_CHECK_ST($TSRM_ST)
elif test "$TSRM_PTHREADS" != "no"; then
TSRM_CHECK_PTHREADS
fi
])
+8 -4
View File
@@ -1,4 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
@@ -103,7 +105,7 @@ TSRM_API void tsrm_win32_shutdown(void)
#endif
}/*}}}*/
const 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, size_t pathname_len, size_t *key_len)
{/*{{{*/
PSID pSid = TWG(impersonation_token_sid);
char *ptcSid = NULL;
@@ -443,7 +445,7 @@ 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, const char *env)
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;
@@ -478,12 +480,12 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
return NULL;
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
if (!cmd) {
return NULL;
}
sprintf(cmd, "%s /s /c \"%s\"", TWG(comspec), command);
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
cmdw = php_win32_cp_any_to_w(cmd);
if (!cmdw) {
free(cmd);
@@ -769,6 +771,7 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
}
}/*}}}*/
#if HAVE_UTIME
static zend_always_inline void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */
{
// Note that LONGLONG is a 64-bit value
@@ -823,3 +826,4 @@ TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */
}
/* }}} */
#endif
#endif
+7 -3
View File
@@ -1,4 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
@@ -19,7 +21,9 @@
#include "TSRM.h"
#include <windows.h>
#include <sys/utime.h>
#if HAVE_UTIME
# include <sys/utime.h>
#endif
#include "win32/ipc.h"
struct ipc_perm {
@@ -89,12 +93,12 @@ TSRMLS_CACHE_EXTERN()
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
const 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, size_t pathname_len, size_t *key_len);
TSRM_API void tsrm_win32_startup(void);
TSRM_API void tsrm_win32_shutdown(void);
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, const char *env);
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env);
TSRM_API FILE *popen(const char *command, const char *type);
TSRM_API int pclose(FILE *stream);
TSRM_API int tsrm_win32_access(const char *pathname, int mode);
+687 -986
View File
File diff suppressed because it is too large. Load diff
+273 -407
View File
@@ -1,30 +1,31 @@
PHP 8.0 INTERNALS UPGRADE NOTES
PHP 7.4 INTERNALS UPGRADE NOTES
1. Internal API changes
a. Object Handlers API
b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler
c. TSRM changes
d. get() and set() object handlers
e. zend_parse_parameters 'L' specifier
f. Arginfo argument types
g. zend_free_op type and should_free argument of zend_get_zval_ptr()
h. zend_value_error()
i. get_closure() object handler
j. compare_objects() and compare() object handlers
k. The 'I' length modifier
l. Some VM instructions switched to IS_TMP_VAR result instead of IS_VAR
m. All internal functions must have arginfo
n. zend_hash_sort compare function and zend_hash_sort signature change
o. cast_object() object handler is now required
p. ARG_COUNT() macro removed
q. GC_COLLECTABLE flag
r. Cannot implement Traversable only
s. zend_fcall_info no_separation flag removed
t. Signature changes
u. Error Notification callbacks to replace zend_error_cb overwrite use-cases
v. Removed Zend APIs
w. Renamed Zend APIs
x. ZEND_EXT_NOP no longer emitted
a. php_sys_symlink() and php_sys_link()
b. zend_lookup_class_ex() and zend_fetch_class_by_name()
c. Function/property/class flags
d. Removed zend_check_private()
e. php_win32_error_to_msg() memory management
f. get_properties_for() handler / Z_OBJDEBUG_P
g. Required object handlers
h. Immutable classes and op_arrays
i. php_fgetcsv() and php_fputcsv()
j. Removed add_get_assoc_*() and add_get_index_*()
k. Class declaration opcodes
l. HASH_FLAG_INITIALIZED
m. write_property return value
n. Assignments to references
o. ZEND_COMPILE_EXTENDED_INFO split
p. ZEND_EXT_FCALL_BEGIN can access arguments
q. ZEND_COMPILE_IGNORE_USER_FUNCTIONS and ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS
r. TSRM environment locking
s. Typed references support
t. Exceptions thrown by string conversions.
u. Removed uint and ulong typedefs
v. Compound assignment opcodes
w. APACHE symbol removed
x. php_error_docref0() renamed to php_error_docref()
y. Stream wrapper read/write ops
2. Build system changes
a. Abstract
@@ -32,430 +33,295 @@ PHP 8.0 INTERNALS UPGRADE NOTES
c. Windows build system changes
3. Module changes
a. ext/xml
b. ext/hash
========================
1. Internal API changes
========================
a. The Object Handlers API was changed to receive zend_object* instead of
zval* and zend_string* instead of zval* for property names. See also
section t for other similar changes.
a. php_sys_symlink() and php_sys_link() portability macros have been
added, which behave like POSIX's symlink() and link(), respectively, on
POSIX compliant systems and on Windows.
b. ZEND_OVERLOADED_FUNCTION and corresponding call_method() object handler
were removed. ZEND_INTERNAL_FUNCTION with ZEND_ACC_CALL_VIA_HANDLER and
defined "handler" callback should be used instead. This "handler" callback
should also take care about function cleanup. See ext/zend_test/test.c
for example.
b. zend_lookup_class_ex() and zend_fetch_class_by_name() prototypes were
changed to accept optional lower-case class name as zend_string*,
instead of zval*.
c. The following things have been removed from TSRM:
- TSRMLS_DC
- TSRMLS_D
- TSRMLS_CC
- TSRMLS_C
- TSRMLS_FETCH
- TSRMLS_FETCH_FROM_CTX
- TSRMLS_SET_CTX
- tsrm_new_interpreter_context
- tsrm_set_interpreter_context
- tsrm_free_interpreter_context
- support for GNUPTH, SGI ST, and BETHREADS
c. Function/property/class flags changes
- ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
during inheritance).
- ZEND_ACC_IMPLICIT_PUBLIC is removed (it was used only for reflection)
- ZEND_ACC_SHADOW property flag is removed. Instead of creating shadow
clone, now we use the same private property_info, and should also
check property_info->ce (in the same way as with methods).
- ZEND_ACC_ANON_BOUND is replaced with ZEND_ACC_LINKED. This flag is set
not only during anonymous classes declaration, but also during any
run-time or compile-time class declaration.
- ZEND_ACC_NO_RT_ARENA renamed into ZEND_ACC_HEAP_RT_CACHE. Now it's used
not only for closures, but also for pseudo-main op_arrays.
- ZEND_ACC_... flags are re-numbered.
d. The get() and set() object handlers have been removed. The get() handler
can generally be replaced with cast_object(). Some uses of set() may be
replaced by do_operation(). If set() was used to overload direct
assignments using "=", then this is no longer supported and the
functionality should be provided in some other way (for example, as
modification of an object property).
d. zend_check_private() is removed. Use (func->common.scope == scope) instead.
e. The zend_parse_parameters 'L' specifier and the Z_PARAM_STRICT_LONG()
family of macros have been removed. Use 'l' and Z_PARAM_LONG() instead,
which, despite the confusing name, actually have stricter input validation.
e. Pointers returned by php_win32_error_to_msg() have to be freed using
php_win32_error_msg_free(). Same regarding php_win_err() vs.
php_win_err_free().
f. Arginfo argument types for internal functions are no longer checked.
Instead type checks should be performed using the zend_parse_parameters()
or ZEND_PARSE_PARAMETERS_*() APIs.
f. A new, optional object handler with the signature
g. The zend_free_op type and the "should_free" and "type" arguments of
zend_get_zval_ptr() were removed. It's possible to get the old
"should_free" value using the following code:
HashTable *get_properties_for(zval *obj, zend_prop_purpose purpose)
zval *ret = zend_get_zval_ptr(
opline, opline->op1_type, &opline->op1, execute_data);
zval *should_free = (op_type & (IS_TMP_VAR|IS_VAR)) ? ret : NULL;
has been introduced, where zend_prop_purpose (currently) takes one of:
h. Added the zend_value_error() function, which is intended to be used
to raise ValueError when inappropriate argument values are passed
to functions.
ZEND_PROP_PURPOSE_DEBUG // var_dump etc.
ZEND_PROP_PURPOSE_ARRAY_CAST // (array) $obj
ZEND_PROP_PURPOSE_SERIALIZE // "O"-format serialization (__wakeup)
ZEND_PROP_PURPOSE_VAR_EXPORT // var_export (__set_state)
ZEND_PROP_PURPOSE_JSON // json_encode
i. get_closure() object handlers now accept an additional zend_bool parameter
`check_only`. If it is true, the handler is called to check whether the
object is callable; in this case the handler should not throw an exception.
The handler returns a non-null HashTable with increased refcounted, and
the return value must be released using zend_release_properties().
j. compare_objects() handler was removed. Extensions should use compare() object
handler instead and check if both arguments are objects and have the same
compare handler, using ZEND_COMPARE_OBJECTS_FALLBACK() macro.
This handler serves the same general function as get_properties(), but
provides more control over different property uses, while also making
it possible to return a temporary property table.
k. The 'I' length modifier, used to denote 32 and 64bit integer from the custom
snprintf and spprintf implementations has been removed.
Use the ZEND_LONG_FMT, ZEND_ULONG_FMT and ZEND_XLONG_FMT macros defined in
php-src/Zend/zend_long.h
get_properties() is still used in cases where none of the above purposes
apply, but overloading get_properties() is generally discouraged. If you
want to provide purposes for general usage rather than just debugging or
serialization, please prefer using properly declared properties.
The 'v' format from the custom snprintf and spprintf implementations has
been removed. Use the standard 's' format instead.
get_debug_info() is superseded by get_properties_for() with the
ZEND_PROP_PURPOSE_DEBUG purpose, but remains available for backwards-
compatibility reasons. However, while it is fine to define this handler,
it should never be directly called by consuming code.
l. Some VM instructions switched to IS_TMP_VAR result instead of IS_VAR.
Actually, all assignments (ZEND_ASSIGN, ZEND_ASSIGN_DIM, ZEND_ASSIGN_OBJ,
ZEND_ASSIGN_STATIC_PROP), all compound assignments (ZEND_ASSIGN_OP,
ZEND_ASSIGN_DIM_OP, ZEND_ASSIGN_OBJ_OP, ZEND_ASSIGN_STATIC_PROP_OP) and all
pre increments/decrements (ZEND_PRE_INC, ZEND_PRE_DEC, ZEND_PRE_INC_OBJ
ZEND_PRE_DEC_OBJ, ZEND_PRE_INC_STATIC_PROP ZEND_PRE_DEC_STATIC_PROP).
The Z_OBJDEBUG_P macro has been removed. It should be replaced by calls to
zend_get_properties_for() with the ZEND_PROP_PURPOSE_DEBUG purpose:
m. All internal functions and methods are now required to specify arginfo
information, otherwise warnings will be thrown on startup.
n. The zend_hash_sort and zend_hash_minmax APIs now accept a comparison
function with the following signature:
typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b);
Previously compare_func_t was used, which accepted void pointers.
Furthermore, the return type of zend_hash_sort and zend_ts_hash_sort has
been changed from int to void; these functions always succeed.
o. The cast_object() handler is now required, i.e. must be non-null. You can
indicate that casting is not supported by always returning FAILURE.
p. The ARG_COUNT() macro has been removed use ZEND_NUM_ARGS() instead.
q. GC_COLLECTABLE flag was inverted into GC_NOT_COLLECTABLE.
Assignments to GC_TYPE_INFO() might need to be changed to properly
set the value of the GC_NOT_COLLECTABLE flag.
r. Just for for userland classes, it is no longer allowed to implement only
the Traversable interface. Instead, it is necessary to implement either
Iterator or IteratorAggregate. You can do the latter by implementing
zend_ce_aggregate and providing the following method implementation:
ZEND_METHOD(MyClass, getIterator) {
ZEND_PARSE_PARAMETERS_NONE();
zend_create_internal_iterator_zval(return_value, ZEND_THIS);
// OLD
int is_temp;
HashTable *ht = Z_OBJDEBUG_P(obj, is_temp);
// ...
if (is_temp) {
zend_hash_destroy(ht);
FREE_HASHTABLE(ht);
}
s. The zend_fcall_info no_separation flag has been removed, and separation is
never allowed. If you wish to pass (or allow passing) arguments by
reference, explicitly create those arguments as references using
ZEND_MAKE_REF. This removal also affects call_user_function_ex(), which
should be replaced by call_user_function().
// NEW
HashTable *ht = zend_get_properties_for(obj, ZEND_PROP_PURPOSE_DEBUG);
// ...
zend_release_properties(ht);
t. The following ZEND_API function have changed signature:
1. Void in Zend Engine 4.0:
- add_assoc_*()
- add_index_*()
- add_property_*()
- object_init()
- zend_declare_class_constant*()
- zend_declare_property*()
- zend_startup_modules()
- zend_wrong_parameters_none_error()
- zend_fcall_info_argp()
- zend_fcall_info_argv()
- zend_fcall_info_argn()
- zend_startup()
- zend_set_memory_limit()
- pass_two()
- zend_startup_constants()
- zend_shutdown_constants()
- zend_startup_extensions_mechanism()
- zend_startup_extensions()
- zend_register_extension()
- highlight_string()
- zend_ini_startup()
- zend_ini_shutdown()
- zend_ini_global_shutdown()
- zend_ini_deactivate()
- zend_copy_ini_directives()
- zend_prepare_string_for_scanning()
- zend_init_rsrc_list()
- zend_list_close()
- zend_signal()
- zend_sigaction()
- zend_stack_init()
- zend_stack_del_top()
- zend_stack_destroy()
2. Argument int to uint32_t in Zend Engine 4.0:
- _zend_get_parameters_array_ex()
- zend_copy_parameters_array()
- zend_fcall_info_args_save()
- zend_fcall_info_args_restore()
- zend_fcall_info_argp()
- zend_fcall_info_argv()
- zend_fcall_info_argn()
- zend_wrong_parameter*()
- zend_wrong_callback_error()
- zend_parse_arg_class()
3. Argument int to bool in Zend Engine 4.0:
- add_next_index_bool()
- zend_register_class_alias_ex()
- add_assoc_bool_ex()
- add_index_bool()
- zend_fcall_info_args_clear()
- zend_set_local_var()
- zend_set_local_var_str()
- zend_parse_arg_*()
- shutdown_memory_manager()
- zend_memory_usage()
- zend_memory_peak_usage()
- zend_mm_shutdown()
- zend_eval_string*()
- zend_set_timeout()
- _zend_hash_append_ex()
- _zend_hash_append_ptr_ex()
- zend_alter_ini_entry_ex()
- (*zend_encoding_list_parser) typedef
- zend_multibyte_parse_encoding_list()
- zend_safe_address()
- zend_string_tolower_ex()
- zend_string_alloc()
- zend_string_safe_alloc()
- zend_string_init()
- zend_string_dup()
- zend_string_realloc()
- zend_string_extend()
- zend_string_truncate()
- zend_string_safe_realloc()
- zend_string_release_ex()
- zend_ts_hash_merge()
- zend_ts_hash_sort()
4. Argument int to size_t in Zend Engine 4.0:
- zend_set_hash_symbol()
5. Argument zval* to zend_object* in Zend Engine 4.0:
- zend_read_property()
- zend_update_property()
- zend_unset_property()
- zend_call_method()
- zend_objects_clone_obj()
- zend_get_closure_method_def()
- zend_throw_exception_hook()
- zend_throw_exception_internal()
- zend_get_exception_base()
6. Argument zval* to zend_long in Zend Engine 4.0:
- _php_math_longtobase()
7. Return type from int to zend_result in Zend Engine 4.0:
- (*stream_open_function) in _zend_utility_functions
- (*zend_post_startup_cb)
- (*zend_preload_autoload)
- zend_execute_scripts()
- zend_post_startup()
- _zend_get_parameters_array_ex()
- zend_copy_parameters_array()
- zend_parse_parameters()
- zend_parse_parameters_ex()
- zend_parse_method_parameters()
- zend_parse_method_parameters_ex()
- zend_parse_method_parameters()
- zend_register_functions()
- zend_startup_module()
- zend_startup_module_ex()
- zend_register_class_alias_ex()
- zend_disable_function()
- zend_disable_class()
- zend_update_class_constants()
- zend_update_static_property*()
- object_init_ex()
- object_and_properties_init()
- add_index_zval()
- add_next_index_long_*()
- array_set_zval_key()
- _call_user_function_impl()
- zend_fcall_info_*()
- zend_call_function()
- zend_set_hash_symbol()
- zend_delete_global_variable()
- zend_set_local_var()
- zend_set_local_var_str()
- zend_forbid_dynamic_call()
- zend_get_default_from_internal_arg_info()
- zend_try_assign_typed_ref*()
- zend_ast_evaluate()
- zend_startup_builtin_functions()
- do_bind_function()
- do_bind_class()
- zend_unmangle_property_name_ex()
- zend_register_auto_global()
- zend_register_constant()
- zend_exception_error()
- zend_eval_string*()
- zend_undefined_offset_write()
- zend_undefined_index_write()
- zval_update_constant(_ex)()
- zend_load_extension()
- zend_load_extension_handle()
- zend_hash_del(_ind)()
- zend_hash_str_del(_ind)()
- zend_hash_index_del()
- zend_hash_move_forward_ex()
- zend_hash_move_backward_ex()
- zend_hash_get_current_key_ex()
- zend_hash_get_current_key_type_ex()
- zend_symtable_del(_ind)()
- zend_symtable_str_del(_ind)()
- highlight_file()
- zend_do_link_class()
- zend_alter_ini_entry*()
- zend_restore_ini_entry()
- zend_ini_register_displayer()
- zend_ini_open_file_for_scanning()
- zend_ini_prepare_string_for_scanning()
- zend_user_it_valid()
- zend_create_internal_iterator_zval()
- zend_multibyte_set_filter()
- zend_lex_tstring()
- _zend_module_entry module_startup_func, module_shutdown_func,
request_startup_func, request_shutdown_func, and post_deactivate_func function pointers
- (*zend_encoding_list_parser) typedef
- (*zend_encoding_internal_encoding_setter) typedef
- zend_multibyte_set_functions()
- zend_multibyte_set_script_encoding_by_string()
- add_function()
- sub_function()
- mul_function()
- pow_function()
- div_function()
- mod_function()
- boolean_xor_function()
- boolean_not_function()
- bitwise_not_function()
- bitwise_or_function()
- bitwise_and_function()
- bitwise_xor_function()
- shift_left_function()
- shift_right_function()
- concat_function()
- is_equal_function(
- is_identical_function()
- is_not_identical_function()
- is_not_equal_function()
- is_smaller_function()
- is_smaller_or_equal_function(zv
- increment_function()
- decrement_function()
- zend_stream_open()
- zend_stream_fixup()
- zend_ts_hash_del()
- zend_ts_hash_index_del()
8. Return type from int to bool in Zend Engine 4.0:
- zend_make_printable_zval()
- zend_parse_arg_*()
- is_zend_mm()
- is_zend_ptr()
- zend_mm_is_custom_heap()
- (*zend_mm_chunk_truncate_t)
- (*zend_mm_chunk_extend_t)
- zend_bitset_empty()
- zend_is_smart_branch()
- zend_check_arg_send_type()
- zend_verify_const_access()
- zend_gdb_register_code()
- zend_gdb_present()
- _zend_handle_numeric_str(_ex)()
- zend_hash_exists_ind()
- zend_hash_str_exists_ind()
- zend_symtable_exists(_ind)()
- zend_symtable_str_exists()
- (*zend_encoding_lexer_compatibility_checker)
- zend_object_is_true()
- i_zend_is_true()
- zendi_smart_streq()
- zend_stack_is_empty()
- zend_ts_hash_exists()
- zend_ts_hash_index_exists()
9. Argument void to const char* in Zend Engine 4.0:
- zend_get_op_array_extension_handle()
10. Argument zend_extension to const char* in Zend Engine 4.0:
- zend_get_resource_handle()
11. Argument const char * to HMODULE in Zend Engine 4.0:
- php_win32_image_compatible()
12. const char * argument dropped in Zend Engine 4.0:
- php_win32_crt_compatible()
g. The following object handlers are now required (must be non-NULL):
u. Instead of overwriting zend_error_cb extensions with debugging, monitoring
use-cases catching Errors/Exceptions are strongly encouraged to use
the new error observer API instead.
* free_obj
* dtor_obj
* read_property
* write_property
* read_dimension
* write_dimension
* get_property_ptr_ptr
* has_property
* unset_property
* has_dimension
* unset_dimension
* get_properties
* get_method
* get_constructor
* get_class_name
* get_gc
Error observering callbacks are guaranteed to be called regardless of
the users error_reporting setting or userland error handler return values.
It is recommended to initialize object handler structures by copying the
std object handlers and only overwriting those you want to change.
Register observer callbacks during MINIT of an extension:
h. Opcache may make classes and op_arrays immutable. Such classes are marked
by ZEND_ACC_IMMUTABLE flag, they are not going to be copied from opcache
shared memory to process memory and must not be modified at all.
Few related data structures were changed to allow addressing mutable data
structures from immutable ones. This access is implemented through
ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of
indirection. op_array->run_time_cache, op_array->static_variables_ptr and
class_entry->static_members_table now have to be accessed through
ZEND_MAP_PTR... macros.
It's also not allowed to change op_array->reserved[] handles of immutable
op_arrays. Instead, now you have to reserve op_array handle using
zend_get_op_array_extension_handle() during MINIT and access its value
using ZEND_OP_ARRAY_EXTENSION(op_array, handle).
void my_error_observer_cb(int type,
const char *error_filename,
uint32_t error_lineno,
zend_string *message) {
}
zend_observer_error_register(my_error_observer_cb);
i. The type of the escape parameter of php_fgetcsv() and php_fputcsv() has
been changed from char to int. This allows to pass the new constant macro
PHP_CSV_NO_ESCAPE to this parameter, to disable PHP's proprietary escape
mechanism.
v. The following APIs have been removed from the Zend Engine:
- zend_ts_hash_init_ex(), drop the last argument and use zend_ts_hash_init() instead
- zend_hash_init_ex(), drop the last argument and use zend_hash_init() instead
- zval_internal_dtor(), use zval_internal_ptr_dtor() instead
- zval_dtor_func(), use rc_dtor_func() instead
- zval_ptr_dtor_wrapper(), use zval_ptr_dtor() instead
- zval_internal_ptr_dtor_wrapper(), use zval_internal_ptr_dtor() instead
j. add_get_assoc_*() and add_get_index_*() are removed. Use add_assoc*(),
add_index*() or zend_hash_*() API functions instead.
w. The following APIs have been renamed:
- _zend_ts_hash_init() to zend_ts_hash_init()
k. Complex class declaration opcodes ZEND_ADD_INTERFACE, ZEND_ADD_TRAIT,
ZEND_BIND_TRAITS and ZEND_VERIFY_ABSTRACT_CLASS were removed. Information
about interfaces and traits is kept in zend_class_entry structure and
actual linked performed by ZEND_DECLARE_...CLASS... opcode(s).
Linked classes have ZEND_ACC_LINKED flag set.
x. In COMPILE_EXTENDED_STMT mode, a ZEND_EXT_NOP opcode will no longer be
generated at the start of a function. Use the new observer APIs or hook
into zend_execute_ex instead.
l. HASH_FLAG_INITIALIZED was reverted into HASH_FLAG_UNINITIALIZED. Special
HT_IS_INITIALIZED() and HT_INVALIDATE() macro were introduced to hide
implementation details.
m. The write_property() object handler now returns the assigned value (after
possible type coercions) rather than void. For extensions, it should
usually be sufficient to return whatever was passed as the argument.
n. Assignments to references now need to ensure that they respect property
types that affect the reference. This means that references should no
longer be directly assigned to, and instead a set of specialized macros of
the form ZEND_TRY_ASSIGN* needs to be used. You can find detailed porting
instructions as well as a compatibility shim in the wiki:
https://wiki.php.net/rfc/typed_properties_v2#assignments_to_references
o. ZEND_COMPILE_EXTENDED_INFO has been split into:
ZEND_COMPILE_EXTENDED_FCALL and ZEND_COMPILE_EXTENDED_STMT
This allows tooling to choose between profiling and debugging behaviour
ZEND_COMPILE_EXTENDED_INFO remains and preserves behaviour.
p. ZEND_EXT_BEGIN_FCALL is emitted after arguments are sent, this means
that handlers may access arguments.
q. ZEND_COMPILE_IGNORE_USER_FUNCTIONS and ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS
are respected by zend_get_call_op such that when set, the only possible
call opcodes are ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME, previously they
were ignored by zend_get_call_op.
r. TSRM adds tsrm_env_lock() and tsrm_env_unlock() for ZTS:
code that may change environ and may run concurrently with user code in ZTS
is expected to use this exclusion API to maintain as much safety as
reasonable. This results in "thread safe" getenv/putenv in Windows and
Unix, however functions that may read the environment without exclusion
still exist, for example:
- setlocale
- mktime
- tzset
The above is not an exhaustive list of such functions, while getenv/putenv
will behave as if they are safe, care should still be taken in
multi-threaded environments.
s. Correct support for typed properties requires the use of new macros to
assign values to references. For more information see
https://wiki.php.net/rfc/typed_properties_v2#impact_on_extensions.
t. convert_to_string() and zval_get_string() are now more likely to result in
an exception. For instructions on how to gracefully handle this see
https://wiki.php.net/rfc/tostring_exceptions#extension_guidelines.
u. The typedefs uint and ulong are no longer guaranteed to be available, and
have to be replaced with standard types.
v. Compound assignment opcodes were changed. Instead of ZEND_ASSIGN_ADD (and
others) with 0, ZEND_ASSIGN_DIM, ZEND_ASSIGN_OBJ or
ZEND_ASSIGN_STATIC_PROP in extended value, now we use ZEND_ASSIGN_OP,
ZEND_ASSIGN_DIM_OP, ZEND_ASSIGN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP with
ZEND_ADD (or other) in extended_value.
w. APACHE symbol has been removed and is no longer defined.
x. php_error_docref0() has been removed and renamed to php_error_docref().
y. The read and write operations of php_stream_ops now return ssize_t, with
negative values indicating an error.
========================
2. Build system changes
========================
a. Abstract
1. Symbol HAVE_HASH_EXT is removed and is no longer defined. It should be
considered to have hash extension always available since PHP 7.4.
2. Symbol HAVE_PCRE is removed and is no longer defined. It should be
considered to have pcre extension always available since PHP 7.4.
3. Symbol HAVE_LOCALE_H has been removed and is no longer defined.
4. --disable-inline-optimization (which actually disabled all compiler
optimizations) has been removed. If you wish to build PHP on a host
with extremely constrained memory, and compilation fails with an "out
of memory" message, add "-O0" to CFLAGS.
5. build system and provider are displayed in phpinfo from environment:
- PHP_BUILD_SYSTEM (default is same as PHP_UNAME)
- PHP_BUILD_PROVIDER (no default)
- The hash extension is now always available, meaning the --enable-hash
configure argument has been removed.
- The filter extension no longer exposes the --with-pcre-dir configure
argument and therefore allows shared builds with ./configure for Unix
builds.
- Symbols HAVE_DATE, HAVE_REFLECTION, and HAVE_SPL have been removed. It
should be considered to have these extensions always available.
- Removed unused build time symbols: PHP_ADA_INCLUDE, PHP_ADA_LFLAGS,
PHP_ADA_LIBS, PHP_APACHE_INCLUDE, PHP_APACHE_TARGET, PHP_FHTTPD_INCLUDE,
PHP_FHTTPD_LIB, PHP_FHTTPD_TARGET, PHP_CFLAGS, PHP_DBASE_LIB,
PHP_BUILD_DEBUG, PHP_GDBM_INCLUDE, PHP_IBASE_INCLUDE, PHP_IBASE_LFLAGS,
PHP_IBASE_LIBS, PHP_IFX_INCLUDE, PHP_IFX_LFLAGS, PHP_IFX_LIBS,
PHP_INSTALL_IT, PHP_IODBC_INCLUDE, PHP_IODBC_LFLAGS, PHP_IODBC_LIBS,
PHP_MSQL_LFLAGS, PHP_MSQL_INCLUDE, PHP_MSQL_LFLAGS, PHP_MSQL_LIBS,
PHP_MYSQL_INCLUDE, PHP_MYSQL_LIBS, PHP_MYSQL_TYPE, PHP_OCI8_SHARED_LIBADD,
PHP_ORACLE_SHARED_LIBADD, PHP_ORACLE_DIR, PHP_ORACLE_VERSION,
PHP_PGSQL_INCLUDE, PHP_PGSQL_LFLAGS, PHP_PGSQL_LIBS, PHP_SOLID_INCLUDE,
PHP_SOLID_LIBS, PHP_EMPRESS_INCLUDE, PHP_EMPRESS_LIBS, PHP_SYBASE_INCLUDE,
PHP_SYBASE_LFLAGS, PHP_SYBASE_LIBS, PHP_DBM_TYPE, PHP_DBM_LIB,
PHP_LDAP_LFLAGS, PHP_LDAP_INCLUDE, PHP_LDAP_LIBS.
- Removed unused symbols: HAVE_CURL_EASY_STRERROR, HAVE_CURL_MULTI_STRERROR,
HAVE_MPIR, HAVE_MBSTR_CN, HAVE_MBSTR_JA, HAVE_MBSTR_KR, HAVE_MBSTR_RU,
HAVE_MBSTR_TW.
b. Unix build system changes
1. --enable-maintainer-zts is renamed --enable-zts for parity with Windows
and as recognition that ZTS is not a "maintainer" or experimental
feature.
2. The PHP_CHECK_GCC_ARG() m4 macro has been removed in favor of
AX_CHECK_COMPILE_FLAG().
3. The 6th argument of PHP_ADD_SOURCES_X has been removed.
4. The 'special-flags' (3rd) argument of PHP_ADD_SOURCES_X are
now appended instead of prepended to previous compiler flags.
This means compiler flags passed to PHP_NEW_EXTENSION and PHP_ADD_SOURCES
are now appended, this allows to disable compiler flags set by Zend/Zend.m4
(e.g. disable certain compiler flags enabled by -Wextra)
- Added --ini-path and --ini-dir options to php-config.
- configure --help now also outputs --program-suffix and --program-prefix
information by using the Autoconf AC_ARG_PROGRAM macro.
- Obsolescent macros AC_FUNC_VPRINTF and AC_FUNC_UTIME_NULL have been
removed. Symbols HAVE_VPRINTF and HAVE_UTIME_NULL are no longer defined
since they are not needed on the current systems.
- Local PHP m4 unused or obsolete macros have been removed:
PHP_TARGET_RDYNAMIC, PHP_SOLARIS_PIC_WEIRDNESS, PHP_SYS_LFS,
PHP_AC_BROKEN_SPRINTF, PHP_EXTENSION, PHP_DECLARED_TIMEZONE,
PHP_CHECK_TYPES, PHP_CHECK_64BIT, PHP_READDIR_R_TYPE,
PHP_SETUP_KERBEROS.
- Local PHP_TM_GMTOFF m4 macro replaced with Autoconf's AC_CHECK_MEMBERS.
The HAVE_TM_GMTOFF symbol is replaced with HAVE_STRUCT_TM_TM_GMTOFF and
HAVE_TM_ZONE symbol is replaced with HAVE_STRUCT_TM_TM_ZONE.
- new --enable-rtld-now build option allow to switch dlopen behavior
from RTLD_LAZY to RTLD_NOW
- Minimum Bison version is 3.0+ for generating parser files.
- PHP_PROG_BISON macro now takes two optional arguments - minimum required
version and excluded versions that aren't supported.
- PHP_PROG_RE2C is not called in the generated configure.ac for extensions
anymore and now takes one optional argument - minimum required version.
- with-pcre-valgrind and with-valgrind are merged, and valgrind detected by
pkgconfig
- Removed unused AC_PROG_CC_C_O check and the NO_MINUS_C_MINUS_O symbol.
- Obsolescant checks for headers and functions that are part of C89 have
been removed. The following symbols are therefore no longer defined by the
PHP build system at the configure step and shouldn't be used anymore:
HAVE_SETLOCALE, HAVE_LOCALECONV, HAVE_STRSTR, HAVE_STRTOL, HAVE_STRBRK,
HAVE_PERROR, HAVE_STRFTIME, HAVE_TZNAME, HAVE_STDARG_H, HAVE_STRING_H,
HAVE_STDLIB_H, HAVE_SYS_VARARGS_H, HAVE_ASSERT_H, HAVE_SYS_DIR_H,
TM_IN_SYS_TIME, HAVE_STRTOD, HAVE_STRCOLL, HAVE_ERRNO_H, HAVE_MEMCPY,
HAVE_SNPRINTF, HAVE_STDIO_H, HAVE_STRPBRK, HAVE_TIME_H, HAVE_LIMITS_H,
HAVE_STRTOUL, HAVE_SYS_NDIR_H, HAVE_SYS_TIMES_H, PHP_HAVE_STDINT_TYPES,
HAVE_SIGNAL_H, HAVE_STRERROR.
- Removed unused check for dev/arandom and the HAVE_DEV_ARANDOM symbol.
- Remove unused functions checks: HAVE_MBSINIT, HAVE_MEMPCPY, HAVE_SETPGID,
HAVE_STRPNCPY, HAVE_STRTOULL, HAVE_VSNPRINTF, HAVE_CUSERID, HAVE_LRAND48,
HAVE_RANDOM, HAVE_SRAND48, HAVE_SRANDOM, HAVE_STRDUP, HAVE_GCVT,
HAVE_ISASCII, HAVE_LINK, HAVE_LOCKF, HAVE_SOCKOPT, HAVE_SETVBUF, HAVE_SIN,
HAVE_TEMPNAM.
- Unused check for struct cmsghdr and symbol HAVE_CMSGHDR have been removed.
- Unused ApplicationServices/ApplicationServices.h headers check and
HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H symbol have been removed.
- PHP_DEBUG_MACRO macro has been removed.
- PHP_CHECK_CONFIGURE_OPTIONS macro has been removed. Default Autoconf's
--enable-option-checking=fatal option can be used in the configure step
to enable error when invalid options are used.
- Removed unused check and symbols HAVE_SHM_MMAP_ZERO, HAVE_SHM_MMAP_FILE.
- Removed unused check and symbol MISSING_MSGHDR_MSGFLAGS.
c. Windows build system changes
- The configuration option --enable-crt-debug has been removed. The VC
debug heap can now be enabled for debug builds by setting the environment
variable PHP_WIN32_DEBUG_HEAP to a non-negative number before PHP process
startup.
. Visual Studio 2019 is utilized for the Windows builds
. Removed unused defined symbol HAVE_LIBBIND.
========================
3. Module changes
========================
a. ext/xml
- The public (internal) API of the ext/xml extension has been removed. All
functions and structures are private to the extension now.
b. ext/hash
- The hash extension is now always available, allowing extensions to rely
on its functionality to be available without compile time checks.
+2 -2
View File
@@ -13,7 +13,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
# Tweak zendparse to be exported through ZEND_API. This has to be revisited once
# bison supports foreign skeletons and that bison version is used. Read
# https://git.savannah.gnu.org/cgit/bison.git/tree/data/README.md for more.
@$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_language_parser.y -o $@
@$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
@$(SED) -e 's,^int zendparse\(.*\),ZEND_API int zendparse\1,g' < $@ \
> $@.tmp && \
mv $@.tmp $@
@@ -27,7 +27,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
@$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
+159 -14
View File
@@ -146,7 +146,9 @@ _LT_AC_TRY_DLOPEN_SELF([
])
dnl Checks for library functions.
AC_CHECK_FUNCS(getpid kill sigsetjmp)
AC_CHECK_FUNCS(getpid kill finite sigsetjmp)
AC_CHECK_DECLS([isfinite, isnan, isinf], [], [], [[#include <math.h>]])
ZEND_CHECK_FLOAT_PRECISION
@@ -155,7 +157,6 @@ AC_MSG_CHECKING(whether double cast to long preserves least significant bits)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <limits.h>
#include <stdlib.h>
int main()
{
@@ -190,14 +191,23 @@ dnl LIBZEND_OTHER_CHECKS
dnl
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
AC_ARG_ENABLE([zts],
[AS_HELP_STRING([--enable-zts],
[Enable thread safety])],
[ZEND_ZTS=$enableval],
[ZEND_ZTS=no])
AC_ARG_ENABLE([maintainer-zts],
[AS_HELP_STRING([--enable-maintainer-zts],
[Enable thread safety - for code maintainers only!!])],
[ZEND_MAINTAINER_ZTS=$enableval],
[ZEND_MAINTAINER_ZTS=no])
AC_ARG_ENABLE([inline-optimization],
[AS_HELP_STRING([--disable-inline-optimization],
[If building zend_execute.lo fails, try this switch])],
[ZEND_INLINE_OPTIMIZATION=$enableval],
[ZEND_INLINE_OPTIMIZATION=yes])
AC_MSG_CHECKING(whether to enable thread-safety)
AC_MSG_RESULT($ZEND_ZTS)
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
AC_MSG_CHECKING(whether to enable inline optimization for GCC)
AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
AC_MSG_CHECKING(whether to enable Zend debugging)
AC_MSG_RESULT($ZEND_DEBUG)
@@ -212,19 +222,26 @@ else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
test -n "$GCC" && CFLAGS="-Wall -Wextra -Wno-strict-aliasing -Wno-implicit-fallthrough -Wno-unused-parameter -Wno-sign-compare $CFLAGS"
dnl Check if compiler supports -Wno-clobbered (only GCC)
AX_CHECK_COMPILE_FLAG([-Wno-clobbered], CFLAGS="-Wno-clobbered $CFLAGS", , [-Werror])
test -n "$GCC" && CFLAGS="$CFLAGS -Wall -Wno-strict-aliasing"
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
if test "$ZEND_ZTS" = "yes"; then
if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
AC_DEFINE(ZTS,1,[ ])
CFLAGS="$CFLAGS -DZTS"
fi
changequote({,})
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
else
INLINE_CFLAGS="$CFLAGS"
fi
changequote([,])
AC_C_INLINE
AC_SUBST(INLINE_CFLAGS)
AC_MSG_CHECKING(target system is Darwin)
if echo "$target" | grep "darwin" > /dev/null; then
AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
@@ -239,7 +256,6 @@ AC_MSG_CHECKING(for MM alignment and log values)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
typedef union _mm_align_test {
void *ptr;
@@ -369,6 +385,135 @@ else
fi
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
dnl Check if atof() accepts NAN.
AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#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 Check if atof() accepts INF.
AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#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 Check if HUGE_VAL == INF.
AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#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 Check if HUGE_VAL + -HUGEVAL == NAN.
AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#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
dnl Check whether __cpuid_count is available.
AC_CACHE_CHECK(whether __cpuid_count is available, ac_cv_cpuid_count_available, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+16 -19
View File
@@ -4,59 +4,56 @@ func_num_args() tests
<?php
function test1() {
var_dump(func_num_args());
var_dump(func_num_args());
}
function test2($a) {
var_dump(func_num_args());
var_dump(func_num_args());
}
function test3($a, $b) {
var_dump(func_num_args());
var_dump(func_num_args());
}
test1();
test2(1);
try {
test2();
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
call_user_func("test3", 1, 2);
class test {
static function test1($a) {
var_dump(func_num_args());
}
static function test1($a) {
var_dump(func_num_args());
}
}
test::test1(1);
try {
func_num_args();
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(func_num_args());
echo "Done\n";
?>
--EXPECTF--
int(0)
int(1)
Exception: Too few arguments to function test2(), 0 passed in %s on line %d and exactly 1 expected
Exception: Too few arguments to function test2(), 0 passed in %s001.php on line 18 and exactly 1 expected
int(2)
int(0)
Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected
Exception: Too few arguments to function test3(), 1 passed in %s001.php on line 27 and exactly 2 expected
int(2)
int(1)
func_num_args() must be called from a function context
Warning: func_num_args(): Called from the global scope - no function context in %s on line %d
int(-1)
Done
+56 -76
View File
@@ -4,118 +4,98 @@ func_get_arg() tests
<?php
function test1() {
try {
var_dump(func_get_arg(-10));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(func_get_arg(-10));
var_dump(func_get_arg(0));
var_dump(func_get_arg(1));
}
function test2($a) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(func_get_arg(0));
var_dump(func_get_arg(1));
}
function test3($a, $b) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(2));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(func_get_arg(0));
var_dump(func_get_arg(1));
var_dump(func_get_arg(2));
}
test1();
test1(10);
test2(1);
try {
test2();
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
call_user_func("test3", 1, 2);
class test {
static function test1($a) {
try {
var_dump(func_get_arg(0));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
}
static function test1($a) {
var_dump(func_get_arg(0));
var_dump(func_get_arg(1));
}
}
test::test1(1);
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(func_get_arg(1));
echo "Done\n";
?>
--EXPECTF--
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
bool(false)
Warning: func_get_arg(): Argument 0 not passed to function in %s on line %d
bool(false)
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
bool(false)
int(10)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
int(1)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Exception: Too few arguments to function test2(), 0 passed in %s002.php on line %d and exactly 1 expected
int(1)
int(2)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected
Warning: func_get_arg(): Argument 2 not passed to function in %s on line %d
bool(false)
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
bool(false)
Warning: func_get_arg(): Argument 0 not passed to function in %s on line %d
bool(false)
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Exception: Too few arguments to function test3(), 1 passed in %s002.php on line %d and exactly 2 expected
int(1)
int(2)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
Warning: func_get_arg(): Argument 2 not passed to function in %s on line %d
bool(false)
int(1)
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
func_get_arg() cannot be called from the global scope
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Warning: func_get_arg(): Called from the global scope - no function context in %s on line %d
bool(false)
Done
+16 -17
View File
@@ -4,49 +4,45 @@ func_get_args() tests
<?php
function test1() {
var_dump(func_get_args());
var_dump(func_get_args());
}
function test2($a) {
var_dump(func_get_args());
var_dump(func_get_args());
}
function test3($a, $b) {
var_dump(func_get_args());
var_dump(func_get_args());
}
test1();
test1(10);
test2(1);
try {
test2();
test2();
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
test3(1,2);
call_user_func("test1");
try {
call_user_func("test3", 1);
call_user_func("test3", 1);
} catch (Throwable $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "Exception: " . $e->getMessage() . "\n";
}
call_user_func("test3", 1, 2);
class test {
static function test1($a) {
var_dump(func_get_args());
}
static function test1($a) {
var_dump(func_get_args());
}
}
test::test1(1);
var_dump(func_get_args());
try {
var_dump(func_get_args());
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
echo "Done\n";
?>
--EXPECTF--
array(0) {
@@ -79,4 +75,7 @@ array(1) {
[0]=>
int(1)
}
func_get_args() cannot be called from the global scope
Warning: func_get_args(): Called from the global scope - no function context in %s on line %d
bool(false)
Done
+10 -7
View File
@@ -3,20 +3,23 @@ strncmp() tests
--FILE--
<?php
var_dump(strncmp("", ""));
var_dump(strncmp("", "", 100));
try {
var_dump(strncmp("aef", "dfsgbdf", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(strncmp("aef", "dfsgbdf", -1));
var_dump(strncmp("fghjkl", "qwer", 0));
var_dump(strncmp("qwerty", "qwerty123", 6));
var_dump(strncmp("qwerty", "qwerty123", 7));
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Warning: strncmp() expects exactly 3 parameters, 2 given in %s on line %d
NULL
int(0)
strncmp(): Argument #3 ($length) must be greater than or equal to 0
Warning: Length must be greater than or equal to 0 in %s on line %d
bool(false)
int(0)
int(0)
int(-1)
Done
+4 -1
View File
@@ -3,6 +3,7 @@ strcasecmp() tests
--FILE--
<?php
var_dump(strcasecmp(""));
var_dump(strcasecmp("", ""));
var_dump(strcasecmp("aef", "dfsgbdf"));
var_dump(strcasecmp("qwe", "qwer"));
@@ -13,7 +14,9 @@ var_dump(strcasecmp("01", "01"));
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Warning: strcasecmp() expects exactly 2 parameters, 1 given in %s on line %d
NULL
int(0)
int(-3)
int(-1)
+10 -8
View File
@@ -3,12 +3,8 @@ strncasecmp() tests
--FILE--
<?php
try {
var_dump(strncasecmp("", "", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(strncasecmp(""));
var_dump(strncasecmp("", "", -1));
var_dump(strncasecmp("aef", "dfsgbdf", 0));
var_dump(strncasecmp("aef", "dfsgbdf", 10));
var_dump(strncasecmp("qwe", "qwer", 3));
@@ -17,9 +13,14 @@ var_dump(strncasecmp("qwErtY", "qwer", 7));
var_dump(strncasecmp("q123", "Q123", 3));
var_dump(strncasecmp("01", "01", 1000));
echo "Done\n";
?>
--EXPECT--
strncasecmp(): Argument #3 ($length) must be greater than or equal to 0
--EXPECTF--
Warning: strncasecmp() expects exactly 3 parameters, 1 given in %s on line %d
NULL
Warning: Length must be greater than or equal to 0 in %s on line %d
bool(false)
int(0)
int(-3)
int(0)
@@ -27,3 +28,4 @@ int(0)
int(2)
int(0)
int(0)
Done
+65
View File
@@ -0,0 +1,65 @@
--TEST--
each() tests
--FILE--
<?php
var_dump(each());
$var = 1;
var_dump(each($var));
$var = "string";
var_dump(each($var));
$var = array(1,2,3);
var_dump(each($var));
$var = array("a"=>1,"b"=>2,"c"=>3);
var_dump(each($var));
$a = array(1);
$a [] =&$a[0];
var_dump(each($a));
echo "Done\n";
?>
--EXPECTF--
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
Warning: Variable passed to each() is not an array or object in %s on line %d
NULL
array(4) {
[1]=>
int(1)
["value"]=>
int(1)
[0]=>
int(0)
["key"]=>
int(0)
}
array(4) {
[1]=>
int(1)
["value"]=>
int(1)
[0]=>
string(1) "a"
["key"]=>
string(1) "a"
}
array(4) {
[1]=>
int(1)
["value"]=>
int(1)
[0]=>
int(0)
["key"]=>
int(0)
}
Done
+20 -16
View File
@@ -3,25 +3,19 @@ define() tests
--FILE--
<?php
try {
var_dump(define(array(1,2,3,4,5), 1));
} catch (TypeError $e) {
echo "TypeError: ", $e->getMessage(), "\n";
}
var_dump(define());
var_dump(define("TRUE"));
var_dump(define("TRUE", 1));
var_dump(define("TRUE", 1, array(1)));
var_dump(define(array(1,2,3,4,5), 1));
var_dump(define(" ", 1));
var_dump(define("[[[", 2));
var_dump(define("test const", 3));
var_dump(define("test const", 3));
var_dump(define("test", array(1)));
var_dump(define("test1", fopen(__FILE__, 'r')));
try {
var_dump(define("test2", new stdclass));
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(constant(" "));
var_dump(constant("[[["));
@@ -30,19 +24,29 @@ var_dump(constant("test const"));
echo "Done\n";
?>
--EXPECTF--
TypeError: define(): Argument #1 ($constant_name) must be of type string, array given
Warning: define() expects at least 2 parameters, 0 given in %s on line %d
NULL
Warning: Constant TRUE already defined in %s on line %d
bool(false)
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
NULL
Warning: define() expects parameter 1 to be string, array given in %s on line %d
NULL
bool(true)
bool(true)
bool(true)
Warning: Constant test const already defined in %s on line %d
Notice: Constant test const already defined in %s on line %d
bool(false)
bool(true)
bool(true)
define(): Argument #2 ($value) cannot be an object, stdClass given
Warning: Constants may only evaluate to scalar values, arrays or resources in %s on line %d
bool(false)
int(1)
int(2)
int(3)
+24 -22
View File
@@ -4,38 +4,29 @@ get_class() tests
<?php
class foo {
function bar () {
var_dump(get_class());
}
function bar () {
var_dump(get_class());
}
function testNull ()
{
try {
var_dump(get_class(null));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
var_dump(get_class(null));
}
}
class foo2 extends foo {
}
foo::bar();
foo2::bar();
$f1 = new foo;
$f2 = new foo2;
$f1->bar();
$f2->bar();
try {
var_dump(get_class());
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(get_class("qwerty"));
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
var_dump(get_class());
var_dump(get_class("qwerty"));
var_dump(get_class($f1));
var_dump(get_class($f2));
@@ -44,12 +35,23 @@ $f1->testNull();
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Deprecated: Non-static method foo::bar() should not be called statically in %s on line %d
string(3) "foo"
Deprecated: Non-static method foo::bar() should not be called statically in %s on line %d
string(3) "foo"
string(3) "foo"
get_class() without arguments must be called from within a class
get_class(): Argument #1 ($object) must be of type object, string given
string(3) "foo"
Warning: get_class() called without object from outside a class in %s on line %d
bool(false)
Warning: get_class() expects parameter 1 to be object, string given in %s on line %d
bool(false)
string(3) "foo"
string(4) "foo2"
get_class(): Argument #1 ($object) must be of type object, null given
Warning: get_class() expects parameter 1 to be object, null given in %s on line %d
bool(false)
Done
+17 -42
View File
@@ -4,19 +4,19 @@ get_parent_class() tests
<?php
interface i {
function test();
function test();
}
class foo implements i {
function test() {
var_dump(get_parent_class());
}
function test() {
var_dump(get_parent_class());
}
}
class bar extends foo {
function test_bar() {
var_dump(get_parent_class());
}
function test_bar() {
var_dump(get_parent_class());
}
}
$bar = new bar;
@@ -32,37 +32,12 @@ var_dump(get_parent_class("bar"));
var_dump(get_parent_class("foo"));
var_dump(get_parent_class("i"));
try {
get_parent_class("");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class("[[[[");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class(" ");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(get_parent_class(""));
var_dump(get_parent_class("[[[["));
var_dump(get_parent_class(" "));
var_dump(get_parent_class(new stdclass));
try {
get_parent_class(array());
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
try {
get_parent_class(1);
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}
var_dump(get_parent_class(array()));
var_dump(get_parent_class(1));
echo "Done\n";
?>
@@ -75,10 +50,10 @@ bool(false)
string(3) "foo"
bool(false)
bool(false)
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, string given
bool(false)
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, array given
get_parent_class(): Argument #1 ($object_or_class) must be an object or a valid class name, int given
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
Done
+35 -45
View File
@@ -4,25 +4,27 @@ property_exists() tests
<?php
class foo {
public $pp1 = 1;
private $pp2 = 2;
protected $pp3 = 3;
public $pp1 = 1;
private $pp2 = 2;
protected $pp3 = 3;
function bar() {
var_dump(property_exists("foo","pp1"));
var_dump(property_exists("foo","pp2"));
var_dump(property_exists("foo","pp3"));
}
function bar() {
var_dump(property_exists("foo","pp1"));
var_dump(property_exists("foo","pp2"));
var_dump(property_exists("foo","pp3"));
}
}
class bar extends foo {
function test() {
var_dump(property_exists("foo","pp1"));
var_dump(property_exists("foo","pp2"));
var_dump(property_exists("foo","pp3"));
}
function test() {
var_dump(property_exists("foo","pp1"));
var_dump(property_exists("foo","pp2"));
var_dump(property_exists("foo","pp3"));
}
}
var_dump(property_exists());
var_dump(property_exists(""));
var_dump(property_exists("foo","pp1"));
var_dump(property_exists("foo","pp2"));
var_dump(property_exists("foo","pp3"));
@@ -39,40 +41,23 @@ var_dump(property_exists($foo,"pp2"));
var_dump(property_exists($foo,"pp3"));
var_dump(property_exists($foo,"nonexistent"));
var_dump(property_exists($foo,""));
try {
var_dump(property_exists(array(), "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(1, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(3.14, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(true, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(property_exists(null, "test"));
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(property_exists(array(),"test"));
var_dump(property_exists(1,"test"));
var_dump(property_exists(true,"test"));
$foo->bar();
$bar = new bar;
$bar->test();
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Warning: property_exists() expects exactly 2 parameters, 0 given in %s on line %d
NULL
Warning: property_exists() expects exactly 2 parameters, 1 given in %s on line %d
NULL
bool(true)
bool(true)
bool(true)
@@ -86,14 +71,19 @@ bool(true)
bool(true)
bool(false)
bool(false)
property_exists(): Argument #1 ($object_or_class) must be of type object|string, array given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, int given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, float given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, bool given
property_exists(): Argument #1 ($object_or_class) must be of type object|string, null given
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
NULL
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
NULL
Warning: First parameter must either be an object or the name of an existing class in %s on line %d
NULL
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
Done
+8 -1
View File
@@ -6,8 +6,10 @@ class_exists() tests
class foo {
}
var_dump(class_exists());
var_dump(class_exists("qwerty"));
var_dump(class_exists(""));
var_dump(class_exists(array()));
var_dump(class_exists("test", false));
var_dump(class_exists("foo", false));
var_dump(class_exists("foo"));
@@ -16,9 +18,14 @@ var_dump(class_exists("stdClass"));
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Warning: class_exists() expects at least 1 parameter, 0 given in %s on line %d
NULL
bool(false)
bool(false)
Warning: class_exists() expects parameter 1 to be string, array given in %s on line %d
NULL
bool(false)
bool(true)
bool(true)
+8 -1
View File
@@ -6,8 +6,10 @@ interface_exists() tests
interface foo {
}
var_dump(interface_exists());
var_dump(interface_exists("qwerty"));
var_dump(interface_exists(""));
var_dump(interface_exists(array()));
var_dump(interface_exists("test", false));
var_dump(interface_exists("foo", false));
var_dump(interface_exists("foo"));
@@ -16,9 +18,14 @@ var_dump(interface_exists("stdClass"));
echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Warning: interface_exists() expects at least 1 parameter, 0 given in %s on line %d
NULL
bool(false)
bool(false)
Warning: interface_exists() expects parameter 1 to be string, array given in %s on line %d
NULL
bool(false)
bool(true)
bool(true)
+10
View File
@@ -8,9 +8,13 @@ var_dump(get_included_files());
include(__DIR__."/014.inc");
var_dump(get_included_files());
var_dump(get_included_files(1,1));
include_once(__DIR__."/014.inc");
var_dump(get_included_files());
var_dump(get_included_files(1));
include(__DIR__."/014.inc");
var_dump(get_included_files());
@@ -27,12 +31,18 @@ array(2) {
[1]=>
string(%d) "%s"
}
Warning: get_included_files() expects exactly 0 parameters, 2 given in %s on line %d
NULL
array(2) {
[0]=>
string(%d) "%s"
[1]=>
string(%d) "%s"
}
Warning: get_included_files() expects exactly 0 parameters, 1 given in %s on line %d
NULL
array(2) {
[0]=>
string(%d) "%s"
+18 -14
View File
@@ -3,31 +3,35 @@ trigger_error() tests
--FILE--
<?php
var_dump(trigger_error());
var_dump(trigger_error("error"));
try {
var_dump(trigger_error("error", -1));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(trigger_error("error", 0));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(trigger_error(array()));
var_dump(trigger_error("error", -1));
var_dump(trigger_error("error", 0));
var_dump(trigger_error("error", E_USER_WARNING));
var_dump(trigger_error("error", E_USER_DEPRECATED));
echo "Done\n";
?>
--EXPECTF--
Warning: trigger_error() expects at least 1 parameter, 0 given in %s on line %d
NULL
Notice: error in %s on line %d
bool(true)
trigger_error(): Argument #2 ($error_level) must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, or E_USER_DEPRECATED
trigger_error(): Argument #2 ($error_level) must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, or E_USER_DEPRECATED
Warning: trigger_error() expects parameter 1 to be string, array given in %s on line %d
NULL
Warning: Invalid error type specified in %s on line %d
bool(false)
Warning: Invalid error type specified in %s on line %d
bool(false)
Warning: error in %s on line %d
bool(true)
Deprecated: error in %s on line %d
bool(true)
Done
+23
View File
@@ -3,6 +3,8 @@ builtin functions tests
--FILE--
<?php
var_dump(get_resource_type());
var_dump(get_resource_type(""));
$fp = fopen(__FILE__, "r");
var_dump(get_resource_type($fp));
fclose($fp);
@@ -12,9 +14,11 @@ var_dump(gettype(get_loaded_extensions()));
var_dump(count(get_loaded_extensions()));
var_dump(gettype(get_loaded_extensions(true)));
var_dump(count(get_loaded_extensions(true)));
var_dump(get_loaded_extensions(true, true));
define("USER_CONSTANT", "test");
var_dump(get_defined_constants(true, true));
var_dump(gettype(get_defined_constants(true)));
var_dump(gettype(get_defined_constants()));
var_dump(count(get_defined_constants()));
@@ -25,9 +29,11 @@ function test () {
var_dump(gettype(get_defined_functions()));
var_dump(count(get_defined_functions()));
var_dump(get_declared_interfaces(true));
var_dump(gettype(get_declared_interfaces()));
var_dump(count(get_declared_interfaces()));
var_dump(get_extension_funcs());
var_dump(get_extension_funcs(true));
var_dump(gettype(get_extension_funcs("standard")));
var_dump(count(get_extension_funcs("standard")));
@@ -38,19 +44,36 @@ var_dump(count(get_extension_funcs("zend")));
echo "Done\n";
?>
--EXPECTF--
Warning: get_resource_type() expects exactly 1 parameter, 0 given in %s on line %d
NULL
Warning: get_resource_type() expects parameter 1 to be resource, string given in %s on line %d
NULL
string(6) "stream"
string(7) "Unknown"
string(5) "array"
int(%d)
string(5) "array"
int(%d)
Warning: get_loaded_extensions() expects at most 1 parameter, 2 given in %s on line %d
NULL
Warning: get_defined_constants() expects at most 1 parameter, 2 given in %s on line %d
NULL
string(5) "array"
string(5) "array"
int(%d)
string(5) "array"
int(%d)
Warning: get_declared_interfaces() expects exactly 0 parameters, 1 given in %s on line %d
NULL
string(5) "array"
int(%d)
Warning: get_extension_funcs() expects exactly 1 parameter, 0 given in %s on line %d
NULL
bool(false)
string(5) "array"
int(%d)
+17 -7
View File
@@ -3,11 +3,11 @@ constant() tests
--FILE--
<?php
try {
var_dump(constant(""));
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump(constant());
var_dump(constant("", ""));
var_dump(constant(""));
var_dump(constant(array()));
define("TEST_CONST", 1);
var_dump(constant("TEST_CONST"));
@@ -17,8 +17,18 @@ var_dump(constant("TEST_CONST2"));
echo "Done\n";
?>
--EXPECT--
Undefined constant ""
--EXPECTF--
Warning: constant() expects exactly 1 parameter, 0 given in %s on line %d
NULL
Warning: constant() expects exactly 1 parameter, 2 given in %s on line %d
NULL
Warning: constant(): Couldn't find constant in %s on line %d
NULL
Warning: constant() expects parameter 1 to be string, array given in %s on line %d
NULL
int(1)
string(4) "test"
Done
+121 -109
View File
@@ -2,6 +2,16 @@
Test unset(), empty() and isset() functions
--FILE--
<?php
/* Prototype: void unset ( mixed $var [, mixed $var [, mixed $...]] );
Description: unset() destroys the specified variables
Prototype: bool empty( mixed $var );
Description: Determine whether a variable is considered to be empty
Prototype: bool isset ( mixed $var [, mixed $var [, $...]] );
Description: Returns TRUE if var exists; FALSE otherwise
*/
echo "*** Testing unset(), empty() & isset() with scalar variables ***\n";
// testing scalar variables
@@ -233,7 +243,7 @@ var_dump( empty($point1->x) ); // expected: bool(true)
// unset all members and check
unset($point1->y);
unset($point1->lable);
// dump the object to check that all variables are unset
// dump the objec to check that all variables are unset
var_dump($point1);
var_dump( isset($point1) ); // expected: bool(ture)
var_dump( empty($point1) ); // expected: bool(false)
@@ -350,6 +360,7 @@ var_dump($global_var);
//Note: No error conditions relating to passing arguments can be tested
// because these are not functions but statements, it will result in syntax error.
?>
===DONE===
--EXPECTF--
*** Testing unset(), empty() & isset() with scalar variables ***
-- Iteration 1 --
@@ -357,7 +368,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -369,7 +380,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -381,7 +392,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -393,7 +404,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -405,7 +416,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -417,7 +428,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -429,7 +440,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -441,7 +452,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -453,7 +464,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -465,7 +476,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -477,7 +488,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -489,7 +500,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -501,7 +512,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -513,7 +524,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -525,7 +536,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -537,7 +548,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -549,7 +560,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -561,7 +572,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -573,7 +584,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -585,7 +596,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -597,7 +608,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -609,7 +620,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -621,7 +632,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -633,7 +644,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -645,7 +656,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -657,7 +668,7 @@ bool(true)
bool(true)
bool(false)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -669,7 +680,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $scalar_var in %s on line %d
Notice: Undefined variable: scalar_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -686,7 +697,7 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -702,18 +713,18 @@ bool(true)
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -729,18 +740,18 @@ bool(true)
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -756,18 +767,18 @@ bool(true)
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -783,18 +794,18 @@ bool(true)
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -816,13 +827,13 @@ array(3) {
int(4)
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(3) {
[1]=>
@@ -840,13 +851,13 @@ array(2) {
int(4)
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(2) {
[2]=>
@@ -860,13 +871,13 @@ array(1) {
int(4)
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(1) {
[3]=>
@@ -876,18 +887,18 @@ array(1) {
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -907,13 +918,13 @@ array(2) {
float(5.6)
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(2) {
[1]=>
@@ -927,13 +938,13 @@ array(1) {
float(5.6)
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(1) {
[2]=>
@@ -943,18 +954,18 @@ array(1) {
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -972,13 +983,13 @@ array(1) {
string(3) "two"
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(1) {
[2]=>
@@ -988,18 +999,18 @@ array(1) {
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -1017,13 +1028,13 @@ array(1) {
string(2) "30"
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(1) {
["Age"]=>
@@ -1033,18 +1044,18 @@ array(1) {
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -1068,13 +1079,13 @@ array(4) {
string(0) ""
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(4) {
[1]=>
@@ -1096,13 +1107,13 @@ array(3) {
string(0) ""
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(3) {
["One"]=>
@@ -1120,13 +1131,13 @@ array(2) {
string(0) ""
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(2) {
[2]=>
@@ -1140,13 +1151,13 @@ array(1) {
string(0) ""
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(1) {
[""]=>
@@ -1156,18 +1167,18 @@ array(1) {
array(0) {
}
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(false)
Warning: Undefined variable $key_val in %s on line %d
Notice: Undefined variable: key_val in %s on line %d
bool(true)
array(0) {
}
Warning: Undefined variable $array_var in %s on line %d
Notice: Undefined variable: array_var in %s on line %d
NULL
bool(false)
bool(false)
@@ -1185,7 +1196,7 @@ bool(true)
bool(false)
bool(false)
Warning: Undefined variable $resource in %s on line %d
Notice: Undefined variable: resource in %s on line %d
NULL
-- Iteration 2 --
resource(%d) of type (stream)
@@ -1198,10 +1209,10 @@ bool(true)
bool(false)
bool(false)
Warning: Undefined variable $resource in %s on line %d
Notice: Undefined variable: resource in %s on line %d
NULL
Warning: Undefined variable $resources in %s on line %d
Notice: Undefined variable: resources in %s on line %d
NULL
bool(false)
bool(true)
@@ -1218,16 +1229,16 @@ object(Point)#%d (3) {
bool(true)
bool(false)
Warning: Undefined variable $lable in %s on line %d
Notice: Undefined variable: lable in %s on line %d
bool(false)
Warning: Undefined variable $lable in %s on line %d
Notice: Undefined variable: lable in %s on line %d
bool(true)
Warning: Undefined variable $lable in %s on line %d
Notice: Undefined variable: lable in %s on line %d
bool(false)
Warning: Undefined variable $lable in %s on line %d
Notice: Undefined variable: lable in %s on line %d
bool(true)
object(Point)#%d (3) {
["x"]=>
@@ -1252,7 +1263,7 @@ bool(false)
bool(false)
bool(true)
Warning: Undefined variable $point1 in %s on line %d
Notice: Undefined variable: point1 in %s on line %d
NULL
bool(false)
bool(true)
@@ -1282,7 +1293,7 @@ value of static_var before unset: 1
bool(true)
bool(false)
Warning: Undefined variable $static_var in %s on line %d
Notice: Undefined variable: static_var in %s on line %d
value of static_var after unset:
bool(false)
bool(true)
@@ -1291,7 +1302,7 @@ value of static_var before unset: 2
bool(true)
bool(false)
Warning: Undefined variable $static_var in %s on line %d
Notice: Undefined variable: static_var in %s on line %d
value of static_var after unset:
bool(false)
bool(true)
@@ -1300,7 +1311,7 @@ value of static_var before unset: 3
bool(true)
bool(false)
Warning: Undefined variable $static_var in %s on line %d
Notice: Undefined variable: static_var in %s on line %d
value of static_var after unset:
bool(false)
bool(true)
@@ -1319,3 +1330,4 @@ bool(false)
bool(false)
bool(true)
int(10)
===DONE===
+20 -15
View File
@@ -3,27 +3,32 @@ func_get_arg() invalid usage
--FILE--
<?php
try {
var_dump(func_get_arg(1));
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump(func_get_arg(1,2,3));
var_dump(func_get_arg(1));
var_dump(func_get_arg());
function bar() {
var_dump(func_get_arg(1));
var_dump(func_get_arg(1));
}
function foo() {
bar(func_get_arg(1));
bar(func_get_arg(1));
}
try {
foo(1,2);
} catch (\Error $e) {
echo $e->getMessage() . \PHP_EOL;
}
foo(1,2);
echo "Done\n";
?>
--EXPECT--
func_get_arg() cannot be called from the global scope
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
--EXPECTF--
Warning: func_get_arg() expects exactly 1 parameter, 3 given in %s on line %d
NULL
Warning: func_get_arg(): Called from the global scope - no function context in %s on line %d
bool(false)
Warning: func_get_arg() expects exactly 1 parameter, 0 given in %s on line %d
NULL
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Done
+6 -7
View File
@@ -1,25 +1,24 @@
--TEST--
Implementing abstracting methods and optional parameters
Implementating abstracting methods and optional parameters
--FILE--
<?php
abstract class Base
{
abstract function someMethod($param);
abstract function someMethod($param);
}
class Ext extends Base
{
function someMethod($param = "default")
{
echo $param, "\n";
}
function someMethod($param = "default")
{
echo $param, "\n";
}
}
$a = new Ext();
$a->someMethod("foo");
$a->someMethod();
?>
--EXPECT--
foo
default
+8 -8
View File
@@ -10,20 +10,20 @@ print "\n";
class bar {
public function a() {
return "bar!";
}
public function a() {
return "bar!";
}
}
class foo {
public function test() {
print "foo!\n";
return new bar;
}
public function test() {
print "foo!\n";
return new bar;
}
}
function test() {
return new foo;
return new foo;
}
$a = 'test';
+16 -16
View File
@@ -15,43 +15,43 @@ var_dump($a->$b->{$c[1]});
?>
--EXPECTF--
Warning: Undefined variable $a in %s on line %d
Notice: Undefined variable: a in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
NULL
Warning: Undefined variable $a in %s on line %d
Notice: Undefined variable: a in %s on line %d
Warning: Undefined variable $c in %s on line %d
Notice: Undefined variable: c in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
NULL
Warning: Undefined variable $a in %s on line %d
Notice: Undefined variable: a in %s on line %d
int(1)
Warning: Undefined variable $a in %s on line %d
Notice: Undefined variable: a in %s on line %d
Warning: Undefined variable $b in %s on line %d
Notice: Undefined variable: b in %s on line %d
int(0)
Warning: Undefined variable $a in %s on line %d
Notice: Undefined variable: a in %s on line %d
NULL
Warning: Undefined variable $b in %s on line %d
Notice: Undefined variable: b in %s on line %d
int(1)
Warning: Attempt to read property "1" on int in %s on line %d
Notice: Trying to get property '1' of non-object in %s on line %d
NULL
Warning: Attempt to read property "1" on int in %s on line %d
Notice: Trying to get property '1' of non-object in %s on line %d
NULL
Warning: Undefined variable $c in %s on line %d
Notice: Undefined variable: c in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Attempt to read property "1" on int in %s on line %d
Notice: Trying to get property '1' of non-object in %s on line %d
Warning: Attempt to read property "" on null in %s on line %d
Notice: Trying to get property '' of non-object in %s on line %d
NULL
+3 -3
View File
@@ -4,9 +4,9 @@ Testing dynamic calls
<?php
class foo {
static public function a() {
print "ok\n";
}
static public function a() {
print "ok\n";
}
}
$a = 'a';
+6 -9
View File
@@ -4,8 +4,8 @@ Trying assign value to property when an object is not returned in a function
<?php
class foo {
public function a() {
}
public function a() {
}
}
$test = new foo;
@@ -13,16 +13,13 @@ $test = new foo;
$test->a()->a;
print "ok\n";
try {
$test->a()->a = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
$test->a()->a = 1;
print "ok\n";
?>
--EXPECTF--
Warning: Attempt to read property "a" on null in %s on line %d
Notice: Trying to get property 'a' of non-object in %s on line %d
ok
Attempt to assign property "a" on null
Warning: Creating default object from empty value in %s on line %d
ok
+2 -2
View File
@@ -18,9 +18,9 @@ bool(true)
bool(true)
bool(true)
Warning: Undefined array key 2 in %s on line %d
Notice: Undefined offset: 2 in %s on line %d
Fatal error: Uncaught Error: Value of type null is not callable in %s:%d
Fatal error: Uncaught Error: Function name must be a string in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
+17 -17
View File
@@ -4,26 +4,26 @@ Overriding $this in catch and checking the object properties later.
<?php
class foo {
public $test = 0;
private $test_2 = 1;
protected $test_3 = 2;
public $test = 0;
private $test_2 = 1;
protected $test_3 = 2;
public function bar() {
try {
throw new Exception('foo');
} catch (Exception $this) {
var_dump($this);
}
public function bar() {
try {
throw new Exception('foo');
} catch (Exception $this) {
var_dump($this);
}
$this->baz();
}
$this->baz();
}
public function baz() {
foreach ($this as $k => $v) {
printf("'%s' => '%s'\n", $k, $v);
}
print "ok\n";
}
public function baz() {
foreach ($this as $k => $v) {
printf("'%s' => '%s'\n", $k, $v);
}
print "ok\n";
}
}
$test = new foo;
+25 -31
View File
@@ -9,58 +9,52 @@ echo $arr[1][2][3][4][5];
$arr[1][2][3][4][5]->foo;
try {
$arr[1][2][3][4][5]->foo = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
$arr[1][2][3][4][5]->foo = 1;
$arr[][] = 2;
try {
$arr[][]->bar = 2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
$arr[][]->bar = 2;
?>
--EXPECTF--
Warning: Undefined variable $arr in %s on line %d
Notice: Undefined variable: arr in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Undefined variable $arr in %s on line %d
Notice: Undefined variable: arr in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Undefined variable $arr in %s on line %d
Notice: Undefined variable: arr in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Trying to access array offset on value of type null in %s on line %d
Notice: Trying to access array offset on value of type null in %s on line %d
Warning: Attempt to read property "foo" on null in %s on line %d
Attempt to assign property "foo" on null
Attempt to assign property "bar" on null
Notice: Trying to get property 'foo' of non-object in %s on line %d
Warning: Creating default object from empty value in %s on line %d
Warning: Creating default object from empty value in %s on line %d
+15 -15
View File
@@ -4,21 +4,21 @@ Testing multiples 'default:' in switch
<?php
switch (1) {
case 2:
print 'foo';
break;
case 3:
print 'bar';
break;
default:
print 1;
break;
default:
print 2;
break;
default:
print 3;
break;
case 2:
print 'foo';
break;
case 3:
print 'bar';
break;
default:
print 1;
break;
default:
print 2;
break;
default:
print 3;
break;
}
?>
+9 -7
View File
@@ -3,12 +3,14 @@ Trying to use lambda in array offset
--FILE--
<?php
try {
$test[function(){}] = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
$test[function(){}] = 1;
$a{function() { }} = 1;
?>
--EXPECT--
Illegal offset type
--EXPECTF--
Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
Warning: Illegal offset type in %s on line %d
Warning: Illegal offset type in %s on line %d
+1 -1
View File
@@ -16,7 +16,7 @@ var_dump($x::$x);
--EXPECTF--
int(1)
Fatal error: Uncaught Error: Access to undeclared static property Closure::$x in %s:%d
Fatal error: Uncaught Error: Access to undeclared static property: Closure::$x in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
+5 -7
View File
@@ -3,12 +3,10 @@ Trying to use lambda as array key
--FILE--
<?php
try {
var_dump(array(function() { } => 1));
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump(array(function() { } => 1));
?>
--EXPECT--
Illegal offset type
--EXPECTF--
Warning: Illegal offset type in %s on line %d
array(0) {
}
-63
View File
@@ -1,63 +0,0 @@
--TEST--
Test default value handling of ErrorException::__construct()
--FILE--
<?php
$e = new ErrorException();
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Second", 0, E_ERROR, null);
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Third", 0, E_ERROR, null, null);
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Forth", 0, E_ERROR, null, 123);
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Fifth", 0, E_ERROR, "abc.php");
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Sixth", 0, E_ERROR, "abc.php", null);
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
$e = new ErrorException("Seventh", 0, E_ERROR, "abc.php", 123);
var_dump($e->getMessage());
var_dump($e->getFile());
var_dump($e->getLine());
?>
--EXPECTF--
string(0) ""
string(%d) "%sErrorException_construct.php"
int(3)
string(6) "Second"
string(%d) "%sErrorException_construct.php"
int(8)
string(5) "Third"
string(%d) "%sErrorException_construct.php"
int(13)
string(5) "Forth"
string(%d) "%sErrorException_construct.php"
int(123)
string(5) "Fifth"
string(7) "abc.php"
int(0)
string(5) "Sixth"
string(7) "abc.php"
int(0)
string(7) "Seventh"
string(7) "abc.php"
int(123)
+2 -2
View File
@@ -4,8 +4,8 @@ using multiple access modifiers (methods)
<?php
class test {
static public public static final public final function foo() {
}
static public public static final public final function foo() {
}
}
echo "Done\n";
+1 -1
View File
@@ -4,7 +4,7 @@ using multiple access modifiers (attributes)
<?php
class test {
static public public static final public final $var;
static public public static final public final $var;
}
echo "Done\n";
+1 -1
View File
@@ -4,7 +4,7 @@ using multiple access modifiers (classes)
<?php
final final class test {
function foo() {}
function foo() {}
}
echo "Done\n";
+2 -2
View File
@@ -4,8 +4,8 @@ using multiple access modifiers (abstract methods)
<?php
class test {
abstract abstract function foo() {
}
abstract abstract function foo() {
}
}
echo "Done\n";
+2 -2
View File
@@ -4,8 +4,8 @@ using multiple access modifiers (final methods)
<?php
class test {
final final function foo() {
}
final final function foo() {
}
}
echo "Done\n";
+2 -2
View File
@@ -4,8 +4,8 @@ using multiple access modifiers (static methods)
<?php
class test {
static static function foo() {
}
static static function foo() {
}
}
echo "Done\n";
+1 -1
View File
@@ -4,7 +4,7 @@ abstract final methods errmsg
<?php
class test {
final abstract function foo();
final abstract function foo();
}
echo "Done\n";
+4 -4
View File
@@ -6,16 +6,16 @@ Discussion: http://marc.info/?l=php-internals&m=120221184420957&w=2
<?php
class A {
static protected function f() {return 'A::f()';}
static protected function f() {return 'A::f()';}
}
class B1 extends A {
static protected function f() {return 'B1::f()';}
static protected function f() {return 'B1::f()';}
}
class B2 extends A {
static public function test() {echo B1::f();}
static public function test() {echo B1::f();}
}
B2::test();
?>
--EXPECTF--
Fatal error: Call to protected method B1::f() from scope B2 in %s on line %d
Fatal error: Call to protected method B1::f() from context 'B2' in %s on line %d
+7 -7
View File
@@ -6,16 +6,16 @@ Discussion: http://marc.info/?l=php-internals&m=120221184420957&w=2
<?php
class A {
static protected function f() {return 'A::f()';}
static protected function f() {return 'A::f()';}
}
class B1 extends A {
static protected function f() {return 'B1::f()';}
static protected function f() {return 'B1::f()';}
}
class B2 extends A {
static public function test() {
var_dump(is_callable('B1::f'));
B1::f();
}
static public function test() {
var_dump(is_callable('B1::f'));
B1::f();
}
}
B2::test();
@@ -23,4 +23,4 @@ B2::test();
--EXPECTF--
bool(false)
Fatal error: Call to protected method B1::f() from scope B2 in %s on line %d
Fatal error: Call to protected method B1::f() from context 'B2' in %s on line %d
+10 -10
View File
@@ -4,31 +4,31 @@ Testing visibility of methods
<?php
class d {
private function test2() {
print "Bar\n";
}
private function test2() {
print "Bar\n";
}
}
abstract class a extends d {
public function test() {
$this->test2();
}
public function test() {
$this->test2();
}
}
abstract class b extends a {
}
class c extends b {
public function __construct() {
$this->test();
}
public function __construct() {
$this->test();
}
}
new c;
?>
--EXPECTF--
Fatal error: Uncaught Error: Call to private method d::test2() from scope a in %s:%d
Fatal error: Uncaught Error: Call to private method d::test2() from context 'a' in %s:%d
Stack trace:
#0 %s(%d): a->test()
#1 %s(%d): c->__construct()
+18 -18
View File
@@ -4,25 +4,25 @@ __call() for private/protected methods
<?php
class A {
private $var1 = 'var1 value';
protected $var2 = 'var2 value';
private $var1 = 'var1 value';
protected $var2 = 'var2 value';
private function func1()
{
return "in func1";
}
protected function func2()
{
return "in func2";
}
public function __get($var)
{
return $this->$var;
}
public function __call($func, array $args = array())
{
return call_user_func_array(array($this, $func), $args);
}
private function func1()
{
return "in func1";
}
protected function func2()
{
return "in func2";
}
public function __get($var)
{
return $this->$var;
}
public function __call($func, array $args = array())
{
return call_user_func_array(array($this, $func), $args);
}
}
$a = new A();
+3 -3
View File
@@ -3,9 +3,9 @@ Trigger __call() in lieu of non visible methods when called via a callback.
--FILE--
<?php
class C {
protected function prot() { }
private function priv() { }
public function __call($name, $args) {
protected function prot() { }
private function priv() { }
public function __call($name, $args) {
echo "In __call() for method $name()\n";
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ Prevent abstract and final in the same class declaration
<?php
final abstract class C {
private function priv() { }
private function priv() { }
}
?>
+8 -4
View File
@@ -9,9 +9,9 @@ $o = new stdclass;
$o->prop = "value";
try {
var_dump($a + $o);
var_dump($a + $o);
} catch (Error $e) {
echo "\nException: " . $e->getMessage() . "\n";
echo "\nException: " . $e->getMessage() . "\n";
}
$c = $a + $o;
@@ -20,9 +20,13 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Exception: Unsupported operand types: array + stdClass
Notice: Object of class stdClass could not be converted to number in %sadd_002.php on line %d
Fatal error: Uncaught TypeError: Unsupported operand types: array + stdClass in %s:%d
Exception: Unsupported operand types
Notice: Object of class stdClass could not be converted to number in %s on line %d
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
+8 -4
View File
@@ -9,9 +9,9 @@ $o = new stdclass;
$o->prop = "value";
try {
var_dump($o + $a);
var_dump($o + $a);
} catch (Error $e) {
echo "\nException: " . $e->getMessage() . "\n";
echo "\nException: " . $e->getMessage() . "\n";
}
$c = $o + $a;
@@ -20,9 +20,13 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Exception: Unsupported operand types: stdClass + array
Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d
Fatal error: Uncaught TypeError: Unsupported operand types: stdClass + array in %s:%d
Exception: Unsupported operand types
Notice: Object of class stdClass could not be converted to number in %s on line %d
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
+4 -4
View File
@@ -6,9 +6,9 @@ adding numbers to arrays
$a = array(1,2,3);
try {
var_dump($a + 5);
var_dump($a + 5);
} catch (Error $e) {
echo "\nException: " . $e->getMessage() . "\n";
echo "\nException: " . $e->getMessage() . "\n";
}
$c = $a + 5;
@@ -17,9 +17,9 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Exception: Unsupported operand types: array + int
Exception: Unsupported operand types
Fatal error: Uncaught TypeError: Unsupported operand types: array + int in %s:%d
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
+2 -2
View File
@@ -17,6 +17,6 @@ var_dump($c);
echo "Done\n";
?>
--EXPECT--
float(2834756759.123123)
float(2834756759.123123)
float(2834756759.1231)
float(2834756759.1231)
Done
+11 -15
View File
@@ -11,12 +11,9 @@ $s2 = "876222numeric";
$s3 = "48474874";
$s4 = "25.68";
try {
$c = $i + $s1;
var_dump($c);
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
$c = $i + $s1;
var_dump($c);
$c = $i + $s2;
var_dump($c);
@@ -26,12 +23,8 @@ var_dump($c);
$c = $i + $s4;
var_dump($c);
try {
$c = $s1 + $i;
var_dump($c);
} catch (\TypeError $e) {
echo $e->getMessage() . \PHP_EOL;
}
$c = $s1 + $i;
var_dump($c);
$c = $s2 + $i;
var_dump($c);
@@ -45,15 +38,18 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Unsupported operand types: int + string
Warning: A non-numeric value encountered in %s on line %d
int(75636)
Notice: A non well formed numeric value encountered in %s on line %d
int(951858)
int(48550510)
float(75661.68)
Unsupported operand types: string + int
Warning: A non-numeric value encountered in %s on line %d
int(75636)
Notice: A non well formed numeric value encountered in %s on line %d
int(951858)
int(48550510)
float(75661.68)
+8 -4
View File
@@ -8,9 +8,9 @@ $a = array(1,2,3);
$s1 = "some string";
try {
var_dump($a + $s1);
var_dump($a + $s1);
} catch (Error $e) {
echo "\nException: " . $e->getMessage() . "\n";
echo "\nException: " . $e->getMessage() . "\n";
}
$c = $a + $s1;
@@ -19,9 +19,13 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Exception: Unsupported operand types: array + string
Warning: A non-numeric value encountered in %s on line %d
Fatal error: Uncaught TypeError: Unsupported operand types: array + string in %s:%d
Exception: Unsupported operand types
Warning: A non-numeric value encountered in %s on line %d
Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
@@ -1,9 +0,0 @@
--TEST--
Alternative offset syntax should emit E_COMPILE_ERROR in const expression
--FILE--
<?php
const FOO_COMPILE_ERROR = "BAR"{0};
var_dump(FOO_COMPILE_ERROR);
?>
--EXPECTF--
Fatal error: Array and string offset access syntax with curly braces is no longer supported in %s on line 2
@@ -1,9 +0,0 @@
--TEST--
Alternative offset syntax should emit E_COMPILE_ERROR outside const expression
--FILE--
<?php
$foo = 'BAR';
var_dump($foo{0});
?>
--EXPECTF--
Fatal error: Array and string offset access syntax with curly braces is no longer supported in %s on line 3
-1
View File
@@ -3,7 +3,6 @@ declare bare anonymous class
--FILE--
<?php
var_dump(new class{});
?>
--EXPECTF--
object(class@%s)#%d (0) {
}
-1
View File
@@ -15,7 +15,6 @@ $a = new class extends A implements B {
};
var_dump($a instanceof A, $a instanceof B);
?>
--EXPECT--
bool(true)
bool(true)
-1
View File
@@ -10,7 +10,6 @@ while (@$i++<10) {
}
});
}
?>
--EXPECTF--
object(class@%s)#1 (1) {
["i"]=>
-1
View File
@@ -26,6 +26,5 @@ $outer = new Outer(array(
/* not null because inheritance */
var_dump($outer->getArrayAccess()[0]);
?>
--EXPECTF--
int(%d)
-1
View File
@@ -32,6 +32,5 @@ $proxy = $outer->getArrayAccess();
/* null because no inheritance, so no access to protected member */
var_dump(@$outer->getArrayAccess()[0]);
?>
--EXPECT--
NULL
-1
View File
@@ -9,7 +9,6 @@ namespace lone {
namespace {
var_dump ($hello);
}
?>
--EXPECTF--
object(class@%s)#1 (0) {
}
-1
View File
@@ -17,7 +17,6 @@ namespace lone {
new Outer();
}
?>
--EXPECTF--
object(class@%s)#2 (0) {
}
-1
View File
@@ -18,7 +18,6 @@ $anonClass = new class("cats", "dogs") {
var_dump($anonClass::$foo);
var_dump($anonClass::getBar());
?>
--EXPECT--
string(4) "cats"
string(4) "dogs"
-1
View File
@@ -14,6 +14,5 @@ $anonClass = new class {
};
var_dump($anonClass->someMethod());
?>
--EXPECT--
string(3) "bar"
+3 -3
View File
@@ -5,9 +5,9 @@ Ensure proper inheritance with get_class(anon class instance) used via class_ali
class_alias(get_class(new class { protected $foo = 1; }), "AnonBase");
var_dump((new class extends AnonBase {
function getFoo() {
return $this->foo;
}
function getFoo() {
return $this->foo;
}
})->getFoo());
?>
--EXPECT--
-30
View File
@@ -1,30 +0,0 @@
--TEST--
Generated names for anonymous classes
--FILE--
<?php
namespace DeclaringNS {
class Test1 {}
interface Test2 {}
interface Test3 {}
}
namespace UsingNS {
function print_name(object $obj) {
echo strstr(get_class($obj), "\0", true), "\n";
}
print_name(new class {});
print_name(new class extends \DeclaringNS\Test1 {});
print_name(new class extends \DeclaringNS\Test1 implements \DeclaringNS\Test2 {});
print_name(new class implements \DeclaringNS\Test2 {});
print_name(new class implements \DeclaringNS\Test2, \DeclaringNS\Test3 {});
}
?>
--EXPECT--
class@anonymous
DeclaringNS\Test1@anonymous
DeclaringNS\Test1@anonymous
DeclaringNS\Test2@anonymous
DeclaringNS\Test2@anonymous
+54
View File
@@ -0,0 +1,54 @@
--TEST--
Testing calls to anonymous function
--FILE--
<?php
for ($i = 0; $i < 10; $i++) {
$a = create_function('', 'return '. $i .';');
var_dump($a());
$b = "\0lambda_". ($i + 1);
var_dump($b());
}
?>
--EXPECTF--
Deprecated: Function create_function() is deprecated in %s on line %d
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)
+19
View File
@@ -0,0 +1,19 @@
--TEST--
Testing anonymous function return as array key and accessing $GLOBALS
--FILE--
<?php
$test = create_function('$v', 'return $v;');
$arr = array(create_function('', 'return $GLOBALS["arr"];'), 2);
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
int(2)
bool(true)
+16
View File
@@ -0,0 +1,16 @@
--TEST--
Using throw $var with anonymous function return
--FILE--
<?php
try {
$a = create_function('', 'return new Exception("test");');
throw $a();
} catch (Exception $e) {
var_dump($e->getMessage() == 'test');
}
?>
--EXPECTF--
Deprecated: Function create_function() is deprecated in %s on line %d
bool(true)
+47 -31
View File
@@ -7,37 +7,53 @@ function test(...$args) {
var_dump($args);
}
try {
test(...null);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
test(...42);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
test(...new stdClass);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
test(...null);
test(...42);
test(...new stdClass);
try {
test(1, 2, 3, ..."foo", ...[4, 5]);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
test(1, 2, 3, ...new StdClass, ...3.14, ...[4, 5]);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
test(1, 2, 3, ..."foo", ...[4, 5]);
test(1, 2, 3, ...new StdClass, ...3.14, ...[4, 5]);
?>
--EXPECT--
Only arrays and Traversables can be unpacked
Only arrays and Traversables can be unpacked
Only arrays and Traversables can be unpacked
Only arrays and Traversables can be unpacked
Only arrays and Traversables can be unpacked
--EXPECTF--
Warning: Only arrays and Traversables can be unpacked in %s on line %d
array(0) {
}
Warning: Only arrays and Traversables can be unpacked in %s on line %d
array(0) {
}
Warning: Only arrays and Traversables can be unpacked in %s on line %d
array(0) {
}
Warning: Only arrays and Traversables can be unpacked in %s on line %d
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
Warning: Only arrays and Traversables can be unpacked in %s on line %d
Warning: Only arrays and Traversables can be unpacked in %s on line %d
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
+6 -6
View File
@@ -3,19 +3,19 @@ Argument unpacking does not work with non-integer keys
--FILE--
<?php
function foo(...$args) {
var_dump($args);
var_dump($args);
}
function gen() {
yield 1.23 => 123;
yield "2.34" => 234;
yield 1.23 => 123;
yield "2.34" => 234;
}
try {
foo(...gen());
foo(...gen());
} catch (Error $ex) {
echo "Exception: " . $ex->getMessage() . "\n";
echo "Exception: " . $ex->getMessage() . "\n";
}
?>
--EXPECT--
Exception: Keys must be of type int|string during argument unpacking
Exception: Cannot unpack Traversable with non-integer keys
+9 -3
View File
@@ -8,11 +8,17 @@ set_error_handler(function($errno, $errstr) {
});
try {
var_dump(...new ArrayIterator([1, 2, "foo" => 3, 4]));
var_dump(...[1, 2, "foo" => 3, 4]);
} catch (Error $ex) {
var_dump($ex->getMessage());
var_dump($ex->getMessage());
}
try {
var_dump(...new ArrayIterator([1, 2, "foo" => 3, 4]));
} catch (Error $ex) {
var_dump($ex->getMessage());
}
?>
--EXPECT--
string(68) "Cannot use positional argument after named argument during unpacking"
string(36) "Cannot unpack array with string keys"
string(42) "Cannot unpack Traversable with string keys"
-39
View File
@@ -1,39 +0,0 @@
<?php
function skipFunction($function): bool {
if (false
/* expect input / hang */
|| $function === 'readline'
|| $function === 'readline_read_history'
|| $function === 'readline_write_history'
/* intentionally violate invariants */
|| $function === 'zend_create_unterminated_string'
|| $function === 'zend_test_array_return'
|| $function === 'zend_leak_bytes'
/* mess with output */
|| (is_string($function) && str_starts_with($function, 'ob_'))
|| $function === 'output_add_rewrite_var'
|| $function === 'error_log'
/* may spend a lot of time waiting for connection timeouts */
|| (is_string($function) && str_contains($function, 'connect'))
|| (is_string($function) && str_starts_with($function, 'snmp'))
|| (is_array($function) && get_class($function[0]) === mysqli::class
&& in_array($function[1], ['__construct', 'connect', 'real_connect']))
/* misc */
|| $function === 'mail'
|| $function === 'mb_send_mail'
|| $function === 'pcntl_fork'
|| $function === 'posix_kill'
|| $function === 'posix_setrlimit'
|| $function === 'sapi_windows_generate_ctrl_event'
|| $function === 'imagegrabscreen'
) {
return true;
}
if ($function[0] instanceof SoapServer) {
/* TODO: Uses fatal errors */
return true;
}
return false;
}
-83
View File
@@ -1,83 +0,0 @@
--TEST--
Test that there is no arginfo/zpp mismatch
--SKIPIF--
<?php
if (getenv('SKIP_MSAN')) die("skip msan misses interceptors for some functions");
?>
--FILE--
<?php
require __DIR__ . "/arginfo_zpp_mismatch.inc";
function test($function) {
if (skipFunction($function)) {
return;
}
ob_start();
if (is_string($function)) {
echo "Testing $function\n";
} else {
echo "Testing " . get_class($function[0]) . "::$function[1]\n";
}
try {
@$function();
} catch (Throwable) {
}
try {
@$function(null);
} catch (Throwable) {
}
try {
@$function(null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null, null, null);
} catch (Throwable) {
}
ob_end_clean();
}
foreach (get_defined_functions()["internal"] as $function) {
test($function);
}
foreach (get_declared_classes() as $class) {
try {
$rc = new ReflectionClass($class);
$obj = $rc->newInstanceWithoutConstructor();
} catch (Throwable) {
continue;
}
foreach (get_class_methods($class) as $method) {
test([$obj, $method]);
}
}
// var_dump() and debug_zval_dump() print all arguments
?>
===DONE===
--EXPECT--
===DONE===
@@ -1,85 +0,0 @@
--TEST--
Test that there is no arginfo/zpp mismatch in strict mode
--SKIPIF--
<?php
if (getenv('SKIP_MSAN')) die("skip msan misses interceptors for some functions");
?>
--FILE--
<?php
declare(strict_types=1);
require __DIR__ . "/arginfo_zpp_mismatch.inc";
function test($function) {
if (skipFunction($function)) {
return;
}
ob_start();
if (is_string($function)) {
echo "Testing $function\n";
} else {
echo "Testing " . get_class($function[0]) . "::$function[1]\n";
}
try {
@$function();
} catch (Throwable) {
}
try {
@$function(null);
} catch (Throwable) {
}
try {
@$function(null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null, null);
} catch (Throwable) {
}
try {
@$function(null, null, null, null, null, null, null, null);
} catch (Throwable) {
}
ob_end_clean();
}
foreach (get_defined_functions()["internal"] as $function) {
test($function);
}
foreach (get_declared_classes() as $class) {
try {
$rc = new ReflectionClass($class);
$obj = $rc->newInstanceWithoutConstructor();
} catch (Throwable) {
continue;
}
foreach (get_class_methods($class) as $method) {
test([$obj, $method]);
}
}
// var_dump() and debug_zval_dump() print all arguments
?>
===DONE===
--EXPECT--
===DONE===
+5 -5
View File
@@ -3,14 +3,14 @@ Bug #55719 (Argument restriction should come with a more specific error message)
--FILE--
<?php
Class Base {
public function &test($foo, array $bar, $option = NULL, $extra = "lllllllllllllllllllllllllllllllllllllllllllllllllll") {
}
public function &test($foo, array $bar, $option = NULL, $extra = "lllllllllllllllllllllllllllllllllllllllllllllllllll") {
}
}
class Sub extends Base {
public function &test() {
}
public function &test() {
}
}
?>
--EXPECTF--
Fatal error: Declaration of & Sub::test() must be compatible with & Base::test($foo, array $bar, $option = null, $extra = 'llllllllll...') in %s on line %d
Warning: Declaration of & Sub::test() should be compatible with & Base::test($foo, array $bar, $option = NULL, $extra = 'llllllllll...') in %sargument_restriction_001.php on line %d
+5 -5
View File
@@ -3,14 +3,14 @@ Bug #55719 (Argument restriction should come with a more specific error message)
--FILE--
<?php
Abstract Class Base {
public function test($foo, array &$bar, $option = NULL, $extra = 3.141592653589793238462643383279502884197169399375105 ) {
}
public function test($foo, array &$bar, $option = NULL, $extra = 3.141592653589793238462643383279502884197169399375105 ) {
}
}
class Sub extends Base {
public function test($foo, array &$bar) {
}
public function test($foo, array &$bar) {
}
}
?>
--EXPECTF--
Fatal error: Declaration of Sub::test($foo, array &$bar) must be compatible with Base::test($foo, array &$bar, $option = null, $extra = 3.1415926535898) in %s on line %d
Warning: Declaration of Sub::test($foo, array &$bar) should be compatible with Base::test($foo, array &$bar, $option = NULL, $extra = 3.1415926535898) in %sargument_restriction_002.php on line %d
+5 -5
View File
@@ -6,14 +6,14 @@ class Foo {
}
Abstract Class Base {
public function test(Foo $foo, array $bar, $option = NULL, $extra = "lllllllllllllllllllllllllllllllllllllllllllllllllll") {
}
public function test(Foo $foo, array $bar, $option = NULL, $extra = "lllllllllllllllllllllllllllllllllllllllllllllllllll") {
}
}
class Sub extends Base {
public function test() {
}
public function test() {
}
}
?>
--EXPECTF--
Fatal error: Declaration of Sub::test() must be compatible with Base::test(Foo $foo, array $bar, $option = null, $extra = 'llllllllll...') in %s on line %d
Warning: Declaration of Sub::test() should be compatible with Base::test(Foo $foo, array $bar, $option = NULL, $extra = 'llllllllll...') in %sargument_restriction_003.php on line %d
+3 -3
View File
@@ -6,12 +6,12 @@ class Foo {
}
Abstract Class Base {
abstract public function test(Foo $foo, array $bar, $option = NULL, $extra = 16777215) ;
abstract public function test(Foo $foo, array $bar, $option = NULL, $extra = 16777215) ;
}
class Sub extends Base {
public function test(Foo $foo, array $bar, $option = NULL, $extra = 0xffffff ) {
}
public function test(Foo $foo, array $bar, $option = NULL, $extra = 0xffffff ) {
}
}
?>
--EXPECT--
+3 -3
View File
@@ -3,9 +3,9 @@ Bug #55719 (Argument restriction should come with a more specific error message)
--FILE--
<?php
class Sub implements ArrayAccess {
public function offsetSet() {
}
public function offsetSet() {
}
}
?>
--EXPECTF--
Fatal error: Declaration of Sub::offsetSet() must be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value) in %sargument_restriction_005.php on line %d
Fatal error: Declaration of Sub::offsetSet() must be compatible with ArrayAccess::offsetSet($offset, $value) in %sargument_restriction_005.php on line %d
+5 -5
View File
@@ -3,14 +3,14 @@ Bug #60174 (Notice when array in method prototype error)
--FILE--
<?php
Abstract Class Base {
public function test($foo, $extra = array("test")) {
}
public function test($foo, $extra = array("test")) {
}
}
class Sub extends Base {
public function test($foo, $extra) {
}
public function test($foo, $extra) {
}
}
?>
--EXPECTF--
Fatal error: Declaration of Sub::test($foo, $extra) must be compatible with Base::test($foo, $extra = [...]) in %s on line %d
Warning: Declaration of Sub::test($foo, $extra) should be compatible with Base::test($foo, $extra = Array) in %sargument_restriction_006.php on line %d
+6 -6
View File
@@ -2,12 +2,12 @@
Tests that array manipulation code is correctly dealing with copy on write and splitting on reference
--FILE--
<?php
$a=array();
$b=1;
$c=&$b;
$a[]=$b;
$b=2;
var_dump ($a);
$a=array();
$b=1;
$c=&$b;
$a[]=$b;
$b=2;
var_dump ($a);
?>
--EXPECT--
array(1) {
+3 -3
View File
@@ -4,12 +4,12 @@ Accept hashes being equal to zero
<?php
$hashes = [
"\x8e\x1a\x63\x0f\x61" => 32,
"\xf7\x17\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x6b\x03\x6a\x13\x63\x17\x6b\x1d\x67" => 64,
"\x8e\x1a\x63\x0f\x61" => 32,
"\xf7\x17\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x6b\x03\x6a\x13\x63\x17\x6b\x1d\x67" => 64,
];
foreach ($hashes as $hash => $bits) {
var_dump($hashes[$hash], $bits);
var_dump($hashes[$hash], $bits);
}
?>
Loaded 100 of 13784 files, more files were not shown because too many files have changed in this diff. Show more