Compare commits

..
14985 changed files with 960409 additions and 1248178 deletions

No files matched your search

-57
View File
@@ -1,57 +0,0 @@
version: "{branch}.build.{build}"
image: Visual Studio 2015
branches:
except:
- PHP-5.6
- PHP-7.0
skip_commits:
files:
- NEWS
- UPGRADING*
- README.*
clone_depth: 64
cache:
- c:\build-cache
- c:\build-cache\sdk -> .appveyor.yml
environment:
PHP_BUILD_CACHE_BASE_DIR: c:\build-cache
PHP_BUILD_OBJ_DIR: c:\obj
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.0.4
# ext and env setup for tests
#MYSQL_TEST_PASSWD: Password12!
#MYSQL_TEST_USER: root
#PDO_MYSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=root password=Password12!"
#PDO_MYSQL_TEST_USER: root
#PDO_MYSQL_TEST_PASS: Password12!
#PGSQL_TEST_CONNSTR: "host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!"
#PDO_PGSQL_TEST_DSN: "pgsql:host=127.0.0.1 port=5432 dbname=test user=postgres password=Password12!"
#build permutations
matrix:
- THREAD_SAFE: 0
OPCACHE: 0
- THREAD_SAFE: 1
OPCACHE: 1
services:
# the setup scripts have to be touched, once some other db version is used
- mysql
- postgresql96
platform:
- x64
# - x86
build_script:
- appveyor\build.bat
test_script:
- appveyor\test.bat
-16
View File
@@ -1,16 +0,0 @@
; http://editorconfig.org/
root = true
[*.{c,h}]
charset = UTF-8
end_of_line = LF
indent_size = 4
indent_style = tab
insert_final_newline = true
tab_width = 4
trim_trailing_whitespace = true
[*.yml]
indent_size = 2
indent_style = space
+372 -403
View File
@@ -1,21 +1,8 @@
define set_ts
set $tsrm_ls = $arg0
end
document set_ts
set the ts resource, it is impossible for gdb to
call ts_resource_ex while no process is running,
but we could get the resource from the argument
of frame info.
end
define ____executor_globals
if basic_functions_module.zts
if !$tsrm_ls
set $tsrm_ls = ts_resource_ex(0, 0)
end
set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1])
set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
set $tsrm_ls = ts_resource_ex(0, 0)
set $eg = ((zend_executor_globals) (*((void ***) $tsrm_ls))[executor_globals_id-1])
set $cg = ((zend_compiler_globals) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
else
set $eg = executor_globals
set $cg = compiler_globals
@@ -28,125 +15,53 @@ document ____executor_globals
ZTS detection is automatically based on ext/standard module struct
end
define print_cvs
if $argc == 0
____executor_globals
set $cv_ex_ptr = $eg.current_execute_data
else
set $cv_ex_ptr = (zend_execute_data *)$arg0
end
set $cv_count = $cv_ex_ptr.func.op_array.last_var
set $cv = $cv_ex_ptr.func.op_array.vars
set $cv_idx = 0
set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)
printf "Compiled variables count: %d\n\n", $cv_count
while $cv_idx < $cv_count
printf "[%d] '%s'\n", $cv_idx, $cv[$cv_idx].val
set $zvalue = ((zval *) $cv_ex_ptr) + $callFrameSize + $cv_idx
printzv $zvalue
set $cv_idx = $cv_idx + 1
end
define printztype
____printz_type $arg0
printf "\n"
end
document print_cvs
Prints the compiled variables and their values.
If a zend_execute_data pointer is set this will print the compiled
variables of that scope. If no parameter is used it will use
current_execute_data for scope.
usage: print_cvs [zend_execute_data *]
document printztype
prints the type name of a zval type
end
define dump_bt
set $ex = $arg0
while $ex
printf "[%p] ", $ex
set $func = $ex->func
if $func
if $ex->This->value.obj
if $func->common.scope
printf "%s->", $func->common.scope->name->val
else
printf "%s->", $ex->This->value.obj->ce.name->val
end
else
if $func->common.scope
printf "%s::", $func->common.scope->name->val
end
end
if $func->common.function_name
printf "%s(", $func->common.function_name->val
else
printf "(main"
end
set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)
set $count = $ex->This.u2.num_args
set $arg = 0
while $arg < $count
if $arg > 0
printf ", "
end
set $zvalue = (zval *) $ex + $callFrameSize + $arg
set $type = $zvalue->u1.v.type
if $type == 1
printf "NULL"
end
if $type == 2
printf "false"
end
if $type == 3
printf "true"
end
if $type == 4
printf "%ld", $zvalue->value.lval
end
if $type == 5
printf "%f", $zvalue->value.dval
end
if $type == 6
____print_str $zvalue->value.str->val $zvalue->value.str->len
end
if $type == 7
printf "array(%d)[%p]", $zvalue->value.arr->nNumOfElements, $zvalue
end
if $type == 8
printf "object[%p]", $zvalue
end
if $type == 9
printf "resource(#%d)", $zvalue->value.lval
end
if $type == 10
printf "reference"
end
if $type > 10
printf "unknown type %d", $type
end
set $arg = $arg + 1
end
printf ") "
else
printf "??? "
end
if $func != 0
if $func->type == 2
printf "%s:%d ", $func->op_array.filename->val, $ex->opline->lineno
else
printf "[internal function]"
end
end
set $ex = $ex->prev_execute_data
printf "\n"
define ____printz_type
set $type = $arg0
if $type == 0
printf "NULL"
end
if $type == 1
printf "long"
end
if $type == 2
printf "double"
end
if $type == 3
printf "bool"
end
if $type == 4
printf "array"
end
if $type == 5
printf "object"
end
if $type == 6
printf "string"
end
if $type == 7
printf "resource"
end
if $type == 8
printf "constant"
end
if $type == 9
printf "const_array"
end
if $type == 10
printf "unicode string"
end
if $type > 10
printf "unknown type %d", $type
end
end
document dump_bt
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
end
define printzv
@@ -158,113 +73,195 @@ document printzv
prints zval contents
end
define printu
set $str = (UChar*)$arg0
if $arg1 > 0
set $max = $arg1
else
set $max = 1024
end
set $pos = 0
while $pos < $max && *(char*)(($str+$pos))
if $str[$pos] < 256
printf "%c", $str[$pos]
else
printf "\\u%04X", $str[$pos]
end
set $pos = $pos + 1
end
if $pos < $max && *((char*)($str+$pos))
printf "[...]"
end
end
document printu
prints a unicode string, optionally with given length
usage: printu str [len]
The function stops at the first zero byte (not char) or when len is reached.
If len is less than or equal to one then a maximum of 1024 characters are
printed.
end
define printt
if $arg0
printu $arg1 $arg2
else
set $len = strlen($arg1)
if $arg2 > 0 && $len > $arg2
set $copy = strdup($arg1)
printf "%p: %s\n", $copy, $copy
set ((char*)$copy)[$arg2] = 0
printf "%s[...]", $copy
call free($copy)
else
printf "%s", $arg1
end
end
end
document printt
prints a binary or unicode string, optionally with given length
usage: printt unicode str [len]
If unicode is 1 the function calls printu, else it uses printf.
end
define print_cvs
____executor_globals
set $p = $eg.current_execute_data.CVs
set $c = $eg.current_execute_data.op_array.last_var
set $v = $eg.current_execute_data.op_array.vars
set $i = 0
printf "Compiled variables count: %d\n", $c
while $i < $c
printf "%d = %s\n", $i, $v[$i].name
if $p[$i] != 0
printzv *$p[$i]
else
printf "*uninitialized*\n"
end
set $i = $i + 1
end
end
define dump_bt
set $t = $arg0
while $t
printf "[0x%08x] ", $t
if $t->function_state.function->common.function_name
printu $t->function_state.function->common.function_name.u 50
printf "() "
else
printf "??? "
end
if $t->op_array != 0
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
end
set $t = $t->prev_execute_data
printf "\n"
end
end
document dump_bt
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
end
define ____printzv_contents
set $zvalue = $arg0
set $type = $zvalue->u1.v.type
set $type = $zvalue->type
# 15 == IS_INDIRECT
if $type > 5 && $type != 15
printf "(refcount=%d) ", $zvalue->value.counted->gc.refcount
printf "(refcount=%d", $zvalue->refcount__gc
if $zvalue->is_ref__gc
printf ",is_ref"
end
printf ") "
if $type == 0
printf "UNDEF"
printf "NULL"
else
____printz_type $type
end
if $type == 1
printf "NULL"
printf ": %ld", $zvalue->value.lval
end
if $type == 2
printf "bool: false"
printf ": %lf", $zvalue->value.dval
end
if $type == 3
printf "bool: true"
if $zvalue->value.lval
printf ": true"
else
printf ": false"
end
end
if $type == 4
printf "long: %ld", $zvalue->value.lval
end
if $type == 5
printf "double: %f", $zvalue->value.dval
end
if $type == 6
printf "string: %s", $zvalue->value.str->val
end
if $type == 7
printf "array: "
if $type == 4
printf "(%d): ", $zvalue->value.ht->nNumOfElements
if ! $arg1
printf "{\n"
set $ind = $ind + 1
____print_ht $zvalue->value.arr 1
____print_ht $zvalue->value.ht 0 1
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
printf "}"
end
set $type = 0
end
if $type == 8
printf "object"
if $type == 5
____executor_globals
set $handle = $zvalue->value.obj.handle
set $handlers = $zvalue->value.obj.handlers
set $zobj = $zvalue->value.obj
set $cname = $zobj->ce->name->val
if basic_functions_module.zts
set $zobj = zend_objects_get_address($zvalue, $tsrm_ls)
else
set $zobj = zend_objects_get_address($zvalue)
end
if $handlers->get_class_entry == &zend_std_object_get_class
set $cname = $zobj->ce.name.s
else
set $cname = "Unknown"
end
printf "(%s) #%d", $cname, $handle
if ! $arg1
if $handlers->get_properties == &zend_std_get_properties
if $zobj->properties
set $ht = $zobj->properties
else
set $ht = &$zobj->ce->properties_info
end
printf "\nProperties "
set $ht = $zobj->properties
if $ht
printf "(%d): ", $ht->nNumOfElements
printf "{\n"
set $ind = $ind + 1
____print_ht $ht 1
____print_ht $ht 1 1
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
printf "}"
else
echo "not found"
echo "no properties found"
end
end
end
set $type = 0
end
if $type == 6
printf "(%d): \"%s\"", $zvalue->value.str.len, $zvalue->value.str.val
end
if $type == 7
printf ": #%d", $zvalue->value.lval
end
if $type == 8
end
if $type == 9
printf "resource: #%d", $zvalue->value.res->handle
end
if $type == 10
printf "reference: "
____printzv &$zvalue->value.ref->val $arg1
printf "(%d): [%p]: \"", $zvalue->value.str.len, $zvalue->value.str.val
printu $zvalue->value.ustr.val $zvalue->value.str.len
printf "\""
end
if $type == 11
printf "const: %s", $zvalue->value.str->val
end
if $type == 12
printf "const_ast"
end
if $type == 13
printf "_IS_BOOL"
end
if $type == 14
printf "IS_CALLABLE"
end
if $type == 15
printf "indirect: "
____printzv $zvalue->value.zv $arg1
end
if $type == 16
printf "string_offset"
end
if $type == 17
printf "pointer: %p", $zvalue->value.ptr
end
if $type > 17
printf "unknown type %d", $type
if $type > 10
end
printf "\n"
end
@@ -273,7 +270,11 @@ define ____printzv
____executor_globals
set $zvalue = $arg0
printf "[%p] ", $zvalue
printf "[0x%08x] ", $zvalue
if $zvalue == $eg.uninitialized_zval_ptr
printf "*uninitialized* "
end
set $zcontents = (zval*) $zvalue
if $arg1
@@ -296,9 +297,8 @@ define ____print_const_table
set $i = $i - 1
end
if $p->nKeyLength > 0
____print_str $p->arKey $p->nKeyLength
printf " => "
if $p->nKeyLength > 0
printf "\"%s\" => ", $p->key.arKey.s
else
printf "%d => ", $p->h
end
@@ -310,67 +310,64 @@ end
define print_const_table
set $ind = 1
printf "[%p] {\n", $arg0
printf "[0x%08x] {\n", $arg0
____print_const_table $arg0
printf "}\n"
end
define ____print_ht
set $ht = (HashTable*)$arg0
set $n = $ind
while $n > 0
printf " "
set $n = $n - 1
end
set $ht = $arg0
set $obj = $arg1
set $p = $ht->pListHead
set $unicode = $ht->unicode
if $ht->u.v.flags & 4
printf "Packed"
else
printf "Hash"
end
printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht
set $num = $ht->nNumUsed
set $i = 0
set $ind = $ind + 1
while $i < $num
set $p = (Bucket*)($ht->arData + $i)
set $n = $ind
if $p->val.u1.v.type > 0
while $n > 0
printf " "
set $n = $n - 1
end
printf "[%d] ", $i
if $p->key
printf "%s => ", $p->key->val
else
printf "%d => ", $p->h
end
if $arg1 == 0
printf "%p\n", (zval *)&$p->val
end
if $arg1 == 1
set $zval = (zval *)&$p->val
____printzv $zval 1
end
if $arg1 == 2
printf "%s\n", (char*)$p->val.value.ptr
end
if $arg1 == 3
set $func = (zend_function*)$p->val.value.ptr
printf "\"%s\"\n", $func->common.function_name->val
end
while $p != 0
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
set $i = $i + 1
if $p->nKeyLength > 0
if $obj && $p->key.arKey.s[0] == 0
if $p->key.arKey.s[1] == '*'
printf "\"protected %s\" => ", $p->key.arKey.s+3
else
set $n = 1
while $n < $p->nKeyLength && $p->key.arKey.s[$n] != 0
set $n = $n + 1
end
printf "\"private %s::%s\" => ", $p->key.arKey.s+1, $p->key.arKey.s+$n+1
end
else
printf "\""
printt $p->key.type $p->key.arKey.s $p->nKeyLength
printf "\" => "
end
else
printf "%d => ", $p->h
end
if $arg1 == 0
printf "%p\n", (void*)$p->pData
end
if $arg1 == 1
set $zval = *(zval **)$p->pData
____printzv $zval 1
end
if $arg1 == 2
printf "%s\n", (char*)$p->pData
end
set $p = $p->pListNext
end
set $ind = $ind - 1
printf "}\n"
end
define print_ht
set $ind = 0
set $ind = 1
printf "[0x%08x] (%d) {\n", $arg0, $arg0->nNumOfElements
____print_ht $arg0 1
printf "}\n"
end
document print_ht
@@ -378,8 +375,10 @@ document print_ht
end
define print_htptr
set $ind = 0
set $ind = 1
printf "[0x%08x] (%d) {\n", $arg0, $arg0->nNumOfElements
____print_ht $arg0 0
printf "}\n"
end
document print_htptr
@@ -387,144 +386,77 @@ document print_htptr
end
define print_htstr
set $ind = 0
set $ind = 1
printf "[0x%08x] (%d) {\n", $arg0, $arg0->nNumOfElements
____print_ht $arg0 2
printf "}\n"
end
document print_htstr
dumps elements of HashTable made of strings
end
define ____print_ft
set $ht = $arg0
set $p = $ht->pListHead
set $unicode = $ht->unicode
while $p != 0
set $func = (zend_function*)$p->pData
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
if $p->nKeyLength > 0
printf "\""
if $p->key.arKey.u.s[1] == '\0'
printu $p->key.arKey.u $p->nKeyLength
else
printt $unicode $p->key.arKey.u $p->nKeyLength
end
printf "\" => "
else
printf "%d => ", $p->h
end
printf "[%p]: ", $func
if $func->common.fn_flags & 0x01
printf "static "
end
if $func->common.fn_flags & 0x02
printf "abstract "
end
if $func->common.fn_flags & 0x04
printf "final "
end
set $visibility = zend_visibility_string($func->common.fn_flags)
printf "%s", $visibility
if *$visibility
printf " "
end
if $func->common.return_reference
printf "& "
end
printt $unicode $func->common.function_name.s 0
printf "()\n"
set $p = $p->pListNext
end
end
define print_ft
set $ind = 0
____print_ht $arg0 3
set $ind = 1
printf "[0x%08x] (%d) {\n", $arg0, $arg0->nNumOfElements
____print_ft $arg0
printf "}\n"
end
document print_ft
dumps a function table (HashTable)
end
define ____print_inh_class
set $ce = $arg0
if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20
printf "abstract "
else
if $ce->ce_flags & 0x40
printf "final "
end
end
printf "class %s", $ce->name->val
if $ce->parent != 0
printf " extends %s", $ce->parent->name->val
end
if $ce->num_interfaces != 0
printf " implements"
set $tmp = 0
while $tmp < $ce->num_interfaces
printf " %s", $ce->interfaces[$tmp]->name->val
set $tmp = $tmp + 1
if $tmp < $ce->num_interfaces
printf ","
end
end
end
set $ce = $ce->parent
end
define ____print_inh_iface
set $ce = $arg0
printf "interface %s", $ce->name->val
if $ce->num_interfaces != 0
set $ce = $ce->interfaces[0]
printf " extends %s", $ce->name->val
else
set $ce = 0
end
end
define print_inh
set $ce = $arg0
set $depth = 0
while $ce != 0
set $tmp = $depth
while $tmp != 0
printf " "
set $tmp = $tmp - 1
end
set $depth = $depth + 1
if $ce->ce_flags & 0x80
____print_inh_iface $ce
else
____print_inh_class $ce
end
printf " {\n"
end
while $depth != 0
set $tmp = $depth
while $tmp != 1
printf " "
set $tmp = $tmp - 1
end
printf "}\n"
set $depth = $depth - 1
end
end
define print_pi
set $pi = (zend_property_info *)$arg0
printf "[%p] {\n", $pi
printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val
printf " flags = %d (", $pi->flags
if $pi->flags & 0x100
printf "ZEND_ACC_PUBLIC"
else
if $pi->flags & 0x200
printf "ZEND_ACC_PROTECTED"
else
if $pi->flags & 0x400
printf "ZEND_ACC_PRIVATE"
else
if $pi->flags & 0x800
printf "ZEND_ACC_CHANGED"
end
end
end
end
printf ")\n"
printf " name = "
print_zstr $pi->name
printf "}\n"
end
document print_pi
Takes a pointer to an object's property and prints the property information
usage: print_pi <ptr>
end
define ____print_str
set $tmp = 0
set $str = $arg0
if $argc > 2
set $maxlen = $arg2
else
set $maxlen = 256
end
printf "\""
while $tmp < $arg1 && $tmp < $maxlen
if $str[$tmp] > 31 && $str[$tmp] < 127
printf "%c", $str[$tmp]
else
printf "\\%o", $str[$tmp]
end
set $tmp = $tmp + 1
end
if $tmp != $arg1
printf "..."
end
printf "\""
end
define printzn
____executor_globals
set $ind = 0
@@ -541,8 +473,11 @@ define printzn
if $znode->op_type == 8
set $optype = "IS_UNUSED"
end
if $znode->op_type == 16
set $optype = "IS_CV"
end
printf "[%p] %s", $znode, $optype
printf "[0x%08x] %s", $znode, $optype
if $znode->op_type == 1
printf ": "
@@ -561,6 +496,9 @@ define printzn
if $znode->op_type == 8
printf "\n"
end
if $znode->op_type == 16
printf "\n"
end
end
document printzn
@@ -581,23 +519,6 @@ document printzops
dump operands of the current opline
end
define print_zstr
set $zstr = (zend_string *)$arg0
if $argc == 2
set $maxlen = $arg1
else
set $maxlen = $zstr->len
end
printf "string(%d) ", $zstr->len
____print_str $zstr->val $zstr->len $maxlen
printf "\n"
end
document print_zstr
print the length and contents of a zend string
usage: print_zstr <ptr> [max length]
end
define zbacktrace
____executor_globals
dump_bt $eg.current_execute_data
@@ -610,27 +531,75 @@ document zbacktrace
> (gdb) dump_bt $eg.current_execute_data
end
define lookup_root
set $found = 0
if gc_globals->roots
set $current = gc_globals->roots->next
printf "looking ref %p in roots\n", $arg0
while $current != &gc_globals->roots
if $current->ref == $arg0
set $found = $current
break
define zmemcheck
set $p = alloc_globals.head
set $stat = "?"
set $total_size = 0
if $arg0 != 0
set $not_found = 1
else
set $not_found = 0
end
printf " block size status file:line\n"
printf "-------------------------------------------------------------------------------\n"
while $p
set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test)
if $arg0 == 0 || (void *)$aptr == (void *)$arg0
if $p->magic == 0x7312f8dc
set $stat = "OK"
end
if $p->magic == 0x99954317
set $stat = "FREED"
end
if $p->magic == 0xfb8277dc
set $stat = "CACHED"
end
set $filename = strrchr($p->filename, '/')
if !$filename
set $filename = $p->filename
else
set $filename = $filename + 1
end
printf " 0x%08x ", $aptr
if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10
printf "ZVAL?(%-2d) ", $p->size
else
printf "%-9d ", $p->size
end
set $total_size = $total_size + $p->size
printf "%-06s %s:%d", $stat, $filename, $p->lineno
if $p->orig_filename
set $orig_filename = strrchr($p->orig_filename, '/')
if !$orig_filename
set $orig_filename = $p->orig_filename
else
set $orig_filename = $orig_filename + 1
end
printf " <= %s:%d\n", $orig_filename, $p->orig_lineno
else
printf "\n"
end
if $arg0 != 0
set $p = 0
set $not_found = 0
else
set $p = $p->pNext
end
set $current = $current->next
end
if $found != 0
printf "found root %p\n", $found
else
printf "not found\n"
set $p = $p->pNext
end
end
if $not_found
printf "no such block that begins at 0x%08x.\n", $aptr
end
if $arg0 == 0
printf "-------------------------------------------------------------------------------\n"
printf " total: %d bytes\n", $total_size
end
end
document lookup_root
lookup a refcounted in root
usage: lookup_root [ptr].
document zmemcheck
show status of a memory block.
usage: zmemcheck [ptr].
if ptr is 0, all blocks will be listed.
end
-180
View File
@@ -1,180 +0,0 @@
ext/mysqlnd/mysqlnd.h ident
ext/simplexml/simplexml.c ident
ext/iconv/php_iconv.h ident
ext/posix/posix.c ident
ext/recode/recode.c ident
ext/skeleton/create_stubs ident
ext/phar/phar/pharcommand.inc ident
ext/phar/phar.c ident
ext/sysvmsg/sysvmsg.c ident
ext/enchant/enchant.c ident
ext/reflection/php_reflection.c ident
ext/oci8/oci8.c ident
ext/dba/libinifile/inifile.c ident
ext/dba/libflatfile/flatfile.c ident
ext/dba/libcdb/cdb_make.c ident
ext/dba/libcdb/cdb.c ident
ext/filter/filter.c ident
ext/zip/php_zip.c ident
README.input_filter ident
run-tests.php ident
sapi/nsapi/nsapi.c ident
sapi/continuity/capi.c ident
Zend/RFCs/002.txt ident
Zend/RFCs/003.txt ident
ext/exif/exif.c ident
ext/ldap/ldap.c ident
ext/pdo_pgsql/pdo_pgsql.c ident
ext/tidy/tidy.c ident
NEWS merge=NEWS
UPGRADING merge=NEWS
UPGRADING.INTERNALS merge=NEWS
/ext/bz2/tests/with_strings.phpt -crlf
/ext/dom/tests/bug40836.phpt -crlf
/ext/dom/tests/domelement.phpt -crlf
/ext/ereg/tests/eregi_basic_002.phpt -crlf
/ext/iconv/tests/iconv004.phpt -crlf
/ext/iconv/tests/iconv_basic.phpt -crlf
/ext/iconv/tests/iconv_strpos.phpt -crlf
/ext/iconv/tests/iconv_strpos_variation2.phpt -crlf
/ext/mbstring/tests/mb_strtoupper_error2.phpt -crlf
/ext/phar/tests/delete_in_phar_confirm.phpt -crlf
/ext/phar/tests/frontcontroller12.phpt -crlf
/ext/phar/tests/security.phpt -crlf
/ext/phar/tests/test_signaturealgos.phpt -crlf
/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt -crlf
/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt -crlf
/ext/spl/tests/dllist_007.phpt -crlf
/ext/spl/tests/iterator_012.phpt -crlf
/ext/spl/tests/SplArray_fromArray.phpt -crlf
/ext/standard/tests/dir/scandir_variation3.phpt -crlf
/ext/standard/tests/general_functions/escapeshellcmd-win32.phpt -crlf
/ext/standard/tests/strings/bug26817.phpt -crlf
/ext/standard/tests/strings/bug26973.phpt -crlf
/ext/standard/tests/strings/bug27457.phpt -crlf
/ext/standard/tests/strings/bug28386.phpt -crlf
/ext/standard/tests/strings/bug37262.phpt -crlf
/ext/standard/tests/strings/bug40637.phpt -crlf
/ext/standard/tests/strings/bug40915.phpt -crlf
/ext/standard/tests/strings/bug61374.phpt -crlf
/ext/standard/tests/strings/chop_error.phpt -crlf
/ext/standard/tests/strings/chop_variation2.phpt -crlf
/ext/standard/tests/strings/chunk_split_variation10.phpt -crlf
/ext/standard/tests/strings/chunk_split_variation8.phpt -crlf
/ext/standard/tests/strings/count_chars_variation2.phpt -crlf
/ext/standard/tests/strings/dirname_error.phpt -crlf
/ext/standard/tests/strings/fprintf_variation_007_64bit.phpt -crlf
/ext/standard/tests/strings/highlight_file.phpt -crlf
/ext/standard/tests/strings/htmlentities03.phpt -crlf
/ext/standard/tests/strings/htmlentities04.phpt -crlf
/ext/standard/tests/strings/htmlentities08.phpt -crlf
/ext/standard/tests/strings/htmlentities15.phpt -crlf
/ext/standard/tests/strings/http_build_query.phpt -crlf
/ext/standard/tests/strings/metaphone.phpt -crlf
/ext/standard/tests/strings/ord_error.phpt -crlf
/ext/standard/tests/strings/printf_basic2.phpt -crlf
/ext/standard/tests/strings/printf_variation2.phpt -crlf
/ext/standard/tests/strings/quoted_printable_decode_basic.phpt -crlf
/ext/standard/tests/strings/rtrim.phpt -crlf
/ext/standard/tests/strings/setlocale_variation1.phpt -crlf
/ext/standard/tests/strings/sha1_basic.phpt -crlf
/ext/standard/tests/strings/similar_text_basic.phpt -crlf
/ext/standard/tests/strings/soundex.phpt -crlf
/ext/standard/tests/strings/sprintf_basic1.phpt -crlf
/ext/standard/tests/strings/sprintf_basic4.phpt -crlf
/ext/standard/tests/strings/sprintf_basic7.phpt -crlf
/ext/standard/tests/strings/sprintf_variation12.phpt -crlf
/ext/standard/tests/strings/sprintf_variation28.phpt -crlf
/ext/standard/tests/strings/sprintf_variation29.phpt -crlf
/ext/standard/tests/strings/sprintf_variation30.phpt -crlf
/ext/standard/tests/strings/sprintf_variation31.phpt -crlf
/ext/standard/tests/strings/sprintf_variation38.phpt -crlf
/ext/standard/tests/strings/sprintf_variation42.phpt -crlf
/ext/standard/tests/strings/sprintf_variation6.phpt -crlf
/ext/standard/tests/strings/sscanf_basic2.phpt -crlf
/ext/standard/tests/strings/sscanf_basic3.phpt -crlf
/ext/standard/tests/strings/str_getcsv_001.phpt -crlf
/ext/standard/tests/strings/stripcslashes_basic.phpt -crlf
/ext/standard/tests/strings/stripos_variation11.phpt -crlf
/ext/standard/tests/strings/stripos_variation13.phpt -crlf
/ext/standard/tests/strings/stripslashes_variation1.phpt -crlf
/ext/standard/tests/strings/stripslashes_variation2.phpt -crlf
/ext/standard/tests/strings/stristr_error.phpt -crlf
/ext/standard/tests/strings/strnatcasecmp_basic.phpt -crlf
/ext/standard/tests/strings/strncasecmp_variation6.phpt -crlf
/ext/standard/tests/strings/strncasecmp_variation7.phpt -crlf
/ext/standard/tests/strings/strncasecmp_variation8.phpt -crlf
/ext/standard/tests/strings/strrchr_error.phpt -crlf
/ext/standard/tests/strings/strrchr.phpt -crlf
/ext/standard/tests/strings/strrchr_variation11.phpt -crlf
/ext/standard/tests/strings/strrpos_error.phpt -crlf
/ext/standard/tests/strings/strrpos_variation4.phpt -crlf
/ext/standard/tests/strings/strrpos_variation8.phpt -crlf
/ext/standard/tests/strings/strstr2.phpt -crlf
/ext/standard/tests/strings/strtok_error.phpt -crlf
/ext/standard/tests/strings/strtok_variation2.phpt -crlf
/ext/standard/tests/strings/strtolower-win32.phpt -crlf
/ext/standard/tests/strings/substr_compare.phpt -crlf
/ext/standard/tests/strings/ucwords_variation1.phpt -crlf
/ext/standard/tests/strings/unpack.phpt -crlf
/ext/standard/tests/strings/vfprintf_basic7_64bit.phpt -crlf
/ext/standard/tests/strings/vfprintf_variation11_64bit.phpt -crlf
/ext/standard/tests/strings/vfprintf_variation12_64bit.phpt -crlf
/ext/standard/tests/strings/vfprintf_variation12.phpt -crlf
/ext/standard/tests/strings/vfprintf_variation13_64bit.phpt -crlf
/ext/standard/tests/strings/vfprintf_variation7.phpt -crlf
/ext/standard/tests/strings/vprintf_basic2.phpt -crlf
/ext/standard/tests/strings/vprintf_basic7_64bit.phpt -crlf
/ext/standard/tests/strings/vprintf_variation10.phpt -crlf
/ext/standard/tests/strings/vprintf_variation14_64bit.phpt -crlf
/ext/standard/tests/strings/vprintf_variation17.phpt -crlf
/ext/standard/tests/strings/vprintf_variation4.phpt -crlf
/ext/standard/tests/strings/vsprintf_basic4.phpt -crlf
/ext/standard/tests/strings/vsprintf_basic8.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation12_64bit.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation13_64bit.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation17.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation4_64bit.phpt -crlf
/ext/standard/tests/strings/vsprintf_variation7.phpt -crlf
/ext/standard/tests/strings/wordwrap.phpt -crlf
/ext/standard/tests/strings/wordwrap_variation5.phpt -crlf
/ext/standard/tests/url/rawurldecode_variation_001.phpt -crlf
/ext/tidy/tests/009.phpt -crlf
/ext/tidy/tests/013.phpt -crlf
/ext/tidy/tests/021.phpt -crlf
/ext/tidy/tests/tidy_error.phpt -crlf
/ext/tokenizer/tests/002.phpt -crlf
/ext/tokenizer/tests/bug26463.phpt -crlf
/ext/tokenizer/tests/token_get_all_error.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation11.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation12.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation13.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation14.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation15.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation18.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation19.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation1.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation2.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation3.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation5.phpt -crlf
/ext/tokenizer/tests/token_get_all_variation8.phpt -crlf
/ext/xml/tests/bug32001b.phpt -crlf
/ext/xmlwriter/tests/OO_003.phpt -crlf
/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt -crlf
/ext/zlib/tests/008.phpt -crlf
/ext/zlib/tests/gzopen_variation4.phpt -crlf
/ext/zlib/tests/gzrewind_error.phpt -crlf
/ext/zlib/tests/readgzfile_variation7.phpt -crlf
/ext/zlib/tests/readgzfile_variation8.phpt -crlf
/ext/zlib/tests/zlib_scheme_stat_basic.phpt -crlf
/sapi/cli/tests/006.phpt -crlf
/tests/run-test/test009.phpt -crlf
/Zend/tests/012.phpt -crlf
/Zend/tests/bug28072.phpt -crlf
/Zend/tests/bug38624.phpt -crlf
/Zend/tests/bug40784.phpt -crlf
/Zend/tests/bug43053.phpt -crlf
/Zend/tests/bug51176.phpt -crlf
/Zend/tests/each_003.phpt -crlf
/Zend/tests/errmsg_006.phpt -crlf
-287
View File
@@ -1,287 +0,0 @@
# General Ignores
*~
.#*
*.
*.slo
*.mk
*.mem
*.gcda
*.gcno
*.la
*.lo
*.loT
*.o
*.a
*.ncb
*.opt
*.plg
*swp
*.patch
*.tgz
*.tar.gz
*.tar.bz2
*.tar.xz
*.tar.gz.asc
*.tar.bz2.asc
*.tar.xz.asc
.FBCIndex
.FBCLockFolder
.deps
.libs
phpt.*
core
dynlib.m4
Debug
Debug_TS
Makefile
Makefile.fragments
Makefile.objects
Release
Release_TS
Release_TSDbg
Release_TS_inline
Release_inline
ZendEngine1
_libs
acconfig.h
aclocal.m4
autom4te.cache
bsd_converted
buildconf.stamp
buildmk.stamp
confdefs.h
config.h
config.guess
config.cache
config.h.in
config.log
config.nice
config.nice.bat
config.status
config.sub
config_vars.mk
configuration-parser.c
configuration-parser.h
configuration-parser.output
configuration-scanner.c
configure
configure.bat
configure.js
conftest
conftest.c
debug.log
diff
generated_lists
include
install-sh
internal_functions.c
lcov_data
lcov_html
libs
libtool
meta_cc
meta_ccld
missing
mkinstalldirs
modules
php
php-*.tar.gz
php7.spec
php_lcov.info
php_test_results_*.txt
php_version.h
results.txt
shlibtool
stamp-h
test.php3
tmp-php.ini
want_dependencies
x64
stamp-h.in
scan_makefile_in.awk
TSRM/tsrm_config.h
Zend/zend_config.h
Zend/zend_dtrace_gen.h
Zend/zend_dtrace_gen.hbak
Zend/zend_ini_parser.c
Zend/zend_ini_parser.h
Zend/zend_ini_parser.output
Zend/zend_language_parser.c
Zend/zend_language_parser.h
Zend/zend_language_parser.output
ext/date/lib/timelib_config.h
ext/iconv/php_iconv_aliased_libiconv.h
ext/phar/phar.php
main/php_config.h
main/php_config.h.in
# Test specific Ignores
tests/*/*.diff
tests/*/*.out
tests/*/*.php
tests/*/*.exp
tests/*/*.log
tests/*/*.sh
tests/*/*/*.diff
tests/*/*/*.out
tests/*/*/*.php
tests/*/*/*.exp
tests/*/*/*.log
tests/*/*/*.sh
*/tests/*.diff
*/tests/*.out
*/tests/*.php
*/tests/*.exp
*/tests/*.log
*/tests/*.sh
*/tests/*/*.diff
*/tests/*/*.out
*/tests/*/*.php
*/tests/*/*.exp
*/tests/*/*.log
*/tests/*/*.sh
*/tests/*/*/*.diff
*/tests/*/*/*.out
*/tests/*/*/*.php
*/tests/*/*/*.exp
*/tests/*/*/*.log
*/tests/*/*/*.sh
*/*/tests/*.diff
*/*/tests/*.out
*/*/tests/*.out.png
*/*/tests/*.php
*/*/tests/*.exp
*/*/tests/*.log
*/*/tests/*.sh
*/*/tests/*/*.diff
*/*/tests/*/*.out
*/*/tests/*/*.php
*/*/tests/*/*.exp
*/*/tests/*/*.log
*/*/tests/*/*.sh
*/*/tests/*/*/*.diff
*/*/tests/*/*/*.out
*/*/tests/*/*/*.php
*/*/tests/*/*/*.exp
*/*/tests/*/*/*.log
*/*/tests/*/*/*.sh
*/*/tests/*/*/*/*.diff
*/*/tests/*/*/*/*.out
*/*/tests/*/*/*/*.php
*/*/tests/*/*/*/*.exp
*/*/tests/*/*/*/*.log
*/*/tests/*/*/*/*.sh
# Extension specifc ignores
ext/*/configure.in
ext/*/ltmain.sh
ext/*/libs.mk
ext/*/build
ext/*/scan_makefile_in.awk
ext/*/Makefile.global
ext/*/acinclude.m4
ext/*/config.sub
# Extension specific
ext/iconv/scan_makefile_in.awk
ext/iconv/php_have_bsd_iconv.h
ext/iconv/php_have_ibm_iconv.h
ext/iconv/php_have_libiconv.h
ext/iconv/php_php_iconv_h_path.h
ext/iconv/php_have_glibc_iconv.h
ext/iconv/php_php_iconv_impl.h
ext/iconv/php_have_iconv.h
ext/iconv/php_iconv_supports_errno.h
ext/iconv/php_iconv_broken_ignore.h
ext/mbstring/libmbfl/Makefile.in
ext/mbstring/libmbfl/autoscan.log
ext/mbstring/libmbfl/config.sub
ext/mbstring/libmbfl/depcomp
ext/mbstring/libmbfl/ltmain.sh
ext/mbstring/libmbfl/stamp-h1
ext/mbstring/libmbfl/*.dll
ext/mbstring/libmbfl/*.lib
ext/mbstring/libmbfl/*.RES
ext/mbstring/libmbfl/*.res
ext/mbstring/libmbfl/*.obj
ext/mbstring/libmbfl/*.tds
ext/mbstring/libmbfl/filters/Makefile.in
ext/mbstring/libmbfl/mbfl/Makefile.in
ext/mbstring/libmbfl/mbfl/EastAsianWidth.txt
ext/mbstring/libmbfl/nls/Makefile.in
ext/mssql/#*#
ext/mssql/Makefile.global
ext/mssql/acinclude.m4
ext/mssql/config.sub
ext/mssql/configure.in
ext/mssql/ltmain.sh
ext/mysql/weztest.sqlite
ext/oci8/tests/*.tmp
ext/oci8/tests/*.vglog
ext/pdo/conftest*
ext/pdo/tests/*.db
ext/pdo/tests/*.tmp
ext/pdo_firebird/conftest*
ext/pdo_mysql/conftest*
ext/pdo_mysql/tests/*.db
ext/pdo_mysql/tests/*.tmp
ext/pdo_oci/conftest*
ext/pdo_odbc/tests/*.db
ext/pdo_odbc/tests/*.tmp
ext/pdo_odbc/tests/*.mdb
ext/pdo_pgsql/conftest*
ext/pdo_pgsql/tests/*.db
ext/pdo_pgsql/tests/*.tmp
ext/pdo_sqlite/conftest*
ext/pdo_sqlite/sqlite3.h
ext/pdo_sqlite/tests/*.db
ext/pdo_sqlite/tests/*.tmp
ext/phar/phar.phar
ext/phar/phar.1
ext/phar/phar.phar.1
ext/pspell/tests/*.tmp
ext/reflection/xml
ext/reflection/html
ext/reflection/spl.chm
ext/simplexml/examples/security.new.xml
ext/spl/examples/.htaccess
ext/spl/examples/*.phps
ext/sqlite3/tests/phpsql*
ext/sqlite3/tests/*.db
ext/sqlite3/tests/*.tmp
ext/standard/tests/misc/*.txt
ext/standard/tests/strings/*.txt
main/build-defs.h
main/internal_functions_cli.c
main/config.w32.h
main/stamp-h1
main/streams/build-defs.h
main/streams/stamp-h1
#pear/install-pear-nozlib.phar
pear/phpize
pear/run-tests
pear/php-config
pear/scripts
sapi/apache/libphp7.module
sapi/apache2handler/libphp7.module
sapi/apache_hooks/libphp7.module
sapi/cgi/php-cgi
sapi/cgi/php-cgi.1
sapi/cli/php.1
sapi/fpm/php-fpm
sapi/fpm/php-fpm.1
sapi/fpm/init.d.php-fpm
sapi/fpm/php-fpm.conf
sapi/fpm/fpm/php-cgi
sapi/phpdbg/phpdbg_parser.c
sapi/phpdbg/phpdbg_parser.h
sapi/phpdbg/phpdbg
scripts/php-config
scripts/phpize
scripts/man1/*.1
win32/*.suo
win32/*.aps
win32/*.positions
win32/ext
win32/phpts.def
win32/wsyslog.h
-60
View File
@@ -1,60 +0,0 @@
language: c
sudo: false
addons:
apt:
packages:
- locales
- language-pack-de
- re2c
- libgmp-dev
- libicu-dev
- libmcrypt-dev
- libtidy-dev
- libenchant-dev
- libaspell-dev
- libpspell-dev
- librecode-dev
- libsasl2-dev
- libxpm-dev
- libt1-dev
notifications:
email:
on_failure: change
irc:
template:
- "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} - Change view : %{compare_url} - Build details : %{build_url}"
channels:
- "irc.efnet.org#php.pecl"
on_success: change
on_failure: always
cache:
- apt
env:
global:
- MYSQL_TEST_HOST=127.0.0.1
- MYSQL_TEST_USER=travis
- PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test"
- PDO_MYSQL_TEST_USER=travis
- PDO_MYSQL_TEST_PASS=
- PDO_MYSQL_TEST_HOST=127.0.0.1
- REPORT_EXIT_STATUS=1
matrix:
- ENABLE_MAINTAINER_ZTS=0 ENABLE_DEBUG=0
- ENABLE_MAINTAINER_ZTS=1 ENABLE_DEBUG=1
before_script:
# Compile PHP
- ./travis/compile.sh
# Setup Extensions
- . ./travis/ext/mysql/setup.sh
- . ./travis/ext/mysqli/setup.sh
- . ./travis/ext/pdo_mysql/setup.sh
- . ./travis/ext/pgsql/setup.sh
- . ./travis/ext/pdo_pgsql/setup.sh
# Run PHPs run-tests.php
script:
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 1 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --set-timeout 120
+11 -36
View File
@@ -2,11 +2,11 @@
PHP Coding Standards
========================
This file lists several standards that any programmer adding or changing
code in PHP should follow. Since this file was added at a very late
This file lists several standards that any programmer, adding or changing
code in PHP, should follow. Since this file was added at a very late
stage of the development of PHP v3.0, the code base does not (yet) fully
follow it, but it's going in that general direction. Since we are now
well into version 5 releases, many sections have been recoded to use
well into the version 4 releases, many sections have been recoded to use
these rules.
Code Implementation
@@ -18,7 +18,6 @@ Code Implementation
For instance, ``function int mail(char *to, char *from)`` should NOT free
to and/or from.
Exceptions:
- The function's designated behavior is freeing that resource. E.g. efree()
@@ -43,7 +42,7 @@ Exceptions:
4. When writing functions that deal with strings, be sure to remember
that PHP holds the length property of each string, and that it
shouldn't be calculated with strlen(). Write your functions in such
shouldn't be calculated with strlen(). Write your functions in a such
a way so that they'll take advantage of the length property, both
for efficiency and in order for them to be binary-safe.
Functions that change strings and obtain their new lengths while
@@ -60,8 +59,8 @@ Exceptions:
you're calling.
7. When commenting out code using a #if statement, do NOT use 0 only. Instead
use "<git username here>_0". For example, #if FOO_0, where FOO is your
git user foo. This allows easier tracking of why code was commented out,
use "<svn username here>_0". For example, #if FOO_0, where FOO is your
svn user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
8. Do not define functions that are not available. For instance, if a
@@ -83,7 +82,7 @@ Exceptions:
library may need to control or free the memory, or when the memory in
question needs to survive between multiple requests.
User Functions/Methods Naming Conventions
Naming Conventions
------------------
1. Function names for user-level functions should be enclosed with in
@@ -113,7 +112,6 @@ User Functions/Methods Naming Conventions
of ``parent_*``::
A family of 'foo' functions, for example:
Good:
'foo_select_bar'
'foo_insert_baz'
@@ -153,7 +151,7 @@ User Functions/Methods Naming Conventions
7. Classes should be given descriptive names. Avoid using abbreviations where
possible. Each word in the class name should start with a capital letter,
without underscore delimiters (CamelCaps starting with a capital letter).
without underscore delimiters (CampelCaps starting with a capital letter).
The class name should be prefixed with the name of the 'parent set' (e.g.
the name of the extension)::
@@ -165,26 +163,6 @@ User Functions/Methods Naming Conventions
'foobar'
'foo_bar'
Internal Function Naming Convensions
----------------------
1. Functions that are part of the external API should be named
'php_modulename_function()' to avoid symbol collision. They should be in
lowercase, with words underscore delimited. Exposed API must be defined
in 'php_modulename.h'.
PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
Unexposed module function should be static and should not be defined in
'php_modulename.h'.
static int php_session_destroy()
2. Main module source file must be named 'modulename.c'.
3. Header file that is used by other sources must be named 'php_modulename.h'.
Syntax and indentation
----------------------
@@ -203,9 +181,9 @@ Syntax and indentation
of PHP or one of its standard modules, please maintain the K&R
style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration
syntax. Also see Indentstyle.
syntax. Also see Indentstyle_.
Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html
.. _Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html
3. Be generous with whitespace and braces. Keep one empty line between the
variable declaration section and the statements in a block, as well as
@@ -281,10 +259,7 @@ The file labelled 'EXPERIMENTAL' should include the following
information::
Any authoring information (known bugs, future directions of the module).
Ongoing status notes which may not be appropriate for Git comments.
In general new features should go to PECL or experimental branches until
there are specific reasons for directly adding it to the core distribution.
Ongoing status notes which may not be appropriate for SVN comments.
Aliases & Legacy Documentation
-----------------------------------
-73
View File
@@ -1,73 +0,0 @@
# Contributing to PHP
Anybody who programs in PHP can be a contributing member of the community that
develops and deploys it; the task of deploying PHP, documentation and
associated websites is a never ending one. With every release, or release
candidate comes a wave of work, which takes a lot of organization and
co-ordination.
## Pull requests
PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to
implement RFCs. Please be sure to include tests as appropriate!
If you are fixing a bug, then please submit your PR against the lowest branch
of PHP that the bug affects, or the oldest fully supported version (the first
green branch on
[the supported version page](http://php.net/supported-versions.php). For
example, at the time of writing in mid-2015, this is PHP 5.5, which corresponds
to the `PHP-5.5` branch in Git. Please also make sure you add a link to the PR
in the bug on [the bug tracker](https://bugs.php.net/).
Pull requests to implement RFCs should be submitted against `master`.
## Filing bugs
Bugs can be filed on the [PHP bug tracker](https://bugs.php.net/). If this is
the first time you've filed a bug, we suggest reading the
[guide to reporting a bug](https://bugs.php.net/how-to-report.php).
Where possible, please include a self-contained reproduction case!
## Feature requests
Feature requests are generally submitted in the form of
[Requests for Comment](https://wiki.php.net/rfc/howto), ideally accompanied by
[pull requests](#pull-requests). You can find the extremely large list of RFCs
that have been previously considered on the
[PHP Wiki](https://wiki.php.net/rfc).
You may want to read
[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process)
for additional notes on the best way to approach submitting an RFC.
## Writing tests
We love getting new tests! PHP is a huge project and improving code coverage is
a huge win for every PHP user.
[Our QA site includes a page detailing how to write test cases.](http://qa.php.net/write-test.php)
Please note that the section on submitting pull requests is outdated: in
addition to the process listed there, you can also
[submit pull requests](#pull-requests).
## Writing documentation
There are two ways to contribute to the PHP manual. You can edit the manual and
send patches anonymously via [the online editor](https://edit.php.net/), or you
can check the XML source out from Subversion and edit that and build it
[per the instructions on the documentation site](http://doc.php.net/tutorial/).
Patches created that way should be sent to the
[documentation mailing list](mailto:phpdoc@lists.php.net).
## Getting help
If you are having trouble contributing to PHP, or just want to talk to a human
about what you're working on, you can contact us via the
[internals mailing list](mailto:internals@lists.php.net), or the
[documentation mailing list](mailto:phpdoc@lists.php.net) for documentation
issues.
Although not a formal channel, you can also find a number of core developers on
the #php.pecl channel on [EFnet](http://www.efnet.org/). Similarly, many
documentation writers can be found on #php.doc.
+157791
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+122 -40
View File
@@ -26,12 +26,34 @@ Status legend
== Server APIs ==
-------------------------------------------------------------------------------
EXTENSION: aolserver
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: apache
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: apache_hooks
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: apache2filter
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: apache2handler
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>, Ilia Alshanetsky <iliaa@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: caudium
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: cgi
MAINTENANCE: Unknown
STATUS: Working
@@ -41,16 +63,19 @@ MAINTENANCE: Marcus Boerger <helly@php.net>, Edin Kadribasic <edink@php.
STATUS: Working
SINCE: 4.3.0
-------------------------------------------------------------------------------
EXTENSION: continuity
PRIMARY MAINTAINER: Alex Leigh <aleigh@php.net>
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: embed
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: fpm
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>, Jerome Loyet <fat@php.net>
MAINTENANCE: Maintained
EXTENSION: isapi
MAINTENANCE: Unknown
STATUS: Working
SINCE: 5.3.3
-------------------------------------------------------------------------------
EXTENSION: litespeed
PRIMARY MAINTAINER: George Wang <gwang@php.net>
@@ -58,9 +83,40 @@ MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: phpdbg
MAINTENANCE: Joe Watkins <krakjoe@php.net>, Bob Weinand <bwoebi@php.net>
STATUS: 5.6
EXTENSION: milter
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: nsapi
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: phttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: pi3web
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: roxen
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: thttpd
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Odd fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tux
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: webjames
PRIMARY MAINTAINER: Alex Waugh <alex@alexwaugh.com>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
@@ -74,10 +130,21 @@ STATUS: Working
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
-------------------------------------------------------------------------------
EXTENSION: interbase
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu>
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu>, Jouni Ahto <jouni.ahto@exdec.fi>
MAINTENANCE: Odd fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mssql
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Tested on phpts and isapi versions
-------------------------------------------------------------------------------
EXTENSION: mysql
PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mysqli
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Maintained
@@ -85,7 +152,7 @@ STATUS: Working
SINCE: 5.0
-------------------------------------------------------------------------------
EXTENSION: mysqlnd
PRIMARY MAINTAINER: Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlüter <johannes@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
@@ -102,14 +169,14 @@ STATUS: Working
COMMENT: Working
-------------------------------------------------------------------------------
EXTENSION: pdo
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Wez Furlong <wez@php.net>
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_dblib
PRIMARY MAINTAINER: Adam Baratz <adambaratz@php.net>
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
@@ -120,7 +187,7 @@ STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_mysql
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Johannes Schlüter <johannes@php.net>, Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>, Johannes Schlüter <johannes@php.net>, Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
@@ -132,7 +199,7 @@ STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_oci
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net>
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
@@ -144,7 +211,7 @@ STATUS: Working
SINCE: 5.1
-------------------------------------------------------------------------------
EXTENSION: pdo_sqlite
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.1
@@ -155,6 +222,13 @@ MAINTENANCE: Maintained
STATUS: Working
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
-------------------------------------------------------------------------------
EXTENSION: sqlite
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Wez Furlong <wez@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0 (Since 4.3.2 in PECL)
COMMENT: Integrates SQLite 2 embeddable SQL database engine.
-------------------------------------------------------------------------------
EXTENSION: sqlite3
PRIMARY MAINTAINER: Scott MacVicar <scottmac@php.net>
MAINTENANCE: Maintained
@@ -162,6 +236,11 @@ STATUS: Working
SINCE: 5.3
COMMENT: Integrates SQLite 3 embeddable SQL database engine.
-------------------------------------------------------------------------------
EXTENSION: sybase_ct
PRIMARY MAINTAINER: Timm Friebe <thekid@thekid.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
== XML extensions ==
@@ -252,7 +331,7 @@ MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: curl
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>, Ilia Alshanetsky <iliaa@php.net>, Pierrick Charron <pierrick@php.net>
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>,Ilia Alshanetsky <iliaa@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.2
@@ -286,7 +365,7 @@ MAINTENANCE: Odd fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gd
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net>, Christoph M. Becker <cmb@php.net>
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -300,36 +379,24 @@ MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: hash
PRIMARY MAINTAINER: Sara Golemon <pollita@php.net>, Mike Wallner <mike@php.net>, Anatol Belski <ab@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1.2
-------------------------------------------------------------------------------
EXTENSION: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: intl
PRIMARY MAINTAINER: Stanislav Malyshev <stas@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
-------------------------------------------------------------------------------
EXTENSION: imap
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>, Ilia Alshanetsky <iliaa@php.net>, Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: json
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net>
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
STATUS: Working
SINCE: 5.2
-------------------------------------------------------------------------------
EXTENSION: ldap
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>, Douglas Goldstein <cardoe@php.net>, Pierre-Alain Joye <pajoye@php.net>, Côme Bernigaud <mcmic@php.net>
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>, Douglas Goldstein <cardoe@php.net>, Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -343,11 +410,21 @@ PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: opcache
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>, Xinchen Hui <laruence@php.net>
MAINTENANCE: Maintained
EXTENSION: mhash
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>, Scott MacVicar <scottmac@php.net>
MAINTENANCE: Unknown
STATUS: Working
SINCE: 5.5.0
-------------------------------------------------------------------------------
EXTENSION: mime_magic
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Deprecated
STATUS: Experimental
COMMENT: Use the fileinfo extension instead
-------------------------------------------------------------------------------
EXTENSION: ming
PRIMARY MAINTAINER: Frank M. Kromann
MAINTENANCE: Unknown
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: openssl
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>, Pierre-Alain Joye <pajoye@php.net>
@@ -366,7 +443,7 @@ MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: phar
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net>, Marcus Börger <helly@php.net>, Steph Fox <sfox@php.net>
PRIMARY MAINTAINER: Greg Beaver <cellog@php.net>, Marcus Börger <helly@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
@@ -408,8 +485,8 @@ STATUS: Working
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: snmp
PRIMARY MAINTAINER: Boris Lytochkin <lytboris@php.net>, Rasmus Lerdorf <rasmus@php.net>, Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>, Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sockets
@@ -443,7 +520,12 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: tokenizer
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Unknown
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: unicode
MAINTENANCE: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: zip
+1140 -1518
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1,6 +1,6 @@
--------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2017 The PHP Group. All rights reserved.
Copyright (c) 1999 - 2009 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
+3 -3
View File
@@ -7,7 +7,7 @@ $(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
$(srcdir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
@@ -18,6 +18,6 @@ $(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
@$(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)
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
$(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(srcdir)/zend_language_parser.h
+27 -27
View File
@@ -3,19 +3,33 @@
# LCOV
#
LCOV_INCLUDE="."
lcov: lcov-html
lcov-test: lcov-clean-data test
lcov-test: all
@echo "Running test suite"
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
NO_INTERACTION=1 \
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(PHP_EXECUTABLE) -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php -d 'extension_dir=modules/' -d `( . $(PHP_MODULES) ; echo extension=$$dlname)` tests/; \
elif test ! -z "$(SAPI_CLI_PATH)" && test -x "$(SAPI_CLI_PATH)"; then \
NO_INTERACTION=1 \
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1' $(top_srcdir)/run-tests.php $(TESTS); \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
php_lcov.info: lcov-test
@echo "Generating data for $@"
@rm -rf lcov_data/
@$(mkinstalldirs) lcov_data/
@echo
-@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.c -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | $(EGREP) $(LCOV_INCLUDE) | sed -e 's/.libs/zzzz/g' | sort | sed -e 's/zzzz/.libs/g' | uniq` ;\
for x in $$files; do \
-@find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | uniq | while read x; do \
echo -n . ;\
y=`echo $$x | sed -e 's!\.libs/!!'`; \
dir=lcov_data/`dirname $$x`; \
@@ -41,26 +55,14 @@ php_lcov.info: lcov-test
if test -f "$(top_builddir)/$$y.c"; then \
ln -f -s $(top_builddir)/$$y.c lcov_data/$$y.c; \
fi; \
if test -f "$$x.gcno"; then \
cp $$x.gcno lcov_data/$$y.gcno ; \
fi; \
if test -f "$$x.gcda"; then \
cp $$x.gcda lcov_data/$$y.gcda ; \
fi; \
if test -f "$$x.da"; then \
cp $$x.da lcov_data/$$y.da ; \
fi; \
if test -f "$$x.bb"; then \
cp $$x.bb lcov_data/$$y.bb ; \
fi; \
if test -f "$$x.bbg"; then \
cp $$x.bbg lcov_data/$$y.bbg ; \
fi; \
done; \
for dir in ext/bcmath/libbcmath ext/date/lib ext/fileinfo/libmagic ext/gd/libgd ext/mbstring/libmbfl ext/mbstring/oniguruma ext/pcre/pcrelib ext/pdo_sqlite/libsqlite ext/sqlite3/libsqlite ext/xmlrpc/libxmlrpc ext/zip/lib; do \
if test -d lcov_data/$$dir; then \
rm -rf lcov_data/$$dir ; \
fi; \
test -f "$$x.gcno" && cp $$x.gcno lcov_data/$$y.gcno ; \
test -f "$$x.gcda" && cp $$x.gcda lcov_data/$$y.gcda ; \
test -f "$$x.da" && cp $$x.da lcov_data/$$y.da ; \
test -f "$$x.bb" && cp $$x.bb lcov_data/$$y.bb ; \
test -f "$$x.bbg" && cp $$x.bbg lcov_data/$$y.bbg ; \
done
for dir in ext/bcmath/libbcmath ext/fileinfo/libmagic ext/gd/libgd ext/mbstring/libmbfl ext/mbstring/oniguruma ext/pcre/pcrelib ext/pdo_sqlite/libsqlite ext/sqlite/libsqlite ext/sqlite3/libsqlite ext/xmlrpc/libxmlrpc ext/zip/lib; do \
test -d lcov_data/$$dir && rm -rf lcov_data/$$dir ; \
done
@echo
@echo "Generating $@"
@@ -75,5 +77,3 @@ lcov-clean:
rm -rf lcov_data/
rm -rf lcov_html/
lcov-clean-data:
@find . -name \*.gcda -o -name \*.da -o -name \*.bbg? | xargs rm -f
+6 -35
View File
@@ -10,11 +10,9 @@ all: $(all_targets)
@echo "Build complete."
@echo "Don't forget to run 'make test'."
@echo
build-modules: $(PHP_MODULES) $(PHP_ZEND_EX)
build-binaries: $(PHP_BINARIES)
libphp$(PHP_MAJOR_VERSION).la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
@@ -37,8 +35,6 @@ install-sapi: $(OVERALL_TARGET)
fi
@$(INSTALL_IT)
install-binaries: build-binaries $(install_binary_targets)
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
@@ -83,10 +79,10 @@ PHP_TEST_SHARED_EXTENSIONS = ` \
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d $(ZEND_EXT_TYPE)=$(top_builddir)/modules/$$dlname"; \
done; \
fi`
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(define_syslog_variables|register_(globals|long_arrays)?|safe_mode|safe_mode_(gid|include_dir|exec_dir|allowed_env_vars|protected_env_vars)?|highlight_bg|enable_dl|detect_unicode|allow_call_time_pass_reference|magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
test: all
@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
if test "$$INI_FILE"; then \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
@@ -102,9 +98,6 @@ test: all
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
TEST_RESULT_EXIT_CODE=$$?; \
rm $(top_builddir)/tmp-php.ini; \
exit $$TEST_RESULT_EXIT_CODE; \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
@@ -115,33 +108,11 @@ clean:
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_MILTER_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
distclean: clean
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module sapi/apache_hooks/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h
rm -f php7.spec main/build-defs.h scripts/phpize
rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/oci8/oci8_dtrace_gen.h ext/oci8/oci8_dtrace_gen.h.bak
rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 ext/phar/phar.1 ext/phar/phar.phar.1
rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
rm -f 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_supports_errno.h ext/iconv/php_php_iconv_h_path.h ext/iconv/php_php_iconv_impl.h
rm -f ext/phar/phar.phar ext/phar/phar.php
if test "$(srcdir)" != "$(builddir)"; then \
rm -f ext/phar/phar/phar.inc; \
fi
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp
$(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f
prof-gen:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-generate all
prof-clean:
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_MILTER_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
prof-use:
CCACHE_DISABLE=1 $(MAKE) PROF_FLAGS=-fprofile-use all
.PHONY: all clean install distclean test prof-gen prof-clean prof-use
.PHONY: all clean install distclean test
.NOEXPORT:
+44 -2463
View File
File diff suppressed because it is too large. Load diff
+39
View File
@@ -0,0 +1,39 @@
Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
that broke both source and binary compatibility. If you are
maintaining a third party extension, here's how to update it:
If this was your old module entry:
zend_module_entry foo_module_entry = {
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
STANDARD_MODULE_PROPERTIES
};
Here's how it should look if you want your code to build with PHP
4.1.0 and up:
zend_module_entry foo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
#if ZEND_MODULE_API_NO >= 20010901
FOO_VERSION, /* extension version number (string) */
#endif
STANDARD_MODULE_PROPERTIES
};
If you don't care about source compatibility with earlier PHP releases
than 4.1.0, you can drop the #if/#endif lines.
+54 -48
View File
@@ -31,11 +31,6 @@ HOW TO USE IT
./buildconf; ./configure --enable-module_name; make
The definition of PHP_MODULE_NAME_VERSION will be present in the
php_module_name.h and injected into the zend_module_entry definition. This
is required by the PECL website for the version string conformity checks
against package.xml
But if you already have planned the overall scheme of your module, what
functions it will contain, their return types and the arguments they take
(a very good idea) and don't want to bother yourself with creating function
@@ -45,29 +40,12 @@ HOW TO USE IT
--proto=filename.
SOURCE AND HEADER FILE NAME
./ext_skel generates 'module_name.c' and 'php_module_name.h' as main source
and header files. Keep these names.
Module functions (User functions) must be named
module_name_function()
When you need to expose module functions to other modules, expose functions
strictly needed by others. Exposed internal function must be named
php_module_name_function()
See also CODING_STANDARDS.
FORMAT OF FUNCTION DEFINITIONS FILE
All the definitions must be on one line. In it's simplest form, it's just
the function name, e.g.
module_name_function
my_function
but then you'll be left with an almost empty function body without any
argument handling.
@@ -89,9 +67,8 @@ FORMAT OF FUNCTION DEFINITIONS FILE
An example:
module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]])
my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st
Arguments arg1 and arg2 are required.
Arguments arg3 and arg4 are optional.
If possible, the function definition should also contain it's return type
@@ -119,7 +96,29 @@ OTHER OPTIONS
function entries and definitions at the end of the file, for copying and
pasting into an already existing module.
--xml[=file]
--assign-params
--string-lens
By default, function proto 'void foo(string bar)' creates the following:
...
zval **bar;
... (zend_get_parameters_ex() called in the middle...)
convert_to_string_ex(bar);
Specifying both of these options changes the generated code to:
...
zval **bar_arg;
int bar_len;
char *bar = NULL;
... (zend_get_parameters_ex() called in the middle...)
convert_to_string_ex(bar_arg);
bar = Z_STRVAL_PP(bar_arg);
bar_len = Z_STRLEN_PP(bar_arg);
You shouldn't have to ask what happens if you leave --string-lens out. If you
have to, it's questionable whether you should be reading this document.
--with-xml[=file]
Creates the basics for phpdoc .xml file.
@@ -151,38 +150,45 @@ EXAMPLE
The following _one_ line
bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color])
bool my_drawtext(resource image, string text, resource font, int x, int y [, int color])
will create this function definition for you (note that there are a few
question marks to be replaced by you, and you must of course add your own
value definitions too):
/* {{{ proto bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color])
/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y[, int color])
*/
PHP_FUNCTION(module_name_drawtext)
PHP_FUNCTION(my_drawtext)
{
char *text = NULL;
int argc = ZEND_NUM_ARGS();
int image_id = -1;
size_t text_len;
int font_id = -1;
zend_long x;
zend_long y;
zend_long color;
zval *image = NULL;
zval *font = NULL;
zval **image, **text, **font, **x, **y, **color;
int argc;
int image_id = -1;
int font_id = -1;
if (zend_parse_parameters(argc, "rsrll|l", &image, &text, &text_len, &font, &x, &y, &color) == FAILURE)
return;
argc = ZEND_NUM_ARGS();
if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &image, &text, &font, &x, &y, &color) == FAILURE) {
WRONG_PARAM_COUNT;
}
if (image) {
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
}
if (font) {
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
}
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
php_error(E_WARNING, "module_name_drawtext: not yet implemented");
switch (argc) {
case 6:
convert_to_long_ex(color);
/* Fall-through. */
case 5:
convert_to_long_ex(y);
convert_to_long_ex(x);
/* font: fetching resources already handled. */
convert_to_string_ex(text);
/* image: fetching resources already handled. */
break;
default:
WRONG_PARAM_COUNT;
}
php_error(E_WARNING, "my_drawtext: not yet implemented");
}
/* }}} */
-133
View File
@@ -1,133 +0,0 @@
====================
Git Commit Rules
====================
This is the first file you should be reading when contributing code via Git.
We'll assume you're basically familiar with Git, but feel free to post
your questions on the mailing list. Please have a look at
http://git-scm.com/ for more detailed information on Git.
PHP is developed through the efforts of a large number of people.
Collaboration is a Good Thing(tm), and Git lets us do this. Thus, following
some basic rules with regards to Git usage will::
a. Make everybody happier, especially those responsible for maintaining
PHP itself.
b. Keep the changes consistently well documented and easily trackable.
c. Prevent some of those 'Oops' moments.
d. Increase the general level of good will on planet Earth.
Having said that, here are the organizational rules::
1. Respect other people working on the project.
2. Discuss any significant changes on the list before committing and get
confirmation from the release manager for the given branch.
3. Look at EXTENSIONS file to see who is the primary maintainer of
the code you want to contribute to.
4. If you "strongly disagree" about something another person did, don't
start fighting publicly - take it up in private email.
5. If you don't know how to do something, ask first!
6. Test your changes before committing them. We mean it. Really.
To do so use "make test".
7. For development use the --enable-maintainer-zts switch to ensure your
code handles TSRM correctly and doesn't break for those who need that.
Currently we have the following branches in use::
master The active development branch.
PHP-5.6 Is used to release the PHP 5.6.x series. This is a current
stable version and is open for bugfixes only.
PHP-5.5 Is used to release the PHP 5.5.x series. This is an old
stable version and is open for security fixes only.
PHP-5.4 Is used to release the PHP 5.4.x series. This is an old
stable version and is open for security fixes only.
PHP-5.3 This branch is closed.
PHP-5.2 This branch is closed.
PHP-5.1 This branch is closed.
PHP-4.4 This branch is closed.
PHP-X.Y.Z These branches are used for the release managers for tagging
the releases, hence they are closed to the general public.
The next few rules are more of a technical nature::
1. All changes should first go to the lowest branch (i.e. 5.6) and then
get merged up to all other branches. If a change is not needed for
later branches (i.e. fixes for features which where dropped from later
branches) an empty merge should be done.
2. All news updates intended for public viewing, such as new features,
bug fixes, improvements, etc., should go into the NEWS file of *any
stable release* version with the given change. In other words,
news about a bug fix which went into PHP-5.4, PHP-5.5 and master
should be noted in both PHP-5.4/NEWS and PHP-5.5/NEWS but
not master, which is not a public released version yet.
3. Do not commit multiple file and dump all messages in one commit. If you
modified several unrelated files, commit each group separately and
provide a nice commit message for each one. See example below.
4. Do write your commit message in such a way that it makes sense even
without the corresponding diff. One should be able to look at it, and
immediately know what was modified. Definitely include the function name
in the message as shown below.
5. In your commit messages, keep each line shorter than 80 characters. And
try to align your lines vertically, if they wrap. It looks bad otherwise.
6. If you modified a function that is callable from PHP, prepend PHP to
the function name as shown below.
The format of the commit messages is pretty simple.
<max 79 characters short description>\n
\n
<long description, 79 chars per line>
\n
An Example from the git project (commit 2b34e486bc):
pack-objects: Fix compilation with NO_PTHREDS
It looks like commit 99fb6e04 (pack-objects: convert to use
parse_options(), 2012-02-01) moved the #ifdef NO_PTHREDS around but
hasn't noticed that the 'arg' variable no longer is available.
If you fix some bugs, you should note the bug ID numbers in your
commit message. Bug ID should be prefixed by "#" for easier access to
bug report when developers are browsing CVS via LXR or Bonsai.
Example:
Fixed bug #14016 (pgsql notice handler double free crash bug.)
When you change the NEWS file for a bug fix, then please keep the bugs
sorted in decreasing order under the fixed version.
You can use OpenGrok (http://lxr.php.net/) and gitweb (http://git.php.net/)
to look at PHP Git repository in various ways.
For further information on the process and further details please refer to
https://wiki.php.net/vcs/gitworkflow and https://wiki.php.net/vcs/gitfaq
Happy hacking,
PHP Team
+38 -38
View File
@@ -1,4 +1,4 @@
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
$Id$
API adjustment to the old output control code:
@@ -8,98 +8,98 @@ API adjustment to the old output control code:
Checking output control layers status:
// Using OG()
php_output_get_status();
php_output_get_status(TSRMLS_C);
Starting the default output handler:
// php_start_ob_buffer(NULL, 0, 1);
php_output_start_default();
// php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
php_output_start_default(TSRMLS_C);
Starting an user handler by zval:
// php_start_ob_buffer(zhandler, chunk_size, erase);
php_output_start_user(zhandler, chunk_size, flags);
// php_start_ob_buffer(zhandler, chunk_size, erase TSRMLS_CC);
php_output_start_user(zhandler, chunk_size, flags TSRMLS_CC);
Starting an internal handler whithout context:
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase);
php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags);
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
php_output_start_internal(handler_name_zval, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
Starting an internal handler with context:
// not possible with old API
php_output_handler *h;
h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags);
h = php_output_handler_create_internal(handler_name_zval, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
php_output_handler_set_context(h, my_context, my_context_dtor);
php_output_handler_start(h);
php_output_handler_start(h TSRMLS_CC);
Testing whether a certain output handler has already been started:
// php_ob_handler_used("output handler name");
php_output_handler_started(handler_name, handler_name_len);
// php_ob_handler_used("output handler name" TSRMLS_CC);
php_output_handler_started(handler_name_zval TSRMLS_CC);
Flushing one output buffer:
// php_end_ob_buffer(1, 1);
php_output_flush();
// php_ob_end_buffer(1, 1 TSRMLS_CC);
php_output_flush(TSRMLS_C);
Flushing all output buffers:
// not possible with old API
php_output_flush_all();
php_output_flush_all(TSRMLS_C);
Cleaning one output buffer:
// php_ob_end_buffer(0, 1);
php_output_clean();
// php_ob_end_buffer(0, 1 TSRMLS_CC);
php_output_clean(TSRMLS_C);
Cleaning all output buffers:
// not possible with old API
php_output_clean_all();
php_output_clean_all(TSRMLS_C);
Discarding one output buffer:
// php_ob_end_buffer(0, 0);
php_output_discard();
// php_ob_end_buffer(0, 0 TSRMLS_CC);
php_output_discard(TSRMLS_C);
Discarding all output buffers:
// php_ob_end_buffers(0);
php_output_discard_all();
// php_ob_end_buffers(0 TSRMLS_CC);
php_output_discard_all(TSRMLS_C);
Stopping (and dropping) one output buffer:
// php_ob_end_buffer(1, 0)
php_output_end();
// php_ob_end_buffer(1, 0 TSRMLS_CC)
php_output_end(TSRMLS_C);
Stopping (and dropping) all output buffers:
// php_ob_end_buffers(1, 0);
php_output_end_all();
// php_ob_end_buffers(1, 0 TSRMLS_CC);
php_output_end_all(TSRMLS_C);
Retrieving output buffers contents:
// php_ob_get_buffer(zstring);
php_output_get_contents(zstring);
// php_ob_get_buffer(zstring TSRMLS_CC);
php_output_get_contents(zstring TSRMLS_CC);
Retrieving output buffers length:
// php_ob_get_length(zlength);
php_output_get_length(zlength);
// php_ob_get_length(zlength TSRMLS_CC);
php_output_get_length(zlength TSRMLS_CC);
Retrieving output buffering level:
// OG(nesting_level);
php_output_get_level();
php_output_get_level(TSRMLS_C);
Issue a warning because of an output handler conflict:
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name");
php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len);
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
php_output_handler_conflict(new_handler_name_zval, set_handler_name_zval TSRMLS_CC);
Registering a conflict checking function, which will be checked prior starting the handler:
// not possible with old API, unless hardcoding into output.c
php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t);
php_output_handler_conflict_register(handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
// not possible with old API
php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t);
php_output_handler_reverse_conflict_register(foreign_handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Facilitating a context from within an output handler callable with ob_start():
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr);
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr TSRMLS_CC);
Disabling of the output handler by itself:
//not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL);
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL TSRMLS_CC);
Marking an output handler immutable by itself because of irreversibility of its operation:
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL);
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
Restarting the output handler because of a CLEAN operation:
// not possible with old API
+114 -56
View File
@@ -13,8 +13,8 @@ meaningful error messages.
Prototypes
----------
/* Implemented. */
int zend_parse_parameters(int num_args, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args, char *type_spec, ...);
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
The zend_parse_parameters() function takes the number of parameters
passed to the extension function, the type specifier string, and the
@@ -28,29 +28,18 @@ Both functions return SUCCESS or FAILURE depending on the result.
The auto-conversions are performed as necessary. Arrays, objects, and
resources cannot be auto-converted.
PHP 5.5 includes a new function:
int zend_parse_parameter(int flags, int arg_num, zval **arg, const char *spec, ...);
This function behaves like zend_parse_parameters_ex() except that instead of
reading the arguments from the stack, it receives a single zval to convert
(passed with double indirection). The passed zval may be changed in place as
part of the conversion process.
See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter
Type specifiers
---------------
The following list shows the type specifier, its meaning and the parameter
types that need to be passed by address. All passed parameters are set
types that need to be passed by address. All passed paramaters are set
if the PHP parameter is non optional and untouched if optional and the
parameter is not present. The only exception is O where the zend_class_entry*
has to be provided on input and is used to verify the PHP parameter is an
instance of that class.
a - array (zval*)
A - array or object (zval*)
A - array or object (zval *)
b - boolean (zend_bool)
C - class (zend_class_entry*)
d - double (double)
@@ -58,16 +47,23 @@ Type specifiers
zend_fcall_info and zend_fcall_info_cache)
h - array (returned as HashTable*)
H - array or HASH_OF(object) (returned as HashTable*)
l - long (zend_long)
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN)
l - long (long)
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (long)
o - object of any type (zval*)
O - object of specific type given by class entry (zval*, zend_class_entry)
p - valid path (string without null bytes in the middle) and its length (char*, size_t)
P - valid path (string without null bytes in the middle) as zend_string (zend_string*)
r - resource (zval*)
s - string (with possible null bytes) and its length (char*, size_t)
S - string (with possible null bytes) as zend_string (zend_string*)
s - string (with possible null bytes) and its length (char*, int)
S - binary string, does not allow conversion from Unicode strings
t - text (zstr (string union), int (length), zend_uchar (IS_STRING/..))
accepts either Unicode or binary string
T - text (zstr (string union), int (length), zend_uchar (IS_STRING/..))
coalesces all T parameters to common type (Unicode or binary)
u - unicode (UChar*, int)
U - Unicode string, does not allow conversion from binary strings
x - Unicode or binary string depending on UG(unicode). In unicode this
behaves like 'u' and in nonunicode mode it behaves like 's'.
z - the actual zval (zval*)
Z - the actual zval (zval**)
* - variable arguments list (0 or more)
+ - variable arguments list (1 or more)
@@ -77,31 +73,33 @@ Type specifiers
will not be touched by the parsing function if they are not
passed to it.
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
! - the parameter it follows can be of specified type or NULL. If NULL is
passed and the output for such type is a pointer, then the output
pointer is set to a native NULL pointer.
For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
passed after the corresponding bool*, zend_long* or double* arguments,
respectively. A non-zero value will be written to the zend_bool if a
PHP NULL is passed.
! - the parameter it follows can be of specified type or NULL (applies
to all specifiers except for 'b', 'l', and 'd'). If NULL is passed, the
results pointer is set to NULL as well.
& - alternate format (currently used for 's' only to specify a converter to
use when converting from Unicode strings)
^ - returns original string type before conversion (only for 's' and 'u'
specifiers)
Note on 64bit compatibility
---------------------------
Please note that since version 7 PHP uses zend_long as integer type and
zend_string with size_t as length, so make sure you pass zend_longs to "l"
and size_t to strings length (i.e. for "s" you need to pass char * and size_t),
Please do not forget that int and long are two different things on 64bit
OSes (int is 4 bytes and long is 8 bytes), so make sure you pass longs to "l"
and ints to strings length (i.e. for "s" you need to pass char * and int),
not the other way round!
Remember: "l" is the only case when you need to pass long (and that's why
it's "l", not "i" btw).
Both mistakes might cause memory corruptions and segfaults:
Both mistakes cause memory corruptions and segfaults on 64bit OSes:
1)
char *str;
long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */
zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len)
long str_len; /* XXX THIS IS WRONG!! Use int instead. */
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len)
2)
int num; /* XXX THIS IS WRONG!! Use zend_long instead. */
zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num)
int num; /* XXX THIS IS WRONG!! Use long instead. */
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num)
If you're in doubt, use check_parameters.php script to the parameters
and their types (it can be found in ./scripts/dev/ directory of PHP sources):
@@ -112,11 +110,11 @@ and their types (it can be found in ./scripts/dev/ directory of PHP sources):
Examples
--------
/* Gets a long, a string and its length, and a zval */
zend_long l;
long l;
char *s;
size_t s_len;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsz",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
&l, &s, &s_len, &param) == FAILURE) {
return;
}
@@ -126,7 +124,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsz",
zval *obj;
double d = 0.5;
zend_class_entry *my_ce;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|d",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
}
@@ -136,7 +134,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|d",
If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
&obj, &arr) == FAILURE) {
return;
}
@@ -144,27 +142,77 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a",
/* Gets a separated array which can also be null. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/!",
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
&arr) == FAILURE) {
return;
}
/* Gets a binary string in UTF-8 */
char *str;
int str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &str, &str_len, UG(utf8_conv)) == FAILURE) {
return;
}
/* Gets a Unicode string */
UChar *str;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "u", &str, &len) == FAILURE) {
return;
}
/* Gets a Unicode or binary string */
zstr str;
int len;
zend_uchar type;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &str, &len, &type) == FAILURE) {
return;
}
if (type == IS_UNICODE) {
/* process str.u as Unicode string */
} else {
/* process str.s binary string */
}
/* Gets two string parameters, both of which will be guaranteed to be of the same type */
zstr str1, str2;
int len1, len2;
zend_uchar type1, type2;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TT", &str1, &len1,
&type1, &str2, &len2, &type2) == FAILURE) {
return;
}
if (type1 == IS_UNICODE) {
/* process as Unicode, str2 is guaranteed to be Unicode as well */
} else {
/* process as binary string, str2 is guaranteed to be the same */
}
/* Get either a set of 3 longs or a string. */
zend_long l1, l2, l3;
long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a size_t in this case, not a long
* The function expects a pointer to a integer in this case, not a long
* or any other type. If you specify a type which is larger
* than a 'size_t', the upper bits might not be initialized
* than a 'int', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
size_t length;
int length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lll", &l1, &l2, &l3) == SUCCESS) {
/* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"s", &s, &length) == SUCCESS) {
/* manipulate string */
} else {
@@ -177,10 +225,10 @@ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
/* Function that accepts only varargs (0 or more) */
int i, num_varargs;
zval *varargs = NULL;
zval ***varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &varargs, &num_varargs) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &varargs, &num_varargs) == FAILURE) {
return;
}
@@ -196,11 +244,11 @@ if (varargs) {
/* Function that accepts a string, followed by varargs (1 or more) */
char *str;
size_t str_len;
int str_len;
int i, num_varargs;
zval *varargs = NULL;
zval ***varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s+", &str, &str_len, &varargs, &num_varargs) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s+", &str, &str_len, &varargs, &num_varargs) == FAILURE) {
return;
}
@@ -208,16 +256,26 @@ for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
if (varargs) {
efree(varargs);
}
/* Function that takes an array, followed by varargs, and ending with a long */
zend_long num;
long num;
zval *array;
int i, num_varargs;
zval *varargs = NULL;
zval ***varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a*l", &array, &varargs, &num_varargs, &num) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a*l", &array, &varargs, &num_varargs, &num) == FAILURE) {
return;
}
for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
if (varargs) {
efree(varargs);
}
+11
View File
@@ -0,0 +1,11 @@
To install the PEAR installer, please use go-pear.
On linux:
$ lynx -source http://pear.php.net/go-pear | php
or save the setup script under go-pear.php and run:
php go-pear.php
For more informations see the PEAR manual:
http://pear.php.net/manual/en/installation.getting.php
+155
View File
@@ -0,0 +1,155 @@
1. strrpos() and strripos() now use the entire string as a needle. Be aware
that the existing scripts may no longer work as you expect.
EX :
<?php
var_dump(strrpos("ABCDEF","DEF"));
var_dump(strrpos("ABCDEF","DAF"));
?>
Will give you different results. The former returns 3 while the latter
returns false rather than the position of the last occurrence of 'D'.
The same applies to strripos().
2. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
EX :
<?php
$a = "foo";
unset($a[0][1][2]);
?>
Fatal error: Cannot use string offset as an array in ... on line 1
3. array_merge() was changed to accept only arrays. If a non-array variable is
passed, a E_WARNING will be thrown for every such parameter. Be careful
because your code may start emitting E_WARNING out of the blue.
4. Be careful when porting from ext/mysql to ext/mysqli. The following
functions return NULL when no more data is available in the result set
(ext/mysql's functions return FALSE).
- mysqli_fetch_row()
- mysqli_fetch_array()
- mysqli_fetch_assoc()
5. PATH_TRANSLATED server variable is no longer set implicitly under
Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
same value as the SCRIPT_FILENAME server variable when it is not populated
by Apache. This change was made to comply with the CGI specification.
Please refer to bug #23610 for further information.
6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
ext/tokenizer extension. If error_reporting is set to E_ALL notices will
be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant
is used, thus both // and /* */ are resolved as the T_COMMENT constant.
However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
by PHP, are recongnized as T_DOC_COMMENT.
7. $_SERVER should be populated with argc and argv if variables_order
includes "S". If you have specifically configured your system to not
create $_SERVER, then of course it shouldn't be there. The change was to
always make argc and argv available in the CLI version regardless of the
variables_order setting. As in, the CLI version will now always populate
the global $argc and $argv variables.
8. In some cases classes must be declared before used. It only happens only
if some of the new features of PHP 5 are used. Otherwise the behaviour is
the old.
Example 1 (works with no errors):
<?php
$a = new a();
class a {
}
?>
Example 2 (throws an error):
<?php
$a = new a();
interface b{
}
class a implements b {
}
?>
Output (example 2) :
Fatal error: Class 'a' not found in /tmp/cl.php on line 2
9. get_class() starting PHP 5 returns the name of the class as it was
declared which may lead to problems in older scripts that rely on
the previous behaviour - the class name is lowercased. Expect the
same behaviour from get_parent_class() when applicable.
Example :
<?php
class FooBar {
}
class ExtFooBar extends FooBar{}
$a = new FooBar();
var_dump(get_class($a), get_parent_class($a));
?>
Output (PHP 4):
string(6) "foobar"
string(9) "extfoobar"
Output (PHP 5):
string(6) "FooBar"
string(9) "ExtFooBar"
----------------------------------------------------------------------
Example code that will break :
//....
function someMethod($p) {
if (get_class($p) != 'helpingclass') {
return FALSE;
}
//...
}
//...
Possible solution is to search for get_class() and get_parent_class() in
all your scripts and use strtolower().
10. get_class_methods() returns the names of the methods of a class as they
declared. In PHP4 the names are all lowercased.
Example code :
<?php
class Foo{
function doFoo(){}
function hasFoo(){}
}
var_dump(get_class_methods("Foo"));
?>
Output (PHP4):
array(2) {
[0]=>
string(5) "dofoo"
[1]=>
string(6) "hasfoo"
}
Output (PHP5):
array(2) {
[0]=>
string(5) "doFoo"
[1]=>
string(6) "hasFoo"
}
11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
meaning in class methods and is recognized by the PHP parser. The latter
will generate a parse error when assignment to $this is found
Example code :
<?php
class Foo {
function assignNew($obj) {
$this = $obj;
}
}
$a = new Foo();
$b = new Foo();
$a->assignNew($b);
echo "I was executed\n";
?>
Output (PHP 4):
I was executed
Output (PHP 5):
PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4
+57
View File
@@ -0,0 +1,57 @@
QNX4 Installation Notes
-----------------------
NOTE: General installation instructions are in the INSTALL file
1. To compile and test PHP3 you have to grab, compile and install:
- GNU dbm library or another db library;
- GNU bison (1.25 or later; 1.25 tested);
- GNU flex (any version supporting -o and -P options; 2.5.4 tested);
- GNU diffutils (any version supporting -w option; 2.7 tested);
2. To use CVS version you may need also:
- GNU CVS (1.9 tested);
- GNU autoconf (2.12 tested);
- GNU m4 (1.3 or later preferable; 1.4 tested);
3. To run configure define -lunix in command line:
LDFLAGS=-lunix ./configure
4. To use Sybase SQL Anywhere define ODBC_QNX and CUSTOM_ODBC_LIBS in
command line and run configure with --with-custom-odbc:
CFLAGS=-DODBC_QNX LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc" ./configure --with-custom-odbc=/usr/lib/sqlany50
If you have SQL Anywhere version 5.5.00, then you have to add
CFLAGS=-DSQLANY_BUG
to workaround its SQLFreeEnv() bug. Other versions has not been tested,
so try without this flag first.
5. To build the Apache module, you may have to hardcode an include path for
alloc.h in your Apache base directory:
- APACHE_DIRECTORY/src/httpd.h:
change #include "alloc.h"
to #include "APACHE_DIRECTORY/src/alloc.h"
Unless you want to use system regex library, you have to hardcode also
a path to regex.h:
- APACHE_DIRECTORY/src/conf.h:
change #include <regex.h>
to #include "APACHE_DIRECTORY/src/regex/regex.h"
I don't know so far why this required for QNX, may be it is Watcom
compiler problem.
If you building Apache module with SQL Anywhere support, you'll get
symbol conflict with BOOL. It is defined in Apache (httpd.h) and in
SQL Anywhere (odbc.h). This has nothing to do with PHP, so you have to
fix it yourself someway.
6. With above precautions, it should compile as is and pass regression
tests completely:
make
make check
make install
Don't bother me unless you really sure you made that all but it
still doesn't work.
June 28, 1998
Igor Kovalenko -- owl@infomarket.ru
+51 -39
View File
@@ -5,16 +5,17 @@
5. ext/standard crypt
6. ext/standard crypt's blowfish implementation
7. Sqlite/Sqlite3 ext/sqlite3 ext/sqlite
8. ext/standard/rand
9. ext/standard/scanf
10. ext/standard/strnatcmp.c
11. ext/standard/uuencode
12. libxmlrpc ext/xmlrpc
13. libzip ext/zip
14. main/snprintf.c
15. main/strlcat
16. main/strlcpy
17. libgd see ext/gd/libgd/COPYING
8. ext/json/json_parser
9. ext/standard/rand
10. ext/standard/scanf
11. ext/standard/strnatcmp.c
12. ext/standard/uuencode
13. libxmlrpc ext/xmlrpc
14. libzip ext/zip
15. main/snprintf.c
16. main/strlcat
17. main/strlcpy
18. libgd see ext/gd/libgd/COPYING
5. ext/standard crypt
@@ -50,40 +51,27 @@ SUCH DAMAGE.
6. ext/standard crypt's blowfish implementation
The crypt_blowfish homepage is:
http://www.openwall.com/crypt/
This code comes from John the Ripper password cracker, with reentrant
and crypt(3) interfaces added, but optimizations specific to password
cracking removed.
Written by Solar Designer <solar at openwall.com> in 1998-2011.
No copyright is claimed, and the software is hereby placed in the public
domain. In case this attempt to disclaim copyright and place the software
in the public domain is deemed null and void, then the software is
Copyright (c) 1998-2011 Solar Designer and it is hereby released to the
general public under the following terms:
Written by Solar Designer <solar at openwall.com> in 1998-2002 and
placed in the public domain.
Redistribution and use in source and binary forms, with or without
modification, are permitted.
There's ABSOLUTELY NO WARRANTY, express or implied.
There's absolutely no warranty.
It is my intent that you should be able to use this on your system,
as part of a software package, or anywhere else to improve security,
as a part of a software package, or anywhere else to improve security,
ensure compatibility, or for any other purpose. I would appreciate
it if you give credit where it is due and keep your modifications in
the public domain as well, but I don't require that in order to let
you place this code and any modifications you make under a license
of your choice.
This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
"$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
This implementation is compatible with OpenBSD bcrypt.c (version 2a)
by Niels Provos <provos at citi.umich.edu>, and uses some of his
ideas. The password hashing algorithm was designed by David Mazieres
<dm at lcs.mit.edu>. For more information on the level of compatibility,
please refer to the comments in BF_set_key() and to the crypt(3) man page
included in the crypt_blowfish tarball.
<dm at lcs.mit.edu>.
There's a paper on the algorithm that explains its design decisions:
@@ -103,7 +91,31 @@ a legal notice, here is a blessing:
May you share freely, never taking more than you give.
8. ext/standard/rand
8. ext/json/json_parser
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
9. ext/standard/rand
The following php_mt_...() functions are based on a C++ class MTRand by
Richard J. Wagner. For more information see the web page at
http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html
@@ -156,7 +168,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9. ext/standard/scanf
10. ext/standard/scanf
scanf.c --
This file contains the base code which implements sscanf and by extension
@@ -202,7 +214,7 @@ authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.
10. ext/standard/strnatcmp.c
11. ext/standard/strnatcmp.c
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
@@ -223,7 +235,7 @@ freely, subject to the following restrictions:
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
11. ext/standard/uuencode
12. ext/standard/uuencode
Portions of this code are based on Berkeley's uuencode/uudecode
implementation.
@@ -259,7 +271,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
12. libxmlrpc ext/xmlrpc
13. libxmlrpc ext/xmlrpc
Copyright 2000 Epinions, Inc.
@@ -283,7 +295,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
DAMAGES.
13. libzip ext/zip
14. libzip ext/zip
zip.h -- exported declarations.
Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
@@ -315,7 +327,7 @@ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14. main/snprintf.c
15. main/snprintf.c
Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
@@ -388,8 +400,8 @@ This code is based on, and used with the permission of, the
SIO stdio-replacement strx_* functions by Panos Tsirigotis
<panos@alumni.cs.colorado.edu> for xinetd.
15. main/strlcat
16. main/strlcpy
16. main/strlcat
17. main/strlcpy
Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
All rights reserved.
+124 -155
View File
@@ -8,41 +8,24 @@ General notes and tips
1. Do not release on Fridays, Saturdays or Sundays
because the sysadmins can not upgrade stuff then.
2. Package two days before a release. So if the release is to be on Thursday,
package on Tuesday. Think about timezones as well.
2. Package the day before a release. So if the release is to be on Thursday,
package on Wednesday.
3. Ensure that the tests on Travis CI are green.
See: https://travis-ci.org/php/php-src/builds
It is recommended to do so a couple of days before the packaging day, to
have enough time to investigate failures, communicate with the authors and
commit the fixes.
The RM for the branch is also responsible for keeping the CI green on
ongoing bases between the releases. Check the CI status for your branch
periodically and resolve the failures ASAP. See more in:
https://wiki.php.net/rfc/travis_ci
3. Ensure that Windows builds will work before packaging
4. Ensure that Windows builds will work before packaging
4. Follow all steps to the letter. When unclear ask previous RM's (Derick/Ilia)
before proceeding. Ideally make sure that for the first releases one of the
previous RM's is around to answer questions. For the steps related to the
php/QA/bug websites try to have someone from the webmaster team (Bjori) on hand.
5. Follow all steps to the letter. When unclear ask previous RM's (David/Julien/
Johannes/Stas/Derick/Ilia) before proceeding. Ideally make sure that for the
first releases one of the previous RM's is around to answer questions. For the
steps related to the php/QA/bug websites try to have someone from the webmaster
team (Bjori) on hand.
5. Verify the tags to be extra sure everything was tagged properly.
6. Verify the tags to be extra sure everything was tagged properly.
7. Moving extensions from/to PECL requires write acces to the destination.
Most developers should have this.
6. Moving extensions from/to PECL requires root level access to the CVS server.
Contact systems@php.net to get this taken care of.
Moving extensions from php-src to PECL
- Checkout the pecl directory, most likely you want a sparse-root checkout
svn co --depth=empty https://svn.php.net/repository/pecl
- Create an directory for the extension incl. branch and tag structure,
no trunk at this point and commit this to svn
cd pecl; mkdir foo foo/tags foo/branches; svn add foo; svn commit
- Move the extension from php-src to the new location
svn mv https://svn.php.net/repository/php/php-src/trunk/ext/foo \
https://svn.php.net/repository/pecl/foo/trunk
- Filesystem: cp -r php-src/ext/foo pecl/foo
- cvs rm php-src/ext/foo
If the extension is still usable or not dead, in cooperation with the extension
maintainers if any:
@@ -50,163 +33,150 @@ maintainers if any:
- create the package.xml, commit
- release the package
For Moving extensions from PECL to php-src the svn mv has to be tone the other
way round.
Moving extensions from PECL to php-src
- Filesystem: cp -r pecl/foo php-src/ext/foo
OR depending on the wishes from the PECL extension maintainer.
- Filesystem: ln -s pecl/foo php-src/ext/foo
Rolling a non stable release (alpha/beta/RC)
--------------------------------------------
1. Check windows snapshot builder logs (http://windows.php.net/downloads/snaps/ the last revision)
1. Check windows snapshot builder logs (http://snaps.php.net/win32/snapshot-STABLE.log f.e.)
2. Check the tests at https://travis-ci.org/php/php-src/builds
2. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
Do not use abbreviations for alpha and beta.
3. run the "scripts/dev/credits" script in php-src and commit the changes in the
3. Commit those changes
4. run the "scripts/dev/credits" script in php-src and commit the changes in the
credits files in ext/standard.
4. Checkout the release branch for this release (e.g., PHP-5.4.2) from the main branch.
5. tag the repository with the version f.e. "``cvs tag php_4_4_1RC1``"
(of course, you need to change that to the version you're rolling an RC for).
5. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
Do not use abbreviations for alpha and beta. Do not use dashes, you should
``#define PHP_VERSION "5.4.22RC1"`` and not ``#define PHP_VERSION "5.4.22-RC1"``
6. Bump up the version numbers in ``main/php_version.h``, ``configure.in``
and possibly ``NEWS`` again, to the **next** version. F.e. if the release
candidate was "4.4.1RC1" then the new one should be "4.4.1RC2-dev" - regardless
if we get a new RC or not. This is to make sure ``version_compare()`` can
correctly work.
6. Compile and make test, with and without ZTS, using the right Bison version
(for example, for 5.5, Bison 2.4.1 is used)
7. Commit those changes
7. Check ./sapi/cli/php -v output for version matching.
8. Log in onto the snaps box and go into the correct tree (f.e. the PHP_4_4
branch if you're rolling 4.4.x releases).
8. If all is right, commit the changes to the release branch with ``git commit -a``.
9. You do not have to update the tree, but of course you can with "``cvs up -dP``".
9. Tag the repository release branch with the version, e.g.:
``git tag -u YOURKEYID php-5.4.2RC2``
10. run: ``./makedist php 4.4.1RC1``, this will export the tree, create configure
and build two tarballs (one gz and one bz2).
10. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and ``NEWS``
in the *main* branch (PHP-5.4 for example) to prepare for the **next** version.
F.e. if the RC is "5.4.1RC1" then the new one should be "5.4.2-dev" - regardless if we get
a new RC or not. This is to make sure ``version_compare()`` can correctly work.
Commit the changes to the main branch.
11. Push the changes to the main repo, the tag, the main branch and the release branch :
``git push --tags origin HEAD``
``git push origin {main branch}``
``git push origin {release branch}``
12. run: ``PHPROOT=. ./makedist 5.4.2RC2``, this will export the tree, create configure
and build three tarballs (gz, bz2 and xz).
13. run ``scripts/dev/gen_verify_stub <version> [identity]``, this will sign the tarballs
and output verification information to be included in announcement email
14. Copy those tarballs (scp, rsync) to downloads.php.net, in your homedir there should be a
11. Copy those two tarballs to www.php.net, in your homedir there should be a
directory "downloads/". Copy them into there, so that the system can generate
MD5 sums. If you do not have this directory, talk to Derick or Dan.
MD5 sums. If you do not have this directory, talk to Derick.
15. Now the RC can be found on http://downloads.php.net/yourname,
12. Now the RC can be found on http://downloads.php.net/yourname,
f.e. http://downloads.php.net/derick/
16. Once the release has been tagged, contact the PHP Windows development team
13. Once the release has been tagged, contact the PHP Windows development team
(internals-win@lists.php.net) so that Windows binaries can be created. Once
those are made, they should be placed into the same directory as the source snapshots.
Getting the non stable release (alpha/beta/RC) announced
--------------------------------------------------------
1. Send an email **To** ``internals@lists.php.net`` and ``php-general@lists.php.net``
lists pointing out "the location of the release" and "the possible release date of
either the next RC, or the final release". Include in this information the verification
information output by ``gen_verify_stub``.
1. Send an email (see example here: http://news.php.net/php.internals/19486)
**To** ``internals@lists.php.net`` and ``php-general@lists.php.net`` lists
pointing out "the location of the release" and "the possible release date of
either the next RC, or the final release".
2. Send an email (see example here http://news.php.net/php.pear.qa/5201) **To**
``php-qa@lists.php.net`` and ``primary-qa-tester@lists.php.net``.
``php-qa@lists.php.net`` and ``primary-qa-tests@lists.php.net``.
This email is to notify the selected projects about a new release so that they
can make sure their projects keep working. Make sure that you have been setup
as a moderator for ``primary-qa-tester@lists.php.net`` by having someone (Hannes, Dan,
as a moderator for ``primary-qa-tests@lists.php.net`` by having someone (Wez,
Derick) run the following commands for you:
``ssh lists.php.net``
``sudo -u ezmlm ezmlm-sub ~ezmlm/primary-qa-tester/mod moderator-email-address``
3. Update ``qa.git/include/release-qa.php`` with the appropriate information.
See the documentation within release-qa.php for more information, but all releases
and RCs are configured here. Only $QA_RELEASES needs to be edited.
3. Update the MD5 sums in ``web/qa/trunk/include/rc-md5sums.txt`` (no empty lines).
Example: When rolling an RC, set the 'rc' with appropriate information for the
given version.
4. Update in ``web/qa/trunk/include/release-qa.php`` constants with the new RC and
commit this.
Note: Remember to update the MD5 checksum information.
a. ``$BUILD_TEST_RELEASES`` = array("4.4.7RC1", "5.2.2RC1")
4. Update ``web/php.git/include/version.inc`` (x=major version number)
b. ``$CURRENT_QA_RELEASE_4`` = "4.4.7RC1" (``$CURRENT_QA_RELEASE_5`` for PHP5)
a. ``$PHP_x_RC`` = "5.4.0RC1" (should be set to "false" before)
c. ``$RELEASE_PROCESS`` = array(4 => true, 5 => true)
1. Update in ``php-bugs/trunk/include/functions.inc`` the ``show_version_option``
function to include the new RC and commit.
2. Update ``phpweb/include/version.inc`` (x=major version number)
a. ``$PHP_x_RC`` = "5.3.0RC1"
b. ``$PHP_x_RC_DATE`` = "06 September 2007"
5. Commit and push those changes:
3. Commit those changes:
a. ``git commit -a && git push origin master``
a. ``cvs commit include/version.inc include/releases.inc``
6. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the
4. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the
INSTALL and win32/install.txt files which are generated from the PHP manual sources.
Rolling a stable release
------------------------
1. Checkout your release branch, you should have created when releasing previous RC
and bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
1. Check windows snapshot builder logs (http://snaps.php.net/win32/snapshot-STABLE.log f.e.)
2. If a CVE commit needs to be merged to the release, then have it committed to
the base branches and merged upwards as usual (f.e commit the CVE fix to 5.3,
merge to 5.4, 5.5 etc...). Then you can cherry-pick it in your release branch.
Don't forget to update NEWS manually in an extra commit then.
2. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``.
3. Commit those changes. Ensure the tests at https://travis-ci.org/php/php-src/builds are
still passing.
3. **Merge** all related sections in NEWS (f.e. merge the 4.4.1RC1 and 4.4.0 sections)
4. run the "scripts/dev/credits" script in php-src and commit the changes in the
4. Commit those changes
5. run the "scripts/dev/credits" script in php-src and commit the changes in the
credits files in ext/standard.
5. Compile and make test, with and without ZTS, using the right Bison version
(for example, for 5.5, Bison 2.4.1 is used)
6. tag the repository with the version f.e. "``cvs tag php_4_4_1``"
(of course, you need to change that to the version you're rolling an RC for).
When making 5.X release, you need to tag the Zend directory separately!!
6. Check ./sapi/cli/php -v output for version matching.
7. Bump up the version numbers in ``main/php_version.h``, ``configure.in`` and
possibly ``NEWS`` again, to the **next** version. F.e. if the release candidate
was "4.4.1RC1" then the new one should be "4.4.1RC2-dev" - regardless if we get
a new RC or not. This is to make sure ``version_compare()`` can correctly work.
7. tag the repository with the version f.e. "``git tag -u YOURKEYID -s php-5.4.1``"
8. Commit those changes
8. Push the tag f.e. "``git push origin php-5.4.1``"
9. Log in onto the snaps box and go into the correct tree (f.e. the PHP_4_4
branch if you're rolling 4.4.x releases).
9. run: ``PHPROOT=. ./makedist php 5.4.1``, this will export the tag, create configure
and build three tarballs (gz, bz2 and xz).
Check if the pear files are updated (phar).
10. You do not have to update the tree, but of course you can with "``cvs up -dP``".
10. Generate the GPG signature files for the archives.
``gpg -u YOUREMAIL --armor --detach-sign php-X.Y.Z.tar.xxx``
11. run: ``./makedist php 4.4.1``, this will export the tree, create configure
and build two tarballs (one gz and one bz2).
11. Commit and push all the tarballs and signature files to web/php-distributions.git,
then update the git submodule reference in web/php.git:
``git submodule init;
git submodule update;
cd distributions;
git pull origin master;
cd ..;
git commit distributions;
git push;``
This is to fetch the last commit id from php-distributions.git and commit this
last commit id to web/php.git, then, mirrors will now sync
12. Commit those two tarballs to CVS (phpweb/distributions)
12. Once the release has been tagged, contact release managers, windows builders, and package maintainers
so that they can build releases. Do not send this announcement to any public lists.
13. Once the release has been tagged, contact the PHP Windows development team
(internals-win@lists.php.net) so that Windows binaries can be created. Once
those are made, they should be committed to CVS too.
14. Check if the pear files are updated (phar for 5.1+ or run pear/make-pear-bundle.php with 4.4)
15. When making a final release, also remind the PHP Windows development team
(internals-win@lists.php.net) to prepare the installer packages for Win32.
Getting the stable release announced
------------------------------------
1. Update phpweb/include/releases.inc with the old release info
(updates the download archives)
1. Run the bumpRelease script for phpweb on your local checkout
a. You can run ``php bin/bumpRelease 5`` if you are making a release for the
highest branch, otherwise you have to do this manually, see point 1.b
b. In case multiple PHP minor versions are in active development you have
to manually copy the old information to include/releases.inc
a. ``php bin/bumpRelease 5`` (or ``php bin/bumpRelease 4`` for PHP4)
2. Edit ``phpweb/include/version.inc`` and change (X=major release number):
@@ -216,24 +186,15 @@ Getting the stable release announced
c. ``$PHP_X_MD5`` array and update all the md5 sums
d. ``$PHP_X_SHA256`` array and update all the SHA256 sums
d. set ``$PHP_X_RC`` to false!
e. set ``$PHP_X_RC`` to false!
f. Make sure there are no outdated "notes" or edited "date" keys in the
e. Make sure there are no outdated "notes" or edited "date" keys in the
``$RELEASES[X][$PHP_X_VERSION]["source"]`` array
g. if the windows builds aren't ready yet prefix the "windows" key with a dot (".windows")
f. if the windows builds aren't ready yet prefix the "windows" key with a dot (".windows")
3. Create the release file (releases/x_y_z.php)
Usually we use the same content as for point 6, but included in php template
instead of the release xml.
4. Update php-qa/include/release-qa.php and add the next version as an QARELEASE
(prepare for next RC)
5. Update the ChangeLog file for the given major version
f.e. ``ChangeLog-5.php`` from the NEWS file
3. Update the ChangeLog file for the given major version
f.e. ``ChangeLog-4.php`` from the NEWS file
a. go over the list and put every element on one line
@@ -252,10 +213,19 @@ f.e. ``ChangeLog-5.php`` from the NEWS file
IV. ``s/Fixed PECL bug #\([0-9]\+\)/<?php peclbugfix(\1); ?>/``
V. ``s/FR #\([0-9]\+\)/FR <?php bugl(\1); ?>/``
e. You may want to try php-web/bin/news2html to automate this task
6. Add a short notice to phpweb stating that there is a new release, and
4. ``cp releases/4_4_0.php releases/4_4_1.php``
5. ``cvs add releases/4_4_1.php``
6. Update the ``releases/*.php`` file with relevant data. The release
announcement file should list in detail:
a. security fixes,
b. changes in behavior (whether due to a bug fix or not)
7. Add a short notice to phpweb stating that there is a new release, and
highlight the major important things (security fixes) and when it is important
to upgrade.
@@ -263,20 +233,24 @@ to upgrade.
b. Add the content for the news entry
7. **Check mirrors have been synced before announcing or pushing news**
Try, f.e. http://www.php.net/get/php-5.5.1.tar.bz2/from/a/mirror
Try several mirrors, mirrors may update slowly (may take an hour)
8. Commit all the changes.
8. Commit all the changes to their respective git repos
9. Please note down the sha256 and the PGP signature (.asc). These *must* be
included in the release mail.
10. Wait an hour or two, then send a mail to php-announce@lists.php.net,
9. Wait an hour or two, then send a mail to php-announce@lists.php.net,
php-general@lists.php.net and internals@lists.php.net with a text similar to
http://news.php.net/php.internals/17222.
Please make sure that the mail to php-announce@ is its own completely seperate email.
This is to make sure that repiles to the announcement on php-general@ or internals@
will not accidentally hit the php-announce@ mailinglist.
10. Update ``php-bugs-web/include/functions.php`` to include the new version
number, and remove the RC from there.
11. Update ``qaweb/include/release-qa.php``
a. Update the $BUILD_TEST_RELEASES array with the release name
b. Update $RELEASE_PROCESS array (set to false)
I. For PHP4: Set $CURRENT_QA_RELEASE_4 to false
II. For PHP5: Set $CURRENT_QA_RELEASE_5 to false
Re-releasing the same version (or -pl)
--------------------------------------
@@ -293,9 +267,7 @@ Re-releasing the same version (or -pl)
d. ``$PHP_X_MD5`` array and update all the md5 sums
e. ``$PHP_X_SHA256`` array and update all the SHA256 sums
f. Make sure there are no outdated "notes" or edited "date" keys in the
e. Make sure there are no outdated "notes" or edited "date" keys in the
``$RELEASES[X][$PHP_X_VERSION]["source"]`` array
3. Add a short notice to phpweb stating that there is a new release, and
@@ -312,6 +284,3 @@ to upgrade.
5. Wait an hour or two, then send a mail to php-announce@lists.php.net,
php-general@lists.php.net and internals@lists.php.net with a text similar to
the news entry.
Please make sure that the mail to php-announce@ is its own completely seperate email.
This is to make sure that repiles to the announcement on php-general@ or internals@
will not accidentally hit the php-announce@ mailinglist.
-15
View File
@@ -153,18 +153,3 @@ ADDING SHARED MODULE SUPPORT TO A MODULE
#ifdef COMPILE_DL_FOO
ZEND_GET_MODULE(foo)
#endif
PECL SITE CONFORMITY
If you plan to release an extension to the PECL website, there are several
points to be regarded.
1. Add LICENSE or COPYING to the package.xml
2. The following should be defined in one of the extension header files
#define PHP_FOO_VERSION "1.2.3"
This macros has to be used within your foo_module_entry to indicate the
extension version.
+4 -4
View File
@@ -28,7 +28,7 @@ The main functions are:
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
count);
PHPAPI size_t php_stream_printf(php_stream * stream,
PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
const char * fmt, ...);
PHPAPI int php_stream_eof(php_stream * stream);
PHPAPI int php_stream_getc(php_stream * stream);
@@ -46,8 +46,8 @@ Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode,
int options, char **opened_path);
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
int options, char **opened_path TSRMLS_DC);
Where:
path is the file or resource to open.
@@ -80,7 +80,7 @@ PHPAPI php_stream *php_stream_fopen_tmpfile(void);
Open a FILE * with tmpfile() and convert into a stream.
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
const char *pfx, char **opened_path);
const char *pfx, char **opened_path TSRMLS_DC);
Generate a temporary file name and open it.
There are some network enabled relatives in php_network.h:
+99 -141
View File
@@ -1,194 +1,152 @@
Submitting Enhancements and Patches to PHP
==========================================
Submitting Patches to PHP
=========================
This document describes how to submit an enhancement or patch for PHP.
It's easy!
This document describes how to submit a patch for PHP. Creating a
patch for PHP is easy!
You don't need any login accounts or special access to download,
build, debug and begin submitting PHP or PECL code, tests or
documentation. Once you've followed this README and had several
patches accepted, commit privileges are often quickly granted.
build, debug and begin submitting PHP code, tests or documentation for
inclusion in PHP. Once you've followed this README and had several
patches accepted, PHP commit privileges are often quickly granted.
An excellent article to read first is:
http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith
Online Forums
-------------
There are several IRC channels where PHP developers are often
available to discuss questions. They include #php.pecl and #php.doc
on the EFNet network and #winphp-dev on FreeNode.
Prework
-------
If you are fixing broken functionality then create a bug or identify
an existing bug at http://bugs.php.net/. This can be used to track
the patch progress and prevent your changes getting lost in the PHP
mail archives.
If your code change is large, then first discuss it with the extension
maintainer and/or a development mail list. Extension maintainers can
be found in the EXTENSIONS file in the PHP source. Use the
internals@lists.php.net mail list to discuss changes to the base PHP
code. Use pecl-dev@lists.php.net for changes to code that is only
available from PECL (http://pecl.php.net/). Use pear-dev@lists.php.net
for PEAR modules (http://pear.php.net/). Use phpdoc@lists.php.net for
PHP documentation questions. Mail list subscription is explained on
http://www.php.net/mailing-lists.php.
PHP Patches
-----------
If you are fixing broken functionality in PHP C source code first
create a bug or identify an existing bug at http://bugs.php.net/. A
bug can be used to track the patch progress and prevent your changes
getting lost in the PHP mail archives.
If a PHP or PECL patch affects user functionality or makes significant
internal changes then create a simple Request For Comment (RFC) page
on http://wiki.php.net/rfc before starting discussion. This RFC can be
used for initial discussion and later for documentation. Wiki accounts
can be requested on http://wiki.php.net/start?do=register
If your change is large then create a Request For Comment (RFC) page
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
and discuss it on the development mail list internals@lists.php.net.
RFC Wiki accounts can be requested on
http://wiki.php.net/start?do=register. PHP extension maintainers can
be found in the EXTENSIONS file in the PHP source. Mail list
subscription is explained on http://php.net/mailing-lists.php.
Information on PHP internal C functions is at
http://php.net/internals, though this is considered incomplete.
Various external resources can be found on the web. See
https://wiki.php.net/internals for some references. A standard
printed reference is the book "Extending and Embedding PHP" by Sara
Online information on PHP internal C functions is at
http://www.php.net/internals, though this is considered
incomplete. Various external resources can be found on the web. A
standard reference is the book "Extending and Embedding PHP" by Sara
Golemon.
The preferred way to propose PHP patch is sending pull request from
GitHub: https://github.com/php/php-src
Fork the official PHP repository and send a pull request. A
notification will be sent to the pull request mailing list. Sending a
note to PHP Internals list (internals@lists.php.net) may help getting
more feedback and quicker turnaround. You can also add pull requests
to bug reports at http://bugs.php.net/.
If you are not using GitHub, attach your patch to a PHP bug and
consider sending a notification email about the change to
internals@lists.php.net. If the bug is for an extension, also CC the
extension maintainer. Explain what has been changed by your patch.
Test scripts should be included.
Please make the mail subject prefix "[PATCH]". If attaching a patch,
ensure it has a file extension of ".txt". This is because only MIME
attachments of type 'text/*' are accepted.
PHP Documentation Patches
-------------------------
If you are fixing incorrect PHP documentation first create a bug or
identify an existing bug at http://bugs.php.net/. A bug can be used
to track the patch progress and prevent your changes getting lost in
the PHP mail archives.
If your change is large, then first discuss it with the mail list
phpdoc@lists.php.net. Subscription is explained on
http://php.net/mailing-lists.php.
Information on contributing to PEAR is available at
http://pear.php.net/manual/en/guide-developers.php
Information on contributing to PHP documentation is at
http://php.net/dochowto and http://wiki.php.net/doc/howto
Attach the patch to the PHP bug and consider sending a notification
email about the change to phpdoc@lists.php.net. Explain what has been
fixed/added/changed by your patch.
Please make the mail subject prefix "[PATCH]". Include the bug id(s)
which can be closed by your patch. If attaching a patch, ensure it
has a file extension of ".txt". This is because only MIME attachments
of type 'text/*' are accepted.
There are several IRC channels where PHP developers are often
available to discuss questions. They include #php.pecl and #php.doc
on the EFNet network and #php-dev-win on FreeNode.
PECL Extension Patches: http://pecl.php.net/
--------------------------------------------
If you are fixing broken functionality in a PECL extension then create
a bug or identify an existing bug at http://bugs.php.net/. A bug
can be used to track the patch progress and prevent your changes
getting lost in the PHP mail archives.
How to create your patch
------------------------
PHP uses Subversion (SVN) for revision control. Read
http://www.php.net/svn.php for help on using SVN to get and build PHP
source code. We recommend using a Sparse Directory checkout described
in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read
http://svnbook.red-bean.com.
If your change is large then create a Request For Comment (RFC) page
on http://wiki.php.net/rfc, discuss it with the extension maintainer,
and discuss it on the development mail list pecl-dev@lists.php.net.
PECL mail list subscription is explained on
http://pecl.php.net/support.php. RFC Wiki accounts can be requested
on http://wiki.php.net/start?do=register
Information on PHP internal C functions is at
http://www.php.net/internals, though this is considered incomplete.
Various external resources can be found on the web. A standard
printed reference is the book "Extending and Embedding PHP" by Sara
Golemon.
Update any open bugs and add a link to the source of your patch. Send
the patch or pointer to the bug to pecl-dev@lists.php.net. Also CC
the extension maintainer. Explain what has been changed by your
patch. Test scripts should be included.
Please make the mail subject prefix "[PATCH] ...". Include the patch
as an attachment with a file extension of ".txt". This is because
only MIME attachments of type 'text/*' are accepted.
PEAR Package Patches: http://pear.php.net/
------------------------------------------
Information on contributing to PEAR is available at
http://pear.php.net/manual/en/developers-newmaint.php and
http://pear.php.net/manual/en/guide-developers.php
How to create your PHP, PHP Documentation or PECL patch
-------------------------------------------------------
PHP and most PECL packages use Git for revision control. Some PECL
packages use Subversion (SVN) Read http://www.php.net/git.php for help
on using Git to get and build PHP source code. We recommend to look
at our workflow on https://wiki.php.net/vcs/gitworkflow and our FAQ
https://wiki.php.net/vcs/gitfaq.
Generally we ask that bug fix patches work on the current stable PHP
development branches and on "master". New PHP features only need to
work on "master".
Generally we ask that patches work on the current stable PHP
development branch and on "trunk".
Read CODING_STANDARDS before you start working.
After modifying the source see README.TESTING and
http://qa.php.net/write-test.php for how to test. Submitting test
scripts helps us to understand what functionality has changed. It is
http://qa.php.net/write-test.php for how to test. Submitting test
scripts helps us to understand what functionality has changed. It is
important for the stability and maintainability of PHP that tests are
comprehensive.
After testing is finished, create a patch file using the command:
git diff > your_patch.txt
svn diff > your_patch.txt
For ease of review and later troubleshooting, submit individual
patches for each bug or feature.
Checklist for submitting your PHP or PECL code patch
----------------------------------------------------
- Update git source just before running your final 'diff' and
Checklist for submitting your patch
-----------------------------------
- Update SVN source just before running your final 'diff' and
before testing.
- Add in-line comments and/or have external documentation ready.
Use only "/* */" style comments, not "//".
- Create test scripts for use with "make test".
- Run "make test" to check your patch 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-maintainer-zts to check your patch
compiles on multi-threaded web servers.
running the PHP tests.
- Rebuild PHP with --enable-maintainer-zts to check your patch compiles
on multi-threaded web servers.
- Create test scripts for use with "make test".
- Add in-line comments and/or have external documentation ready.
- Review the patch once more just before submitting it.
What happens after submitting your PHP, PHP Documentation or PECL patch
-----------------------------------------------------------------------
Where to send your patch
------------------------
If you are patching PHP C source then email the patch to
internals@lists.php.net
If you patching a PECL extension then send the patch to
pecl-dev@lists.php.net
If you are patching PEAR then send the patch to
pear-dev@lists.php.net
If you are patching PHP's documentation then send the patch to
phpdoc@lists.php.net
The mail can be CC'd to the extension maintainer (see EXTENSIONS).
Please make the subject prefix "[PATCH]", for example "[PATCH] Fix
return value of all array functions"
Include the patch as an attachment with a file extension of ".txt".
This is because only MIME attachments of type 'text/*' are accepted.
Explain what has been fixed/added/changed by your patch. Test scripts
should be included in the email.
Include the bug id(s) which can be closed by your patch.
Finally, update any open bugs and add a link to the source of your
patch.
What happens after you submit your patch
----------------------------------------
If your patch is easy to review and obviously has no side-effects,
it might be committed relatively quickly.
Because PHP is a volunteer-driven effort more complex patches will
require patience on your side. If you do not receive feedback in a
few days, consider resubmitting the patch. Before doing this think
about these questions:
require patience on your side. If you do not receive feedback in a few
days, consider resubmitting the patch. Before doing this think about
these questions:
- Did I send the patch to the right mail list?
- Did I review the mail list archives to see if these kind of
changes had been discussed before?
- Did I explain my patch clearly?
- Is my patch too hard to review? Because of what factors?
- Is my patch too hard to review? Because of which factors?
- Are there any unwanted white space changes?
What happens when your PHP or PECL patch is applied
---------------------------------------------------
Your name will likely be included in the Git commit log. If your
patch affects end users, a brief description and your name might be
added to the NEWS file.
What happens when your patch is applied
---------------------------------------
Your name will be included in the SVN commit log. If your patch
affects end users, a brief description and your name might be added to
the NEWS file.
Thank you for patching PHP!
+146
View File
@@ -0,0 +1,146 @@
====================
SVN Commit Rules
====================
This is the first file you should be reading after you get your SVN account.
We'll assume you're basically familiar with SVN, but feel free to post
your questions on the mailing list. Please have a look at
http://svnbook.red-bean.com/ for more detailed information on SVN.
PHP is developed through the efforts of a large number of people.
Collaboration is a Good Thing(tm), and SVN lets us do this. Thus, following
some basic rules with regards to SVN usage will::
a. Make everybody happier, especially those responsible for maintaining
the SVN itself.
b. Keep the changes consistently well documented and easily trackable.
c. Prevent some of those 'Oops' moments.
d. Increase the general level of good will on planet Earth.
Having said that, here are the organizational rules::
1. Respect other people working on the project.
2. Discuss any significant changes on the list before committing and get
confirmation from the release manager for the given branch.
3. Look at EXTENSIONS file to see who is the primary maintainer of
the code you want to contribute to.
4. If you "strongly disagree" about something another person did, don't
start fighting publicly - take it up in private email.
5. If you don't know how to do something, ask first!
6. Test your changes before committing them. We mean it. Really.
To do so use "make test".
7. For development use the --enable-maintainer-zts switch to ensure your
code handles TSRM correctly and doesn't break for thos who need that.
Currently we have the following branches in use::
trunk Will become PHP 6.0. This branch is for active development.
branches/PHP_5_3 Is used to release the PHP 5.3.x series. It still allows for
larger enhancements.
branches/PHP_5_2 Is used to release the PHP 5.2.x series. Only bugfixes are permitted
on this branch (Consult the releasemaster prior to commit).
branches/PHP_5_1 This branch is closed.
branches/PHP_4_4 This branch is closed.
The next few rules are more of a technical nature::
1. All changes should first go to trunk and then get merged from trunk
(aka MFH'ed) to all other relevant branches.
2. DO NOT TOUCH ChangeLog! It is automagically updated from the commit
messages every day. Woe be to those who attempt to mess with it.
3. All news updates intended for public viewing, such as new features,
bug fixes, improvements, etc., should go into the NEWS file of the
*first* to be released version with the given change. In other words
any NEWS file change only needs to done in one branch.
NB! Lines, starting with @ will go automagically into NEWS file, but
this is NOT recommended, though. Please, add news entries directly to
NEWS file and don't forget to keep them adjusted and sorted.
4. Do not commit multiple file and dump all messages in one commit. If you
modified several unrelated files, commit each group separately and
provide a nice commit message for each one. See example below.
5. Do write your commit message in such a way that it makes sense even
without the corresponding diff. One should be able to look at it, and
immediately know what was modified. Definitely include the function name
in the message as shown below.
6. In your commit messages, keep each line shorter than 80 characters. And
try to align your lines vertically, if they wrap. It looks bad otherwise.
7. If you modified a function that is callable from PHP, prepend PHP to
the function name as shown below.
The format of the commit messages is pretty simple.
Use a - to start a new item in your commit message.
If a line begins with #, it is taken to be a comment and will not appear
in the ChangeLog. Everything else goes into the ChangeLog.
It is important to note that if your comment or news logline spans multiple
lines, you have to put # at the beginning of **every** such line.
Example. Say you modified two files, datetime.c and string.c. In datetime.c you
added a new format option for the date() function, and in string.c you fixed a
memory leak in php_trim(). Don't commit both of these at once. Commit them
separately and try to make sure your commit messages look something like the
following.
For datetime.c::
- Added new 'K' format modifier to date() for printing out number of days
until New Year's Eve.
For string.c::
- Fixed a memory leak in php_trim() resulting from improper use of zval_dtor().
#- Man, that thing was leaking all over the place!
The # lines will be omitted from the ChangeLog automagically.
Use the [DOC] tag in your log message whenever you feel that your changes
imply a documentation modification. The php-doc team will automatically
get notified about your commit through the php-doc mailing list.
If you fix some bugs, you should note the bug ID numbers in your
commit message. Bug ID should be prefixed by "#" for easier access to
bug report when developers are browsing SVN via LXR or Bonsai.
Example::
Fixed bug #14016 (pgsql notice handler double free crash bug.)
If you don't see your messages in ChangeLog right away, don't worry!
These files are updated once a day, so your stuff will not show up until
somewhat later.
When you change the NEWS file for a bug fix, then please keep the bugs
sorted in decreasing order under the fixed version.
You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
to look at PHP SVN repository in various ways.
To receive daily updates to ChangeLog and NEWS, send an empty message to
php-cvs-daily-subscribe@lists.php.net.
Happy hacking,
PHP Team
+6 -7
View File
@@ -1,8 +1,8 @@
[IMPORTANT NOTICE]
------------------
Failed tests usually indicate a problem with your local system setup
Failed tests usualy indicate a problem with your local system setup
and not within PHP itself (at least for official PHP release versions).
You may decide to automatically submit a test summary to our QA workflow
You may decide to automaticaly submit a test summary to our QA workflow
at the end of a test run.
Please do *not* submit a failed test as a bug or ask for help on why
it failed on your system without providing substantial backup information
@@ -104,8 +104,7 @@ The php file will be generated always.
NOTE: You can set environment variable TEST_PHP_DETAILED to enable
detailed test information.
[Automated Testing]
--------------
[Automated testing]
If you like to keep up to speed, with latest developments and quality
assurance, setting the environment variable NO_INTERACTION to 1, will not
prompt the tester for any user input.
@@ -119,12 +118,12 @@ Example script to be run by cron(1):
========== qa-test.sh =============
#!/bin/sh
CO_DIR=$HOME/cvs/php7
CO_DIR=$HOME/cvs/php5
MYMAIL=qa-test@domain.com
TMPDIR=/var/tmp
TODAY=`date +"%Y%m%d"`
# Make sure compilation environment is correct
# Make sure compilation enviroment is correct
CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
export MAKE=gmake
export CC=gcc
@@ -143,7 +142,7 @@ then
fi
========== end of qa-test.sh =============
NOTE: The exit status of run-tests.php will be 1 when
NOTE: the exit status of run-tests.php will be 1 when
REPORT_EXIT_STATUS is set. The result of "make test" may be higher
than that. At present, gmake 3.79.1 returns 2, so it is
advised to test for non-zero, rather then a specific value.
+3 -3
View File
@@ -8,7 +8,7 @@ the original run-tests.php script. server-tests is *not* used by
'make test'. server-tests was developed to provide support for
testing PHP under it's primary environment, HTTP, and can run the
PHP tests under any of the SAPI modules that are direct executables,
or are accessible via HTTP.
or are accessable via HTTP.
[New features]
----------------
@@ -95,7 +95,7 @@ include:
$filename full native path to file, will become PATH_TRANSLATED
$filepath =dirname($filename)
$scriptname this is what will become SCRIPT_NAME unless you override it
$docroot the equivalent of DOCUMENT_ROOT under Apache
$docroot the equivelant of DOCUMENT_ROOT under Apache
$cwd the directory that the test is being initiated from
$this->conf all server-tests configuration vars
$this->env all environment variables that will get passed to the test
@@ -105,7 +105,7 @@ include:
This section is also eval'd, and is similar in nature to --ENV--. However,
this section is used to build the url used in an HTTP request. Valid values
to set in this section would include:
SCRIPT_NAME The initial part of the request url
SCRIPT_NAME The inital part of the request url
PATH_INFO The pathinfo part of a request url
FRAGMENT The fragment section of a url (after #)
QUERY_STRING The query part of a url (after ?)
+644
View File
@@ -0,0 +1,644 @@
Audience
========
This README describes how PHP 6 provides native support for the Unicode
Standard. Readers of this document should be proficient with PHP and have a
basic understanding of Unicode concepts. For more technical details about
PHP 6 design principles and for guidelines about writing Unicode-ready PHP
extensions, refer to README.UNICODE-UPGRADES.
Introduction
============
As successful as PHP has proven to be over the years, its support for
multilingual and multinational environments has languished. PHP can no
longer afford to remain outside the overall movement towards the Unicode
standard. Although recent updates involving the mbstring extension have
enabled easier multibyte data processing, this does not constitute native
Unicode support.
Since the full implementation of the Unicode Standard is very involved, our
approach is to speed up implementation by using the well-tested,
full-featured, and freely available ICU (International Components for
Unicode) library.
General Remarks
===============
International Components for Unicode
------------------------------------
ICU (International Components for Unicode is a mature, widely used set of
C/C++ and Java libraries for Unicode support, software internationalization
and globalization. It provides:
- Encoding conversions
- Collations
- Unicode text processing
- and much more
When building PHP 6, Unicode support is always enabled. The only
configuration option during development should be the location of the ICU
headers and libraries.
--with-icu-dir=<dir>
where <dir> specifies the location of ICU header and library files. If you do
not specify this option, PHP attempts to find ICU under /usr and /usr/local.
NOTE: ICU is not bundled with PHP 6 yet. To download the distribution, visit
http://icu.sourceforge.net. PHP requires ICU version 3.4 or higher.
Backwards Compatibility
-----------------------
Our paramount concern for providing Unicode support is backwards compatibility.
Because PHP is used on so many sites, existing data types and functions must
work as they always have. However, although PHP's interfaces must remain
backwards-compatible, the speed of certain operations might be affected due to
internal implementation changes.
Encoding Names
--------------
All the encoding settings discussed in this document can accept any valid
encoding name supported by ICU. For a full list of encodings, refer to the ICU
online documentation.
NOTE: References to "Unicode" in this document generally mean the UTF-16
character encoding, unless explicitly stated otherwise.
Unicode Semantics Switch
========================
Because many applications do not require Unicode, PHP 6 provides a server-wide
INI setting to enable Unicode support:
unicode.semantics = On/Off
This switch is off by default. If your applications do not require native
Unicode support, you may leave this switch off, and continue to use Unicode
strings only when you need to.
However, if your application is ready to fully support Unicode, you should
turn this switch on. This activates various Unicode support mechanisms,
including:
* All string literals become Unicode
* All variables received from HTTP requests become Unicode
* PHP identifiers may use Unicode characters
More fundamentally, your PHP environment is now a Unicode environment. Strings
inside PHP are Unicode, and the system is responsible for converting non-Unicode
strings on PHP's periphery (for example, in HTTP input and output, streams, and
filesystem operations). With unicode.semantics on, you must specify binary
strings explicitly. PHP makes no assumptions about the content of a binary
string, so your application must handle all binary string appropriately.
Conversely, if unicode.semantics is off, PHP behaves as it did in the past.
String literals do not become Unicode, and files are binary strings for
backwards compatibility. You can always create Unicode strings programmatically,
and all functions and operators support Unicode strings transparently.
Fallback Encoding
=================
The fallback encoding provides a default value for all other unicode.*_encoding
INI settings. If you do not set a particular unicode.*_encoding setting, PHP
uses the fallback encoding. If you do not specify a fallback encoding, PHP uses
UTF-8.
unicode.fallback_encoding = "iso-8859-1"
Runtime Encoding
================
The runtime encoding specifies the encoding PHP uses for converting binary
strings within the PHP engine itself.
unicode.runtime_encoding = "iso-8859-1"
This setting has no effect on I/O-related operations such as writing to
standard out, reading from the filesystem, or decoding HTTP input variables.
PHP enables you to explicitly convert strings using casting:
* (binary) -- casts to binary string type
* (unicode) -- casts to Unicode string type
* (string) -- casts to Unicode string type if unicode.semantics is on,
to binary otherwise
For example, if unicode.runtime_encoding is iso-8859-1, and $uni is a unicode
string, then
$str = (binary)$uni
creates a binary string $str in the ISO-8859-1 encoding.
Implicit conversions include concatenation, comparison, and parameter passing.
For better precision, PHP attempts to convert strings to Unicode before
performing these sorts of operations. For example, if we concatenate our binary
string $str with a unicode literal, PHP converts $str to Unicode first, using
the encoding specified by unicode.runtime_encoding.
Output Encoding
===============
PHP automatically converts output for commands that write to the standard
output stream, such as 'print' and 'echo'.
unicode.output_encoding = "utf-8"
However, PHP does not convert binary strings. When writing to files or external
resources, you must rely on stream encoding features or manually encode the data
using functions provided by the unicode extension.
The existing default_charset INI setting is DEPRECATED in favor of
unicode.output_setting. Previously, default_charset only specified the charset
portion of the Content-Type MIME header. Now default_charset only takes effect
when unicode.semantics is off, and it does not affect the actual transcoding of
the output stream. Setting unicode.output_encoding causes PHP to add the
'charset' portion to the Content-Type header, overriding any value set for
default_charset.
HTTP Input Encoding
===================
The HTTP input encoding specifies the encoding of variables received via
HTTP, such as the contents of the $_GET and _$POST arrays.
This functionality is currently under development. For a discussion of the
approach that the PHP 6 team is taking, refer to:
http://marc.theaimsgroup.com/?t=116613047300005&r=1&w=2
Filesystem Encoding
===================
The filesystem encoding specifies the encoding of file and directory names
on the filesystem.
unicode.filename_encoding = "utf-8"
Filesystem-related functions such as opendir() perform this conversion when
accepting and returning file names. You should set the filename encoding to
the encoding used by your filesystem.
Script Encoding
===============
You may write PHP scripts in any encoding supported by ICU. To specify the
script encoding site-wide, use the INI setting:
unicode.script_encoding = utf-8
If you cannot change the encoding system wide, you can use a pragma to
override the INI setting in a local script:
<?php declare(encoding = 'Shift-JIS'); ?>
The pragma setting must be the first statement in the script. It only affects
the script in which it occurs, and does not propagate to any included files.
INI Files
=========
If unicode.semantics is on, INI files are presumed to contain UTF-8 encoded
keys and values. If unicode.semantics is off, the data is taken as-is,
similar to PHP 5. No validation occurs during parsing. Instead invalid UTF-8
sequences are caught during access by ini_*() functions.
Stream I/O
==========
PHP has a streams-based I/O system for generalized filesystem access,
networking, data compression, and other operations. Since the data on the
other end of the stream can be in any encoding, you need to think about
data conversion.
Okay, this needs to be clarified. By "default", streams are actually
opened in binary mode. You have to specify 't' flag or use FILE_TEXT in
order to open it in text mode, where conversions apply. And for the text
mode streams, the default stream encoding is UTF-8 indeed.
By default, PHP opens streams in binary mode. To open a file in text mode,
you must use the 't' flag (or the FILE_TEXT parameter -- see below). The
default encoding for streams in text mode is UTF-8. This means that if
'file.txt' is a UTF-8 text file, this code snippet:
$fp = fopen('file.txt', 'rt');
$str = fread($fp, 100)
returns 100 Unicode characters, while:
$fp = fopen('file.txt', 'wt');
$fwrite($fp, $uni)
writes to a UTF-8 text file.
If you mainly work with files in an encoding other than UTF-8, you can
change the default context encoding setting:
stream_default_encoding('Shift-JIS');
$data = file_get_contents('file.txt', FILE_TEXT);
// work on $data
file_put_contents('file.txt', $data, FILE_TEXT);
The file_get_contents() and file_put_contents() functions now accept an
additional parameter, FILE_TEXT. If you provide FILE_TEXT for
file_get_contents(), PHP returns a Unicode string. Without FILE_TEXT, PHP
returns a binary string (which would be appropriate for true binary data, such
as an image file). When writing a Unicode string with file_put_contents(), you
must supply the FILE_TEXT parameter, or PHP generates a warning.
If you need to work with multiple encodings, you can create custom contexts
using stream_context_create() and then pass in the custom context as an
additional parameter. For example:
$ctx = stream_context_create(NULL, array('encoding' => 'big5'));
$data = file_get_contents('file.txt', FILE_TEXT, $ctx);
// work on $data
file_put_contents('file.txt', $data, FILE_TEXT, $ctx);
Conversion Semantics and Error Handling
=======================================
PHP can convert strings explicitly (casting) and implicitly (concatenation,
comparison, and parameter passing. For example, when concatenating a Unicode
string and a binary string, PHP converts the binary string to Unicode for better
precision.
However, not all characters can be converted between Unicode and legacy
encodings. The first possibility is that a string contains corrupt data or
an illegal byte sequence. In this case, the converter simply stops with
a message that resembles:
Warning: Could not convert binary string to Unicode string
(converter UTF-8 failed on bytes (0xE9) at offset 2)
Conversely, if a similar error occurs when attempting to convert Unicode to
a legacy string, the converter generates a message that resembles:
Warning: Could not convert Unicode string to binary string
(converter ISO-8859-1 failed on character {U+DC00} at offset 2)
To customize this behavior, refer to "Creating a Custom Error Handler" below.
The second possibility is that a Unicode character simply cannot be represented
in the legacy encoding. By default, when downconverting from Unicode, the
converter substitutes any missing sequences with the appropriate substitution
sequence for that codepage, such as 0x1A (Control-Z) in ISO-8859-1. When
upconverting to Unicode, the converter replaces any byte sequence that has no
Unicode equivalent with the Unicode substitution character (U+FFFD).
You can customize the conversion error behavior to:
- stop the conversion and return an empty string
- skip any invalid characters
- substitute invalid characters with a custom substitution character
- escape the invalid character in various formats
To control the global conversion error settings, use the functions:
unicode_set_error_mode(int direction, int mode)
unicode_set_subst_char(unicode char)
where direction is either FROM_UNICODE or TO_UNICODE, and mode is one of these
constants:
U_CONV_ERROR_STOP
U_CONV_ERROR_SKIP
U_CONV_ERROR_SUBST
U_CONV_ERROR_ESCAPE_UNICODE
U_CONV_ERROR_ESCAPE_ICU
U_CONV_ERROR_ESCAPE_JAVA
U_CONV_ERROR_ESCAPE_XML_DEC
U_CONV_ERROR_ESCAPE_XML_HEX
As an example, with a runtime encoding of ISO-8859-1, the conversion:
$str = (binary)"< \u30AB >";
results in:
MODE RESULT
--------------------------------------
stop ""
skip "< >"
substitute "< ? >"
escape (Unicode) "< {U+30AB} >"
escape (ICU) "< %U30AB >"
escape (Java) "< \u30AB >"
escape (XML decimal) "< &#12459; >"
escape (XML hex) "< &#x30AB; >"
With a runtime encoding of UTF-8, the conversion of the (illegal) sequence:
$str = (unicode)b"< \xe9\xfe >";
results in:
MODE RESULT
--------------------------------------
stop ""
skip ""
substitute ""
escape (Unicode) "< %XE9%XFE >"
escape (ICU) "< %XE9%XFE >"
escape (Java) "< \xE9\xFE >"
escape (XML decimal) "< &#233;&#254; >"
escape (XML hex) "< &#xE9;&#xFE; >"
The substitution character can be set only for FROM_UNICODE direction and has to
exist in the target character set. The default substitution character is (?).
NOTE: Casting is just a shortcut for using unicode.runtime_encoding. To convert
using an alternative encoding, use the unicode_encode() and unicode_decode()
functions. For example,
$str = unicode_encode($uni, 'koi8-r', U_CONV_ERROR_SUBST);
results in a binary KOI8-R encoded string.
Creating a Custom Error Handler
-------------------------------
If an error occurs during the conversion, PHP outputs a warning describing the
problem. Instead of this default behavior, PHP can invoke a user-provided error
handler, similar to how the current user-defined error handler works. To set
the custom conversion error handler, call:
mixed unicode_set_error_handler(callback error_handler)
The function returns the previously defined custom error handler. If no error
handler was defined, or if an error occurs when returning the handler, this
function returns NULL.
When the custom handler is set, the standard error handler is bypassed. It is
the responsibility of the custom handler to output or log any messages, raise
exceptions, or die(), if necessary. However, if the custom error handler returns
FALSE, the standard handler will be invoked afterwards.
The user function specified as the error_handler must accept five parameters:
mixed error_handler($direction, $encoding, $char_or_byte, $offset,
$message)
where:
$direction - the direction of conversion, FROM_UNICODE/TO_UNICODE
$encoding - the name of the encoding to/from which the conversion
was attempted
$char_or_byte - either Unicode character or byte sequence (depending
on direction) which caused the error
$offset - the offset of the failed character/byte sequence in
the source string
$message - the error message describing the problem
NOTE: If the error mode set by unicode_set_error_mode() is substitute,
skip, or escape, the handler won't be called, since these are non-error
causing operations. To always invoke your handler, set the error mode to
U_CONV_ERROR_STOP.
Unicode String Type
===================
The Unicode string type (IS_UNICODE) is supposed to contain text data encoded in
UTF-16. This is the main string type in PHP when Unicode semantics switch is
turned on. Unicode strings can exist when the switch is off, but they have to be
produced programmatically via calls to functions that return Unicode types.
Binary String Type
==================
Binary string type (IS_STRING) serves two purposes: backwards compatibility and
representing non-Unicode strings and binary data. When Unicode semantics switch
is off, it is used for all strings in PHP, same in previous versions. When the
switch is on, this type will be used to store text in other encodings as well as
true binary data such as images, PDFs, etc.
Printing binary data to the standard output passes it through as-is, independent
of the output encoding.
For examples of specifying binary string literals, refer to the section
"Language Modfications".
Language Modifications
======================
If a Unicode switch is turned on, PHP string literals -- single-quoted,
double-quoted, and heredocs -- become Unicode strings (IS_UNICODE type). String
literals support all the same escape sequences and variable interpolations as
before, plus several new escape sequences.
PHP interprets the contents of strings as follows:
- all non-escaped characters are interpreted as a corresponding Unicode
codepoint based on the current script encoding, e.g. ASCII 'a' (0x61) =>
U+0061, Shift-JIS (0x92 0x86) => U+4E2D
- existing PHP escape sequences are also interpreted as Unicode codepoints,
including \xXX (hex) and \OOO (octal) numbers, e.g. "\x20" => U+0020
- two new escape sequences, \uXXXX and \UXXXXXX, are interpreted as a 4 or
6-hex Unicode codepoint value, e.g. \u0221 => U+0221, \U010410 =>
U+10410. (Having two sequences avoids the ambiguity of \u020608 --
is that supposed to be U+0206 followed by "08", or U+020608 ?)
- a new escape sequence allows specifying a character by its full
Unicode name, e.g. \C{THAI CHARACTER PHO SAMPHAO} => U+0E20
PHP allows variable interpolation inside the double-quoted and heredoc strings.
However, the parser separates the string into literal and variable chunks during
compilation, e.g. "abc $var def" -> "abc" . $var . "def". This means that PHP
can handle literal chunks in the normal way as far as Unicode support is
concerned.
Since all string literals become Unicode by default, PHP 6 introduces new syntax
for creating byte-oriented or binary strings. Prefixing a string literal with
the letter 'b' creates a binary string:
$var = b'abc\001';
$var = b"abc\001";
$var = b<<<EOD
abc\001
EOD;
The content of a binary string is the literal byte sequence inside the
delimiters, which depends on the script encoding (unicode.script_encoding).
Binary string literals support the same escape sequences as PHP 5 strings. If
the Unicode switch is turned off, then the binary string literals generate the
normal string (IS_STRING) type internally without any effect on the application.
The string operators now accomodate the new IS_UNICODE and IS_BINARY types:
- The concatenation operator (.) and concatenation assignment operator (.=)
automatically coerce the IS_STRING type to the more precise IS_UNICODE if
the operands are of different string types.
- The string indexing operator [] now accommodates IS_UNICODE type strings
and extracts the specified character. To support supplementary characters,
the index specifies a code point, not a byte or a code unit.
- Bitwise operators and increment/decrement operators do not work on
Unicode strings. They do work on binary strings.
- Two new casting operators are introduced, (unicode) and (binary). The
(string) operator casts to Unicode type if the Unicode semantics switch is
on, and to binary type otherwise.
- The comparison operators compare Unicode strings in binary code point
order. They also coerce strings to Unicode if the strings are of different
types.
- The arithmetic operators use the same semantics as today for converting
strings to numbers. A Unicode string is considered numeric if it
represents a long or a double number in the en_US_POSIX locale.
Unicode Support in Existing Functions
=====================================
All functions in the PHP default distribution are undergoing analysis to
determine which functions need to be upgraded for native Unicode support.
You can track progress here:
http://www.php.net/~scoates/unicode/render_func_data.php
Key extensions that are fully converted include:
* curl
* dom
* json
* mysql
* mysqli
* oci8
* pcre
* reflection
* simplexml
* soap
* sqlite
* xml
* xmlreader/xmlwriter
* xsl
* zlib
NOTE: Unsafe functions might still work, since PHP performs Unicode conversions
at runtime. However, unsafe functions might not work correctly with multibyte
binary strings, or Unicode characters that are not representable in the
specified unicode.runtime_encoding.
Identifiers
===========
Since scripts may be written in various encodings, we do not restrict
identifiers to be ASCII-only. PHP allows any valid identifier based
on the Unicode Standard Annex #31.
Numbers
=======
Unlike identifiers, numbers must consist only of ASCII digits,.and are
restricted to the en_US_POSIX or C locale. In other words, numbers have no
thousands separator, and the fractional separator is (.) "full stop". Numeric
strings adhere to the same rules, so "10,3" is not interpreted as a number even
if the current locale's fractional separator is a comma.
TextIterators
=============
Instead of using the offset operator [] to access characters in a linear
fashion, use a TextIterator instead. TextIterator is very fast and enables you
to iterate over code points, combining sequences, characters, words, lines, and
sentences, both forward and backward. For example:
$text = "nai\u308ve";
foreach (new TextIterator($text) as $u) {
var_inspect($u)
}
lists six code points, including the umlaut (U+0308) as a separate code point.
Instantiating the TextIterator to iterate over characters,
$text = "nai\u308ve";
foreach (new TextIterator($text, TextIterator::CHARACTER) as $u) {
var_inspect($u)
}
lists five characters, including an "i" with an umlaut as a single character.
Locales
=======
Unicode support in PHP relies exclusively on ICU locales, NOT the POSIX locales
installed on the system. You may access the default ICU locale using:
locale_set_default()
locale_get_default()
ICU locale IDs have a somewhat different format from POSIX locale IDs. The ICU
syntax is:
<language>[_<script>]_<country>[_<variant>][@<keywords>]
For example, sr_Latn_YU_REVISED@currency=USD is Serbian (Latin, Yugoslavia,
Revised Orthography, Currency=US Dollar).
Do not use the deprecated setlocale() function. This function interacts with the
POSIX locale. If Unicode semantics are on, using setlocale() generates
a deprecation warning.
Document TODO
==========================================
- Final review.
- Fix the HTTP Input Encoding section, that's obsolete now.
References
==========
Unicode
http://www.unicode.org
Unicode Glossary
http://www.unicode.org/glossary/
UTF-8
http://www.utf-8.com/
UTF-16
http://www.ietf.org/rfc/rfc2781.txt
ICU Homepage
http://www.ibm.com/software/globalization/icu/
ICU User Guide and API Reference
http://icu.sourceforge.net/
Unicode Annex #31
http://www.unicode.org/reports/tr31/
PHP Parameter Parsing API
http://www.php.net/manual/en/zend.arguments.retrieval.php
Authors
=======
Andrei Zmievski <andrei@gravitonic.com>
Evan Goer <goer@yahoo-inc.com>
vim: set et tw=80 :
+806
View File
@@ -0,0 +1,806 @@
This document attempts to describe portions of the API related to the new
Unicode functionality and the best practices for upgrading existing
functions to support Unicode.
Your first stop should be README.UNICODE: it covers the general Unicode
functionality and concepts without going into technical implementation
details.
Internal Encoding
=================
UTF-16 is the internal encoding used for Unicode strings. UTF-16 consumes
two bytes for any Unicode character in the Basic Multilingual Plane, which
is where most of the current world's languages are represented. While being
less memory efficient for basic ASCII text it simplifies the processing and
makes interfacing with ICU easier, since ICU uses UTF-16 for its internal
processing as well.
Zval Structure Changes
======================
For IS_UNICODE type, we add another structure to the union:
union {
....
struct {
UChar *val; /* Unicode string value */
int len; /* number of UChar's */
} ustr;
....
} value;
This cleanly separates the two types of strings and helps preserve backwards
compatibility.
To optimize access to IS_STRING and IS_UNICODE storage at runtime, we need yet
another structure:
union {
....
struct { /* Universal string type */
zstr val;
int len;
} uni;
....
} value;
Where zstr is a union of char*, UChar*, and void*.
Parameter Parsing API Modifications
===================================
There are now five new specifiers: 'u', 't', 'T', 'U', 'S', 'x' and a new '&'
modifier.
't' specifier
-------------
This specifier indicates that the caller requires the incoming parameter to be
string data (IS_STRING, IS_UNICODE). The caller has to provide the storage for
string value, length, and type.
void *str;
int len;
zend_uchar type;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &str, &len, &type) == FAILURE) {
return;
}
if (type == IS_UNICODE) {
/* process Unicode string */
} else {
/* process binary string */
}
For IS_STRING type, the length represents the number of bytes, and for
IS_UNICODE the number of UChar's. When converting other types (numbers,
booleans, etc) to strings, the exact behavior depends on the Unicode semantics
switch: if on, they are converted to IS_UNICODE, otherwise to IS_STRING.
'u' specifier
-------------
This specifier indicates that the caller requires the incoming parameter
to be a Unicode encoded string. If a non-Unicode string is passed, the engine
creates a copy of the string and automatically convert it to Unicode type before
passing it to the internal function. No such conversion is necessary for Unicode
strings, obviously.
UChar *str;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "u", &str, &len) == FAILURE) {
return;
}
/* process Unicode string */
'T' specifier
-------------
This specifier is useful when the function takes two or more strings and
operates on them. Using 't' specifier for each one would be somewhat
problematic if the passed-in strings are of mixed types, and multiple
checks need to be performed in order to do anything. All parameters
marked by the 'T' specifier are promoted to the same type.
If at least one of the 'T' parameters is of Unicode type, then the rest of
them are converted to IS_UNICODE. Otherwise all 'T' parameters are conveted to
IS_STRING type.
void *str1, *str2;
int len1, len2;
zend_uchar type1, type2;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "TT", &str1, &len1,
&type1, &str2, &len2, &type2) == FAILURE) {
return;
}
if (type1 == IS_UNICODE) {
/* process as Unicode, str2 is guaranteed to be Unicode as well */
} else {
/* process as binary string, str2 is guaranteed to be the same */
}
'x' specifier
-------------
This specifier acts as either 'u' or 's', depending on the value of the
unicode semantics switch. If UG(unicode) is on, it behaves as 'u', and as
's' otherwise.
The existing 's' specifier has been modified as well. If a Unicode string is
passed in, it automatically copies and converts the string to the runtime
encoding, and issues a warning. If a binary type is passed-in, no conversion
is necessary. The '&' modifier can be used after 's' specifier to force
a different converter instead.
char *str;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &str, &len, UG(utf8_conv)) == FAILURE) {
return;
}
/* here str is in UTF-8, if a Unicode string was passed in */
The 'U' and 'S' specifiers are similar to 'u' and 's' but they are more strict
about the type of the passed-in parameter. If 'U' is specified and the binary
string is passed in, the engine will issue a warning instead of doing automatic
conversion. The converse applies to the 'S' specifier.
Working in Unicode World
========================
Strings
-------
A lot of internal functionality is controlled by the unicode.semantics
switch. Its value is found in the Unicode globals variable, UG(unicode). It
is either on or off for the entire request.
The big thing is that there is a new string types: IS_UNICODE.
This has its own storage in the value union part of
zval (value.ustr) while non-unicode (binary) strings reuse the
IS_STRING type and the value.str element of the zval.
New macros exist (parallel to Z_STRVAL/Z_STRLEN) for accessing unicode strings.
Z_USTRVAL(), Z_USTRLEN()
- accesses the value (as a UChar*) and length (in code units) of the Unicode type string
value.ustr.val value.ustr.len
Z_UNIVAL(), Z_UNILEN()
- accesses the value (as a zstr) and length (in type-appropriate units)
value.uni.val value.uni.len
Z_USTRCPLEN()
- gives the number of codepoints (not units) in the Unicode type string
This macro examines the actual string taking into account Surrogate Pairs
and returns the number of UChar32(UTF32) codepoints which may be less than the
number of UChar(UTF16) codeunits found in the string buffer.
If this value will be used repeatedly, consider storing it in a local variable
to avoid having to reexamine the string every time.
ZVAL_* macros
-------------
The 'dup' parameter to the ZVAL_STRING()/RETVAL_STRING()/RETURN_STRING() type
macros has been extended slightly. The following defines are now encouraged instead:
#define ZSTR_DUPLICATE (1<<0)
#define ZSTR_AUTOFREE (1<<1)
ZSTR_DUPLICATE (which has a resulting value of 1) serves the same purpose as a
truth value in old-style 'dup' flags. The value of 1 was specifically chosen
to match the common practice of passing a 1 for this parameter.
Warning: If you find extension code which uses a truth value other than one for
the dup flag, its logic should be modified to explicitly pass ZSTR_DUPLICATE instead.
ZSTR_AUTOFREE is used with macros such as ZVAL_RT_STRING which may populate Unicode
zvals from non-unicode source strings. When UG(unicode) is on, the source string
will be implicitly copied (to make a UChar* version). If the original string
needed copying anyway this is fine. However if the original string was emalloc()'d
and would have ordinarily been given to the engine (i.e. RETURN_STRING(estrdup("foo"), 0))
then it will need to be freed in UG(unicode) mode to avoid leaking.
The ZSTR_AUTOFREE flag ensures that the original string is freed in UG(unicode) mode.
ZVAL_UNICODE(pzv, str, dup), ZVAL_UNICODEL(pzv, str, str_len, dup)
- Sets zval to hold a Unicode string. Takes the same parameters as
Z_STRING(), Z_STRINGL().
ZVAL_U_STRING(conv, pzv, str, dup), ZVAL_U_STRINGL(conv, pzv, str, str_len, dup)
- When UG(unicode) is off, it's equivalent to Z_STRING(), ZSTRINGL()
and the conv parameter is ignored.
When UG(unicode) is on, it sets zval to hold a Unicode representation of the
passed-in string using the UConverter* specified by conv.
Since a new string is always created in this case, passing ZSTR_DUPLICATE
for 'dup' does not matter, but ZSTR_AUTOFREE will be used will be used to
efree the original value
ZVAL_RT_STRING(pzv, str, dup), ZVAL_RT_STRINGL(pzv, str, str_len, dup)
- When UG(unicode) is off, it's equivalent to Z_STRING(), Z_STRINGL().
When UG(unicode) is on, it takes the input string, converts it to Unicode
using the runtime_encoding converter and sets zval to it.
Since a new string is always created in this case, passing ZSTR_DUPLICATE
for 'dup' does not matter, but ZSTR_AUTOFREE will be used will be used to
efree the original value
ZVAL_ASCII_STRING(pzv, str, dup), ZVAL_ASCII_STRINGL(pzv, str, str_len, dup)
- When UG(unicode) is off, it's equivalent to Z_STRING(), Z_STRINGL().
When UG(unicode) is on, it takes the input string, converts it to Unicode
using an ASCII converter and sets zval to it.
Since a new string is always created in this case, passing ZSTR_DUPLICATE
for 'dup' does not matter, but ZSTR_AUTOFREE will be used will be used to
efree the original value
ZVAL_UTF8_STRING(pzv, str, dup), ZVAL_UTF8_STRINGL(pzv, str, str_len, dup)
- When UG(unicode) is off, it's equivalent to Z_STRING(), Z_STRINGL().
When UG(unicode) is on, it takes the input string, converts it to Unicode
using a UTF8 converter and sets zval to it.
Since a new string is always created in this case, passing ZSTR_DUPLICATE
for 'dup' does not matter, but ZSTR_AUTOFREE will be used will be used to
efree the original value
ZVAL_ZSTR(pzv, type, zstr, dup), ZVAL_ZSTRL(pzv, type, zstr, zstr_len, dup)
- This macro uses 'type' to switch between calling ZVAL_STRING(pzv, zstr.s, dup)
and ZVAL_UNICODE(pzv, zstr.u, dup). No conversion happens so the
presense of absense of ZSTR_AUTOFREE is ignored.
ZVAL_TEXT(pzv, zstr, dup), ZVAL_TEXTL(pzv, zstr, zstr_len, dup)
- This macro sets the zval to hold either a Unicode or a normal string,
depending on the value of UG(unicode). No conversion happens, so be certain
that the string passed in matches the type expected by UG(unicode).
One example of its usage would be to initialize zval to hold the name
of a user function.
ZVAL_EMPTY_UNICODE(pzv) / ZVAL_EMPTY_TEXT(pzv)
- These macros work identically to ZVAL_EMPTY_STRING() with the UNICODE
version always generating an IS_UNICODE zval, and the TEXT version
generating a UG(unicode) dependent string type.
ZVAL_UCHAR32(pzv, char)
- Converts the character provided into a UChar string (which may potentially
be 1 or 2 characters long in the case of surrogate pairs) and dispatches
to ZVAL_UNICODEL().
As usual, for each ZVAL_* macro, there is a matching RETVAL_* and RETURN_* macro.
Conversion Macros
-----------------
convert_to_string_with_converter(zval *op, UConverter *conv)
- converts a zval to native string using the specified converter, if necessary.
convert_to_unicode_with_converter(zval *op, UConverter *conv)
- converts a zval to Unicode string using the specified converter, if
necessary.
convert_to_unicode(zval *op)
- converts a zval to Unicode string.
convert_to_string(zval *op)
- Behaves just as it currently does, converting to IS_STRING type
convert_to_text(zval *op)
- converts a zval to either Unicode or native string, depending on the
value of UG(unicode) switch
zend_ascii_to_unicode() function can be used to convert an ASCII char*
string to Unicode. This is useful especially for inline string literals, in
which case you can simply use USTR_MAKE() macro, e.g.:
UChar* ustr;
ustr = USTR_MAKE("main");
If you need to initialize a few such variables, it may be more efficient to
use ICU macros, which avoid the conversion, depending on the platform. See
[1] for more information.
USTR_FREE(zstr) can be used to free a UChar* string safely, since it checks for
NULL argument. USTR_LEN() takes a zstr as its argument, and
depending on the UG(unicode) value, and returns its strlen() or u_strlen().
Array Manipulation
------------------
The add_next_index_*(), add_index_*() and add_assoc_*() functions have been
significantly expanded both to allow for the unicode type as a value and to
permit various types of keys.
Values: In the following examples, {1} represents a placeholder for the keytype and
its arguments (covered later).
add_{1}_unicode(zval *arr, {1}, UChar *ustr, int dup);
add_{1}_unicodel(zval *arr, {1}, UChar *ustr, int ustr_len, int dup);
- Works like add_{1}_string() and add_{1}_stringl() but takes a UChar* value
and adds an IS_UNICODE type.
add_{1}_rt_string(zval *arr, {1}, char *str, int dup);
add_{1}_rt_stringl(zval *arr, {1}, char *str, int str_len, int dup);
- Works like add_{1}_string() and add_{1}_stringl() but converts the char*
value to Unicode using runtime encoding when UG(unicode) is on.
add_{1}_ascii_string(zval *arr, {1}, char *str, int dup);
add_{1}_ascii_stringl(zval *arr, {1}, char *str, int str_len, int dup);
- Works like add_{1}_rt_string() and add_{1}_rt_stringl() but uses
an ASCII converter rather than runtime encoding.
add_{1}_utf8_string(zval *arr, {1}, char *str, int dup);
add_{1}_utf8_stringl(zval *arr, {1}, char *str, int str_len, int dup);
- Works like add_{1}_rt_string() and add_{1}_rt_stringl() but uses
a UTF8 converter rather than runtime encoding.
add_{1}_text(zval *arr, {1}, zstr str, int dup);
add_{1}_textl(zval *arr, {1}, zstr str, int str_len, int dup);
- Wrapper which dispatches to add_{1}_string(l)() or add_{1}_unicode(l)()
depending on the setting of UG(unicode).
add_{1}_zstr(zval *arr, {1}, zend_uchar type, zstr str, int dup);
add_{1}_zstrl(zval *arr, {1}, zend_uchar type, zstr str, int str_len, int dup);
- Works like add_{1}_text() and add_{1}_textl(), but dispatches based on 'type'.
Keys: In the following example, the zval* type is used for values, however
each of the value types (including those listed above) are supported.
The existing key types work as they always have:
add_next_index_zval(zval *arr, zval *val);
add_index_zval(zval *arr, long idx, zval *val);
add_assoc_zval(zval *arr, char *key, zval *val);
add_assoc_zval_ex(zval *arr, char *key, int key_len, zval *val);
. Associative keys are considered binary (IS_STRING)
. Remember that key_len includes the terminating NULL
The following additional methods provide unicode capable keytypes:
add_u_assoc_zval(zval *arr, zend_uchar type, zstr key, zval *val);
add_u_assoc_zval_ex(zval *arr, zend_uchar type, zstr key, int key_len, zval *val);
. When type==IS_STRING, these behave identically to their
add_assoc_zval() and add_assoc_zval_ex() counterparts.
When type==IS_STRING, the key is considered to be Unicode (UChar*).
add_rt_assoc_zval(zval *arr, char *key, zval *val);
add_rt_assoc_zval_ex(zval *arr, char *key, int key_len, zval *val);
. When UG(unicode) is off, these behave identically to their
add_assoc_zval() and add_assoc_zval_ex() counterparts.
When UG(unicode) is on, key is converted to Unicode using runtime encoding.
add_ascii_assoc_zval(zval *arr, char *key, zval *val);
add_ascii_assoc_zval_ex(zval *arr, char *key, int key_len, zval *val);
. When UG(unicode) is off, these behave identically to their
add_assoc_zval() and add_assoc_zval_ex() counterparts.
When UG(unicode) is on, key is converted to Unicode using an ASCII converter.
add_utf8_assoc_zval(zval *arr, char *key, zval *val);
add_utf8_assoc_zval_ex(zval *arr, char *key, int key_len, zval *val);
. When UG(unicode) is off, these behave identically to their
add_assoc_zval() and add_assoc_zval_ex() counterparts.
When UG(unicode) is on, key is converted to Unicode using a UTF8 converter.
Keytype and Valuetype specification may be mixed in any combination, for example:
add_utf8_assoc_ascii_stringl_ex(zval *arr, char *key, int key_len, char *val, int val_len, int dup);
Miscellaneous
-------------
UBYTES() macro can be used to obtain the number of bytes necessary to store
the given number of UChar's. The typical usage is:
char *constant_name = colon + (UG(unicode)?UBYTES(2):2);
Code Points and Code Units
--------------------------
Unicode type strings are in the UTF-16 encoding where 1 Unicode character
may be represented by 1 or 2 UChar's. Each UChar is referred to as a "code
unit", and a full Unicode character as a "code point". Consequently, number
of code units and number of code points for the same Unicode string may be
different. This has many implications, the most important of which is that
you cannot simply index the UChar* string to get the desired codepoint.
The zval's value.ustr.len contains the number of code units (UChar -- UTF16).
To obtain the number of code points, one can use u_countChar32() ICU API
function or Z_USTRCPLEN() macro.
ICU provides a number of macros for working with UTF-16 strings on the
codepoint level [2]. They allow you to do things like obtain a codepoint at
random code unit offset, move forward and backward over the string, etc.
There are two versions of iterator macros, *_SAFE and *_UNSAFE. It is strong
recommended to use *_SAFE version, since they handle unpaired surrogates and
check for string boundaries. Here is an example of how to move through
UChar* string and work on codepoints.
UChar *str = ...;
int32_t str_len = ...;
UChar32 codepoint;
int32_t offset = 0;
while (offset < str_len) {
U16_NEXT(str, offset, str_len, codepoint);
/* now we have the Unicode character in codepoint */
}
There is not macro to get a codepoint at a certain code point offset, but
there is a Zend API function that does it.
inline UChar32 zend_get_codepoint_at(UChar *str, int32_t length, int32_t n);
To retrieve 3rd codepoint, you would call:
zend_get_codepoint_at(str, str_len, 3);
If you have a UChar32 codepoint and need to put it into a UChar* string,
there is another helper function, zend_codepoint_to_uchar(). It takes
a single UChar32 and converts it to a UChar sequence (1 or 2 UChar's).
UChar buf[8];
UChar32 codepoint = 0x101a2;
int8_t num_uchars;
num_uchars = zend_codepoint_to_uchar(codepoint, buf);
The return value is the number of resulting UChar's or 0, which indicates
invalid codepoint.
Memory Allocation
-----------------
For ease of use and to reduce possible bugs, there are memory allocation
functions specific to Unicode strings. Please use them at all times when
allocating UChar's.
eumalloc(size)
eurealloc(ptr, size)
eustrndup(s, length)
eustrdup(s)
peumalloc(size, persistent)
peurealloc(ptr, size, persistent)
The size parameter refers to the number of UChar's, not bytes.
zend_zstrndup(type, zstr, length)
Hashes
------
Hashes API has been upgraded to work with Unicode and binary strings. All
hash functions that worked with string keys now have their equivalent
zend_u_hash_* API. The zend_u_hash_* functions take the type of the key
string as the second argument.
When UG(unicode) switch is on, the IS_STRING keys are upconverted to
IS_UNICODE and then used in the hash lookup.
A new HASH_KEY constant has been added for differentiating key types:
. HASH_KEY_IS_UNICODE
Note that zend_hash_get_current_key_ex() does not have a zend_u_hash_*
version. It returns the key as a char* pointer, you can can cast it
appropriately based on the key type.
Identifiers and Class Entries
-----------------------------
In Unicode mode all the identifiers are Unicode strings. This means that
while various structures such as zend_class_entry, zend_function, etc store
the identifier name as a char* pointer, it will actually point to UChar*
string. Be careful when accessing the names of classes, functions, and such
-- always check UG(unicode) before using them.
Formatted Output
----------------
Since UTF-16 strings frequently contain NULL bytes, you cannot simpley use
%s format to print them out. Towards that end, output functions such as
php_printf(), spprintf(), etc now have three different formats for use with
Unicode strings:
%r
This format treats the corresponding argument as a Unicode string. The
string is automatically converted to the output encoding. If you wish to
apply a different converter to the string, use %*r and pass the
converter before the string argument.
UChar *class_name = USTR_NAME("ReflectionClass");
zend_printf("%r", class_name);
spprintf(&utf8_buffer, 0, "%*r", UG(utf8_conv), class_name);
%R
This format requires at least two arguments: the first one specifies the
type of the string to follow (IS_STRING or IS_UNICODE), and the second
one - the string itself. If the string is of Unicode type, it is
automatically converted to the output encoding. If you wish to apply
a different converter to the string, use %*R and pass the converter
before the string argument.
zend_throw_exception_ex(U_CLASS_ENTRY(reflection_exception_ptr), 0 TSRMLS_CC,
"Interface %R does not exist",
Z_TYPE_P(class_name), Z_UNIVAL_P(class_name));
%v
This format takes only one parameter, the string, but the expected
string type depends on the UG(unicode) value. If the string is of
Unicode type, it is automatically converted to the output encoding. If
you wish to apply a different converter to the string, use %*R and pass
the converter before the string argument.
zend_error(E_WARNING, "%v::__toString() did not return anything",
Z_OBJCE_P(object)->name);
%Z
This format prints a zval's value. You can specify the minimum length
of the string representation using "%*Z" as well as the absolute length
using "%.*Z". The following example is taken from the engine and
therefor uses zend_spprintf rather than spprintf. Further more clen is
an integer that is smaller than Z_UNILEN_P(callable).
zend_spprintf(error, 0, "class '%.*Z' not found", clen, callable);
The function allows to output any kind of zval values, as long as a
string (or unicode) conversion is available. Note that printing non
string zvals outside of request time is not possible.
Since [v]spprintf() can only output native strings there are also the new
functions [v]uspprintf() and [v]zspprintf() that create unicode strings and
return the number of characters printed. That is they return the length rather
than the byte size. The second pair of functions also takes an additional type
parameter that allows to create a string of arbitrary type. The following
example illustrates the use. Assume it fetches a unicode/native string into
path, path_len and path_type inorder to create sub_name, sub_len and sub_type.
zstr path, sub_name;
int path_len, sub_len;
zend_uchar path_type, sub_type;
/* fetch */
if (path.v) {
sub_type = path_type;
sub_len = zspprintf(path_type, &sub_name, 0, "%R%c%s",
path_type, path,
DEFAULT_SLASH,
entry.d_name);
}
Upgrading Functions
===================
Let's take a look at a couple of functions that have been upgraded to
support new string types.
substr()
--------
This functions returns part of a string based on offset and length
parameters.
zstr str;
int str_len, cp_len;
zend_uchar str_type;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tl|l", &str, &str_len, &str_type, &f, &l) == FAILURE) {
return;
}
The first thing we notice is that the incoming string specifier is 't',
which means that we can accept all 3 string types. The 'str' variable is
declared as zstr, because it can point to either UChar* or char*.
The actual type of the incoming string is stored in 'str_type' variable.
if (str_type == IS_UNICODE) {
cp_len = u_countChar32(str.u, str_len);
} else {
cp_len = str_len;
}
If the string is a Unicode one, we cannot rely on the str_len value to tell
us the number of characters in it. Instead, we call u_countChar32() to
obtain it.
The next several lines normalize start and length parameters to fit within the
string. Nothing new here. Then we locate the appropriate segment.
if (str_type == IS_UNICODE) {
int32_t start = 0, end = 0;
U16_FWD_N(str.u, end, str_len, f);
start = end;
U16_FWD_N(str.u, end, str_len, l);
RETURN_UNICODEL(str.u + start, end-start, ZSTR_DUPLICATE);
Since codepoint (character) #n is not necessarily at offset #n in Unicode
strings, we start at the beginning and iterate forward until we have gone
through the required number of codepoints to reach the start of the segment.
Then we save the location in 'start' and continue iterating through the number
of codepoints specified by the offset. Once that's done, we can return the
segment as a Unicode string.
} else {
RETURN_STRINGL(str.s + f, l, ZSTR_DUPLICATE);
}
For native strings, we can return the segment directly.
strrev()
--------
Let's look at strrev() which requires somewhat more complicated upgrade.
While one of the guidelines for upgrades is that combining sequences are not
really taken into account during processing -- substr() can break them up,
for example -- in this case, we actually should be concerned, because
reversing combining sequence may result in a completely different string. To
illustrate:
a (U+0061 LATIN SMALL LETTER A)
o (U+006f LATIN SMALL LETTER O)
+ ' (U+0301 COMBINING ACUTE ACCENT)
+ _ (U+0320 COMBINING MINUS SIGN BELOW)
l (U+006C LATIN SMALL LETTER L)
Reversing this would result in:
l (U+006C LATIN SMALL LETTER L)
+ _ (U+0320 COMBINING MINUS SIGN BELOW)
+ ' (U+0301 COMBINING ACUTE ACCENT)
o (U+006f LATIN SMALL LETTER O)
a (U+0061 LATIN SMALL LETTER A)
All of a sudden the combining marks are being applied to 'l' instead of 'o'.
To avoid this, we need to treat combininig sequences as a unit, by checking
the combining character class of each character with u_getCombiningClass().
strrev() obtains its single argument, a string, and unless the string is of
Unicode type, processes it exactly as before, simply swapping bytes around.
For Unicode case, the magic is like this:
int32_t i, x1, x2;
UChar32 ch;
UChar *u_s, *u_n, *u_p;
u_n = eumalloc(Z_USTRLEN_PP(str)+1);
u_p = u_n;
u_s = Z_USTRVAL_PP(str);
i = Z_USTRLEN_PP(str);
while (i > 0) {
U16_PREV(u_s, 0, i, ch);
if (u_getCombiningClass(ch) == 0) {
u_p += zend_codepoint_to_uchar(ch, u_p);
} else {
x2 = i;
do {
U16_PREV(u_s, 0, i, ch);
} while (u_getCombiningClass(ch) != 0);
x1 = i;
while (x1 <= x2) {
U16_NEXT(u_s, x1, Z_USTRLEN_PP(str), ch);
u_p += zend_codepoint_to_uchar(ch, u_p);
}
}
}
*u_p = 0;
The basic idea is to walk the string backwards from the end, using
U16_PREV() macro. If the combining class of the current character is 0,
meaning it's a base character and not a combining mark, we simply append it
to the new string. Otherwise, we save the location of the index and do a run
over the characters until we get to the next one with combining class 0. At
that point we append the sequence as is, without reversing, to the new
string. Voila.
Note that the code uses zend_codepoint_to_uchar() to convert full Unicode
characters (UChar32 type) to 1 or 2 UTF-16 code units (UChar type).
realpath()
----------
Filenames use their own converter as it's not uncommon, for example,
to need to access files on a filesystem with latin1 entries while outputting
UTF8 runtime content.
The most common approach to parsing filenames can be found in realpath():
zval **ppfilename;
char *filename;
int filename_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &ppfilename) == FAILURE ||
php_stream_path_param_encode(ppfilename, &filename, &filename_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
return;
}
Here, the filename is taken first as a generic zval**, then converted (separating if necessary)
and populated into local char* and int storage. The filename will be converted according to
unicode.filesystem_encoding unless the wrapper specified overrides this with its own conversion
function (The http:// wrapper, for example, enforces utf8 conversion).
rmdir()
-------
If the function accepts a context parameter, then this context should be used in place of FG(default_context)
zval **ppdir, *zcontext = NULL;
char *dir;
int dir_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|r", &ppdir, &zcontext) == FAILURE) {
return;
}
context = php_stream_context_from_zval(zcontext, 0);
if (php_stream_path_param_encode(ppdir, &dir, &dir_len, REPORT_ERRORS, context) == FAILURE) {
return;
}
sqlite_query()
--------------
If the function's underlying library expects a particular encoding (i.e. UTF8), then the alternate form of
the string parameter may be used with zend_parse_parameters().
char *sql;
int sql_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &sql, &sql_len, UG(utf8_conv)) == FAILURE) {
return;
}
Converters
==========
Standard Converters
-------------------
The following converters (UConverter*) are initialized by Zend and are always available (regardless of UG(unicode) mode):
UG(utf8_conv)
UG(ascii_conv)
UG(fallback_encoding_conv) - UTF8 unless overridden by INI setting unicode.fallback_encoding
Additional converters will be optionally initialized depending on INI settings:
UG(runtime_encoding_conv) - unicode.runtime_encoding
. Unicode output generated by a script will be encoding using this converter
UG(script_encoding_conv) - unicode.script_encoding
. Scripts read from disk will be decoded using this converter
UG(filesystem_encoding_conv) - unicode.filesystem_encoding
. Filenames and paths will be encoding using this converter
Since these additional converters may not be instatiated (because their INI value is not set), all uses of these converters must
be wrapped in ZEND_U_CONVERTER() for safety. If the converter hasn't been instantiated, then UG(fallback_encoding_conv) will be
used instead.
For example, RETURN_RT_STRING("foo", ZSTR_DUPLICATE); expands out to:
RETURN_U_STRING(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), "foo", ZSTR_DUPLICATE);
Which uses UG(runtime_encoding_conv) if it's been set, otherwise using UG(fallback_encoding_conv).
Note that the INI setting unicode.stream_encoding does not instantiate a UConverter* automatically for use by the process/thread,
it stores the value as a string for use during fopen() style calls where a UConverter* is instantiated for that particular stream.
References
==========
[1] http://icu.sourceforge.net/apiref/icu4c/ustring_8h.html#a1
[2] http://icu.sourceforge.net/apiref/icu4c/utf16_8h.html
vim: set et ai tw=76 fo=tron21:
+1 -1
View File
@@ -108,7 +108,7 @@ module, program, etc).
For example for APXS:
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php7.c php_apache.c)
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php5.c php_apache.c)
+172
View File
@@ -0,0 +1,172 @@
Updating your script to PHP6
============================
This document attempts to describe portions of PHP that changed or
disapeared in PHP6 and the best practices for upgrading existing
applications to support PHP6.
1. Language
1.1 Functions and function aliases
1.2 Register globals
1.3 Magic quotes
1.4 Register long arrays ($HTTP_*_VARS)
1.5 ZE1 compatibility mode
1.6 dl() function
1.7 E_ALL and E_STRICT constants
1.8 References
2. Unicode (see README.UNICODE-UPGRADES)
2. Extensions
2.1 GD
1.1 Functions and function aliases
------------------------------
<TODO: List all arguments order changes, aliases droped in php6...>
1.2 Register globals
----------------
For security reasons, register_globals has been removed from php6.
ini_get('register_globals') will always return false.
You can emulate its behavior with some minimum changes in your code.
*DISCLAIMER*
people should get a short-term solution if they are willing to run
an insecure app.
Here is an example to emulate the session related functions and
a snippet to register variables:
$_register_globals_order = strrev(ini_get("variables_order"));
$_register_globals_order_len = strlen($_register_globals_order);
for($_register_globals_i=0;$_register_globals_i<$_register_globals_order_len;$_register_globals_i++) {
switch($_register_globals_order{$_register_globals_i}) {
case "E":
extract($_ENV, EXTR_REFS|EXTR_SKIP);
break;
case "G":
extract($_GET, EXTR_REFS|EXTR_SKIP);
break;
case "P":
extract($_POST, EXTR_REFS|EXTR_SKIP);
break;
case "C":
extract($_COOKIE, EXTR_REFS|EXTR_SKIP);
break;
case "S":
extract($_SERVER, EXTR_REFS|EXTR_SKIP);
break;
}
}
unset($_register_globals_order, $_register_globals_order_len, $_register_globals_i);
function session_register($mixed) {
static $started;
if(!isset($started) || session_id() === "") {
session_start();
$started = true;
}
$array = func_get_args();
foreach($array as $mixed) {
if(is_scalar($mixed)) {
$_SESSION[$mixed] =& $GLOBALS[$mixed];
}
elseif(is_array($mixed)) {
foreach($mixed as $name) {
$ok = session_register($name);
if(!$ok) {
return false;
}
}
}
else {
return false;
}
}
return true;
}
function session_is_registered($name) {
if(is_scalar($name)) {
return isset($_SESSION[$name]);
}
return false;
}
function session_unregister($name) {
if(isset($_SESSION[$name]) && is_scalar($name)) {
unset($_SESSION[$name]);
return true;
}
return false;
}
1.3 Magic quotes
------------
1.4 Register long arrays ($HTTP_*_VARS)
-----------------------------------
register_long_arrays and the long versions of super globals had been removed.
PHP will emit E_CORE_ERROR during PHP startup if it would detect
register_long_arrays setting.
You can emulate long arrays by including the following file:
<?php
if (!ini_get('register_long_arrays')) {
$HTTP_POST_VARS =& $_POST;
$HTTP_GET_VARS =& $_GET;
$HTTP_COOKIE_VARS =& $_COOKIE;
$HTTP_SERVER_VARS =& $_SERVER;
$HTTP_ENV_VARS =& $_ENV;
$HTTP_POST_FILES =& $_FILES;
}
?>
1.5 ZE1 compatibility mode
----------------------
ZE1 compatibility mode (PHP4 object model) was introduced to migrate from PHP4
to PHP5 in an easier way, but it never keeped 100% compatibility.
It is completly removed in PHP6, and there is no way to emulate it.
Applications should assume PHP5/PHP6 object model.
1.6 dl() function
-------------
Now dl() function is supported only in CLI, CGI and EMBED SAPI.
There is no way to emulte it. You can just check if dl() is supported by SAPI:
<?php
if (!function_exists("dl")) {
die("dl() function is required\n!");
}
?>
1.7 E_ALL and E_STRICT constants
----------------------------
Now E_ALL error reporting mask includes E_STRICT.
You can filter E_STRICT error messages using the following code:
<?php
error_reporting(error_reporting() & ~E_STRICT);
?>
1.8 References
----------
<TODO: Derick plans to clean the reference mess in php6>
2.1 GD
<TODO: gd2/ft2 only, functions droped>
+112
View File
@@ -0,0 +1,112 @@
Using PHP 5 with the Zeus Web Server
-----------------------------------
Zeus fully supports running PHP in combination with our
webserver. There are three different interfaces that can be used to
enable PHP:
* CGI
* ISAPI
* FastCGI
Of the three, we recommend using FastCGI, which has been tested and
benchmarked as providing the best performance and reliability.
Full details of how to install PHP are available from our
website, at:
http://support.zeus.com/products/php.html
If you have any problems, please check the support site for more
up-to-date information and advice.
Quick guide to installing CGI/FastCGI with Zeus
-----------------------------------------------
Step 1 - Compile PHP as FastCGI.
Compile as follows:
./configure --enable-fastcgi
make
Note that PHP has many options to the configure script -
e.g. --with-mysql. You will probably want to select your usual options
before compiling; the above is just a bare minimum, for illustration.
After compilation finishes, you will be left with an executable
program called 'php'. Copy this into your document root, under a
dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
Step 2 - configure Zeus
Four stages:
- enable FastCGI
- configure FastCGI
- setup alias for FastCGI
- setup alias for PHP
1) Using the admin server, go to the 'module configuration' page for
your virtual server, and ensure that 'fastcgi' is enabled (select the
tickbox to the left).
2) While we can run FastCGI's locally, there are known problems with
some OS's (specifically, the communication between web server and
FastCGI happens over a unix domain socket, and some OS's have trouble
sustaining high connection rates over these sockets). So instead, we
are going to set up the PHP FastCGI to run 'remotely' over localhost
(this uses TCP sockets, which do not suffer this problem). Go to the
'fastcgi configuration' page, and under 'add remote fastcgi':
Add Remote FastCGI
Docroot path /fcgi-bin/php
Remote machine localhost:8002
The first entry is where you saved PHP, above.
The second entry is localhost:<any unused port>
We will start the FastCGI listening on this port shortly.
Click 'update' to commit these changes.
3) Go to the path mapping module and add an alias for FastCGI:
Add Alias
Docroot path /fcgi-bin
Filesystem directory /path/to/docroot/fcgi-bin
Alias type fastcgi
Click 'update' to commit these changes
4) Also on the path mapping module, add a handler for PHP:
Add handler
File extension php
Handler /fcgi-bin/php
Click 'update' to commit these changes
Finally restart your virtual server for these changes to take effect.
Step 3 - start PHP as a FastCGI runner
When you start PHP, it will pre-fork a given number of child processes
to handle incoming PHP requests. Each process will handle a given
number of requests before exiting (and being replaced by a newly
forked process). You can control these two parameters by setting the
following environment variables BEFORE starting the FastCGI runner:
PHP_FCGI_CHILDREN - the number of child processes to pre-fork. This
variable MUST be set, if not then the PHP will not run as a FastCGI.
We recommend a value of 8 for a fairly busy site. If you have many,
long-running PHP scripts, then you may need to increase this further.
PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
handles before exiting. If not set, defaults to 500.
To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
8002 $DOCROOT/fcgi-bin/php'. Substitute the appropriate values for
$ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
above.
To stop the runner (e.g. to experiment with the above environment
variables) you will need to manually stop and running PHP
processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
of children and not the runner, Zeus unfortunately cannot keep track
of what processes are running, sorry. A typical command line may look
like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
'{print $4}' | xargs kill'
+22 -12
View File
@@ -10,16 +10,15 @@ The Input Filter support in PHP 5 is aimed at providing the framework
through which a company-wide or site-wide security policy can be
enforced. It is implemented as a SAPI hook and is called from the
treat_data and post handler functions. To implement your own security
policy you will need to write a standard PHP extension. There is also
a powerful standard implementation in ext/filter that should suit most
peoples' needs. However, if you want to implement your own security
policy, read on.
policy you will need to write a standard PHP extension.
A simple implementation might look like the following. This stores the
original raw user data and adds a my_get_raw() function while the normal
$_POST, $_GET and $_COOKIE arrays are only populated with stripped
data. In this simple example all I am doing is calling strip_tags() on
the data.
the data. If register_globals is turned on, the default globals that
are created will be stripped ($foo) while a $RAW_foo is created with the
original user input.
ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
zval *post_array;
@@ -86,7 +85,7 @@ PHP_MINFO_FUNCTION(my_input_filter)
{
php_info_print_table_start();
php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
php_info_print_table_row( 2, "Revision", "$Id$");
php_info_print_table_row( 2, "Revision", "$Revision$");
php_info_print_table_end();
}
@@ -138,7 +137,7 @@ SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
strcpy(raw_var, "RAW_");
strlcat(raw_var,var,var_len+5);
php_register_variable_ex(raw_var, &new_var, array_ptr);
php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
php_strip_tags(*val, val_len, NULL, NULL, 0);
@@ -153,8 +152,10 @@ PHP_FUNCTION(my_get_raw)
int var_len;
zval **tmp;
zval *array_ptr = NULL;
HashTable *hash_ptr;
char *raw_var;
if(zend_parse_parameters(2, "ls", &arg, &var, &var_len) == FAILURE) {
if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
return;
}
@@ -170,14 +171,23 @@ PHP_FUNCTION(my_get_raw)
break;
}
if(!array_ptr) {
RETURN_FALSE;
}
if(!array_ptr) RETURN_FALSE;
if(zend_hash_find(HASH_OF(array_ptr), var, var_len+5, (void **)&tmp) == SUCCESS) {
/*
* I'm changing the variable name here because when running with register_globals on,
* the variable will end up in the global symbol table
*/
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
strcpy(raw_var, "RAW_");
strlcat(raw_var,var,var_len+5);
hash_ptr = HASH_OF(array_ptr);
if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
*return_value = **tmp;
zval_copy_ctor(return_value);
} else {
RETVAL_FALSE;
}
efree(raw_var);
}
-40
View File
@@ -1,40 +0,0 @@
The PHP Interpreter
===================
This is the github mirror of the official PHP repository located at
http://git.php.net.
[![Build Status](https://secure.travis-ci.org/php/php-src.svg?branch=master)](http://travis-ci.org/php/php-src)
[![Build status](https://ci.appveyor.com/api/projects/status/meyur6fviaxgdwdy?svg=true)](https://ci.appveyor.com/project/php/php-src)
Pull Requests
=============
PHP accepts pull requests via github. Discussions are done on github, but
depending on the topic can also be relayed to the official PHP developer
mailinglist internals@lists.php.net.
New features require an RFC and must be accepted by the developers.
See https://wiki.php.net/rfc and https://wiki.php.net/rfc/voting for more
information on the process.
Bug fixes **do not** require an RFC, but require a bugtracker ticket. Always
open a ticket at https://bugs.php.net and reference the bug id using #NNNNNN.
Fix #55371: get_magic_quotes_gpc() throws deprecation warning
After removing magic quotes, the get_magic_quotes_gpc function caused
a deprecate warning. get_magic_quotes_gpc can be used to detected
the magic_quotes behavior and therefore should not raise a warning at any
time. The patch removes this warning
We do not merge pull requests directly on github. All PRs will be
pulled and pushed through http://git.php.net.
Guidelines for contributors
===========================
- [CODING_STANDARDS](/CODING_STANDARDS)
- [README.GIT-RULES](/README.GIT-RULES)
- [README.MAILINGLIST_RULES](/README.MAILINGLIST_RULES)
- [README.RELEASE_PROCESS](/README.RELEASE_PROCESS)
Regular → Executable
View File
File mode changed.
+153
View File
@@ -0,0 +1,153 @@
Things to do or at least think about doing in the future. Name in
parenthesis means that person has taken on this project.
Zend
----
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
dimensional arrays.
* Look at replacing c-lib call tolower().
* Make hash API functions work with HASH_OF() to save time.
* Native large number support (probably with GNU GMP)
* Const'ify APIs. Right now, many functions leave parameters untouched,
but don't declare those as const. This makes interaction with other
interfaces difficult which pass const parameters to us.
* Clean up object->string conversion behavior wherever possible (switch(),
comparison, etc)
* Port safe-allocation functions from 5.3 (zend_alloc.[ch])
global
------
* Make sure that all ZTS globals get destructed. Most ts_allocate_id()
calls should have a dtor entry.
* on some platforms unimplemented function will just do nothing
(e.g. symlink) they should print a warning or not even be defined!
(DONE ?)
* --enable-all in configure. (--enable-shared=max ...)
* make configure print out a summary when it's done (like XEmacs)
* replace standard functions which work on static data with
reentrancy-safe functions (DONE?).
* make SAPI conform to CGI/1.1. Currently, all SAPI modules
define REMOTE_ADDR etc. themselves and reach only various level
of compliance.
* see what functions might need to be changed to use HashPosition, so
that the internal array pointer is not affected.
Other
* use thread-safe resolver functions (either require BIND 8 or adns).
* implement javadoc based function docs template system.
* provide optional IPv6 support (seems to be done?).
* find a better way to implement script timeouts. SIGVTALRM is used
by some POSIX threads implementations (i.e. OpenBSD) and is not
available in ZTS mode.
* Implement flush feature suitable for nested output buffers.
Streams
-------
* Route filestat.c through the wrapper layer; isolate the statcache code
so that it is independent of php functions and can be applied to any
stream/path.
* Implement generalized connection pool for stated protocols such as
ftp and http/1.1 (using keep-alive) to avoid having to negotiate
new command/request stream for each subsequent call; Possibly store
resources in contexts (creating a default context if necessary) to
allow segmentation of connection pools.
* Add a method to take ownership of the memory buffer in memory streams so
that generating string values for zvals doesn't require an estrdup.
* bundle and use curl lib for fopen wrapper.
documentation
-------------
* Add remarks in the documentation which functions are not implemented
on win32.
* Add remarks in the documentation which functions are not binary-safe.
* Update curl documentation (DONE?)
* Add developer documentation.
* Add detailed documentation for Java extension.
ext/bz2
-------
* Add an ini directive to specify the size of decompression buffer.
The default 4k is too small for large files and also requires much time
for decompression. 40k is suitable for such files, however it may be too
much under certain environments. There should be appropriate default
settings for the various SAPI modules (e.g. apache and cli).
ext/curl
--------
* Have a warning scheme for when people use unsupported features.
ext/oci8
--------
* All OCIFetch*() functions should return 0 for no more data and false on
error.
* Have a flag that trims trailing spaces from CHAR fields on retrieval.
* Make allow_call_time_pass_reference=Off working.
* For additional todo information, see oci8.c, in ext/oci8
ext/odbc
--------
For PHP 4.3.0:
* update all php_error calls to php_error_docref where valid
* integrate EXPERIMENTAL ODBC update for use in PHP 5.0, use for
testing purposes only.
For PHP 5.0.0
* Activate EXPERIMENTAL ODBC codebase update
ext/pcre
--------
* Allow user to set PCRE_NOTEMPTY, PCRE_ANCHORED at execution time, maybe
ext/pcntl
---------
* Change internal callback handler to use TICKS
* Remove all zend_extension code
* Add object callback support to pcntl_signal()
ext/pgsql
---------
For PHP 4.3.0:
* Add pg_metadata() with metadata cache feature.
* Add pg_convert() to check and convert array value for query.
* Add pg_insert/pg_update/pg_delete/pg_select for simple query.
ext/session
-----------
For PHP 4.3.0:
* session_abort() to abort session. ie: Do not save session data.
* Allow unset($_SESSION) or unset($HTTP_SESSION_VARS) to unset
session vars regardless of register_globals setting.
Other:
* Maybe implement finer-grained session variables that could be
locked individually.
* Write a network-transparent storage back-end with fallover
facilities
* Provide a callback facility which is executed upon encountering
an unknown class name during deserialization
ext/standard
------------
* Add a version number to data serialized via serialize().
* Possibly modify parsing of GPC data to automatically create arrays if
variable name is seen more than once.
* Implement regex-cache for url-functions.
* Move socket related functions to fsock.c.
ext/wddx
--------
* See if we can support the remaining data types:
dateTime
binary
http://www.wddx.org/WDDX_SDK_10a/7__References/WDDX_DTD.htm
(Andrei)
* implement wddx_packet_as_javascript(). (Andrei)
other cool stuff
----------------
* PVM extension
vim:et:sw=4:ts=4
+5
View File
@@ -0,0 +1,5 @@
Zend Engine
-----------
- Look at making zend_constant value member be a zval* instead of zval. (Andi)
- Implement inheritance rules for type hints. (Marcus)
- Find a keyword for the if-set-or operator (apply the patch). (Marcus, all)
+109
View File
@@ -0,0 +1,109 @@
Component: Zend Engine 2
Important stuff to finish: PPP members/PPP methods,
support of overloaded extensions, possibly differentiate
between class and namespace as discussed with Stig in
Germany.
Responsibility: Zeev, Andi, Stas
Time frame: Couple of months for first part and extensions will be
ongoing while PHP is being fixed.
Things to leave for later versions: Native aggregation
support, accessing static members via object and not class.
Component: Aggregation
Responsibility: Andi, Stig?
Time frame: ?
Component: Redesign of API Versioning
Responsibility: ?
Time frame: 1 month
Component: Thread Safety
Identify the extensions that are not thread safe by design
or due to dependant libraries and identify them as such.
If possible try to resolve thread safety issue via code
improvements (if php code or patches will be accepted by
library maintainers). For situations where thread safety
cannot easily be acheived a flag in the extension API is
set so PHP can identify non-thread safe extensions. These
extensions will not be loaded in a ZTS compiled binary
(unless it is cli/cgi).
Responsibility: ?
Time frame: ?
Component: SAPI
Environment variables defined in the CGI spec need to be
verified in each SAPI module that they conform to the CGI
spec correctly. If they do not, the SAPI module needs to
fix the variable prior to script execution. Having this
conformity will aid in having PHP scripts run correctly
under different sapi modules.
Responsibility: Shane Caraveo & each sapi module owner
Timeframe: ? (but shouldn't be much effort, most modules are probably ok)
Component: Input Filtering
- Implement a SAPI input filter hook that will get called
just before registering a variable in the
treat_data/post_handler hooks. (done)
- Make sure this is also done in mbstring (done)
- Provide access functions, or perhaps a new
$_RAW_GET/POST/Cookie set of superglobals to get at the
unfiltered data
- Provide a .ini directive which allows people to set their
input filter to one of the built-in strip_tags,
htmlspecialchars or whatever other internal function might
be useful here.
- (The main benefit of this is to make it easier for people
to solve the XSS problem once and for all without having
to go through every line of their code and adding input
validation/filtering everywhere)
Responsibility: Rasmus
Timeframe: Yesterday
Component: RPC Abstraction Layer
Porting java, com, dotnet, xmlrpc, corba, soap and python, srm
(are there more ?) to work with the new oo api and preferably
by using ext/rpc.
Responsibility: Harald
Time frame: 2 months (but i have to wait for a few engine features first)
Component: OO Extensions
Each OO extension has to be revised and rewritten to fit into
the new OO model. We should decide which extensions are a must
to have for the release and which can be ported by the maintainer
later as a separate pecl release.
A list of extensions to be extended that have to be investigated:
* browscap
* aggregate
* all *sql extensions (*_fetch_object)
* domxml (seems like christian is rewriting it anyways)
* ming
Responsibility: Harald (, extension maintainers)
Component: Abstract Data Types (ADT)
Responsibility: Sterling, Harald
Time frame: ?
Component: Test Suite
Extending the test suite with atleast a test for every
function in an extension that doesn't require external
resources. Also developing an automated test thing which
cvs ups's, compiles and tests the build on a daily base on
as much platforms/extensions as possible.
The test suite will also be extended to support threaded
testing and testing for differing sapi modules (via http
calls or other methods).
Reponsibility: Derick (, extension maintainers)
Time frame: 3 months
+1 -1
View File
@@ -1,6 +1,6 @@
## process this file with automake to produce Makefile.am
AUTOMAKE_OPTIONS=foreign
noinst_LTLIBRARIES=libtsrm.la
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c
depend:
+18 -46
View File
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Thread Safe Resource Manager |
+----------------------------------------------------------------------+
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| Copyright (c) 1999-2009, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| This source file is subject to the TSRM license, that is bundled |
| with this package in the file LICENSE |
+----------------------------------------------------------------------+
@@ -22,10 +22,6 @@
typedef struct _tsrm_tls_entry tsrm_tls_entry;
#if defined(TSRM_WIN32)
/* TSRMLS_CACHE_DEFINE; is already done in Zend, this is being always compiled statically. */
#endif
struct _tsrm_tls_entry {
void **storage;
int count;
@@ -181,7 +177,7 @@ TSRM_API void tsrm_shutdown(void)
for (j=0; j<p->count; j++) {
if (p->storage[j]) {
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
resource_types_table[j].dtor(p->storage[j], &p->storage);
}
free(p->storage[j]);
}
@@ -256,7 +252,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
for (j=p->count; j<id_count; j++) {
p->storage[j] = (void *) malloc(resource_types_table[j].size);
if (resource_types_table[j].ctor) {
resource_types_table[j].ctor(p->storage[j]);
resource_types_table[j].ctor(p->storage[j], &p->storage);
}
}
p->count = id_count;
@@ -277,10 +273,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
(*thread_resources_ptr)->storage = NULL;
if (id_count > 0) {
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
}
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
(*thread_resources_ptr)->count = id_count;
(*thread_resources_ptr)->thread_id = thread_id;
(*thread_resources_ptr)->next = NULL;
@@ -289,7 +282,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
tsrm_tls_set(*thread_resources_ptr);
if (tsrm_new_thread_begin_handler) {
tsrm_new_thread_begin_handler(thread_id);
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
}
for (i=0; i<id_count; i++) {
if (resource_types_table[i].done) {
@@ -298,13 +291,13 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
{
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
if (resource_types_table[i].ctor) {
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
}
}
}
if (tsrm_new_thread_end_handler) {
tsrm_new_thread_end_handler(thread_id);
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
}
tsrm_mutex_unlock(tsmm_mutex);
@@ -397,7 +390,7 @@ void tsrm_free_interpreter_context(void *context)
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
}
}
for (i=0; i<thread_resources->count; i++) {
@@ -438,7 +431,7 @@ void *tsrm_new_interpreter_context(void)
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);
@@ -462,7 +455,7 @@ void ts_free_thread(void)
if (thread_resources->thread_id == thread_id) {
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
}
}
for (i=0; i<thread_resources->count; i++) {
@@ -504,7 +497,7 @@ void ts_free_worker_threads(void)
if (thread_resources->thread_id != thread_id) {
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
}
}
for (i=0; i<thread_resources->count; i++) {
@@ -550,7 +543,7 @@ void ts_free_id(ts_rsrc_id id)
while (p) {
if (p->count > j && p->storage[j]) {
if (resource_types_table && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
resource_types_table[j].dtor(p->storage[j], &p->storage);
}
free(p->storage[j]);
p->storage[j] = NULL;
@@ -616,7 +609,7 @@ TSRM_API MUTEX_T tsrm_mutex_alloc(void)
#elif defined(BETHREADS)
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
mutexp->ben = 0;
mutexp->sem = create_sem(1, "PHP sempahore");
mutexp->sem = create_sem(1, "PHP sempahore");
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
@@ -645,7 +638,7 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
st_mutex_destroy(mutexp);
#elif defined(BETHREADS)
delete_sem(mutexp->sem);
free(mutexp);
free(mutexp);
#endif
}
#ifdef THR_DEBUG
@@ -679,8 +672,8 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
#elif defined(TSRM_ST)
return st_mutex_lock(mutexp);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, 1) != 0)
return acquire_sem(mutexp->sem);
if (atomic_add(&mutexp->ben, 1) != 0)
return acquire_sem(mutexp->sem);
return 0;
#endif
}
@@ -711,28 +704,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
#elif defined(TSRM_ST)
return st_mutex_unlock(mutexp);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, -1) != 1)
if (atomic_add(&mutexp->ben, -1) != 1)
return release_sem(mutexp->sem);
return 0;
return 0;
#endif
}
/*
Changes the signal mask of the calling thread
*/
#ifdef HAVE_SIGPROCMASK
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
{
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
/* TODO: add support for other APIs */
#ifdef PTHREADS
return pthread_sigmask(how, set, oldset);
#else
return sigprocmask(how, set, oldset);
#endif
}
#endif
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
{
@@ -798,9 +775,4 @@ void tsrm_error_set(int level, char *debug_filename)
#endif
}
TSRM_API void *tsrm_get_ls_cache(void)
{
return tsrm_tls_get();
}
#endif /* ZTS */
+186
View File
@@ -0,0 +1,186 @@
# Microsoft Developer Studio Project File - Name="TSRM" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=TSRM - Win32 Debug_TS
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "TSRM.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "TSRM.mak" CFG="TSRM - Win32 Debug_TS"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "TSRM - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "TSRM - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "TSRM___Win32_Debug_TS"
# PROP BASE Intermediate_Dir "TSRM___Win32_Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "C:\Projects\TSRM" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=1 /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_DEBUG"
# ADD RSC /l 0x40d /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TSRM___Win32_Release_TS"
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS_inline"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TSRM___Win32_Release_TS_inline"
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS_inline"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TS_inline"
# PROP Intermediate_Dir "Release_TS_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "TSRM_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TSDbg"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TSRM___Win32_Release_TSDbg"
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TSDbg"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TSDbg"
# PROP Intermediate_Dir "Release_TSDbg"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "TSRM - Win32 Debug_TS"
# Name "TSRM - Win32 Release_TS"
# Name "TSRM - Win32 Release_TS_inline"
# Name "TSRM - Win32 Release_TSDbg"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\TSRM.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_strtok_r.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_virtual_cwd.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_win32.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# Begin Source File
SOURCE=.\TSRM.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_config.w32.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_config_common.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_strtok_r.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_virtual_cwd.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_win32.h
# End Source File
# End Group
# End Target
# End Project
+21 -57
View File
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Thread Safe Resource Manager |
+----------------------------------------------------------------------+
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| Copyright (c) 1999-2009, Andi Gutmans, Sascha Schumann, Zeev Suraski |
| This source file is subject to the TSRM license, that is bundled |
| with this package in the file LICENSE |
+----------------------------------------------------------------------+
@@ -20,8 +20,6 @@
# include <tsrm_config.h>
#endif
#include "main/php_stdint.h"
#ifdef TSRM_WIN32
# ifdef TSRM_EXPORTS
# define TSRM_API __declspec(dllexport)
@@ -34,8 +32,13 @@
# define TSRM_API
#endif
typedef intptr_t tsrm_intptr_t;
typedef uintptr_t tsrm_uintptr_t;
#ifdef _WIN64
typedef __int64 tsrm_intptr_t;
typedef unsigned __int64 tsrm_uintptr_t;
#else
typedef long tsrm_intptr_t;
typedef unsigned long tsrm_uintptr_t;
#endif
/* Only compile multi-threading functions if we're in ZTS mode */
#ifdef ZTS
@@ -53,7 +56,7 @@ typedef uintptr_t tsrm_uintptr_t;
#elif defined(TSRM_ST)
# include <st.h>
#elif defined(BETHREADS)
#include <kernel/OS.h>
#include <kernel/OS.h>
#include <TLS.h>
#endif
@@ -84,15 +87,11 @@ typedef struct {
sem_id sem;
int32 ben;
} beos_ben;
# define MUTEX_T beos_ben *
# define MUTEX_T beos_ben *
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
typedef void (*ts_allocate_ctor)(void *);
typedef void (*ts_allocate_dtor)(void *);
typedef void (*ts_allocate_ctor)(void *, void ***);
typedef void (*ts_allocate_dtor)(void *, void ***);
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
@@ -126,8 +125,8 @@ TSRM_API void ts_free_id(ts_rsrc_id id);
#define TSRM_ERROR_LEVEL_CORE 2
#define TSRM_ERROR_LEVEL_INFO 3
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);
TSRM_API int tsrm_error(int level, const char *format, ...);
@@ -139,9 +138,6 @@ TSRM_API MUTEX_T tsrm_mutex_alloc(void);
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
#ifdef HAVE_SIGPROCMASK
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
#endif
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
@@ -152,39 +148,17 @@ 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);
#ifdef TSRM_WIN32
# define TSRM_TLS __declspec(thread)
#else
# define TSRM_TLS __thread
#endif
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_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_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element)
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
#if ZEND_DEBUG
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#else
#define TSRMLS_CACHE_UPDATE() if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
#endif
#define TSRMLS_CACHE _tsrm_ls_cache
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#define TSRMLS_FETCH()
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
#define TSRMLS_D void ***tsrm_ls
#define TSRMLS_DC , TSRMLS_D
#define TSRMLS_C tsrm_ls
#define TSRMLS_CC , TSRMLS_C
#ifdef __cplusplus
}
@@ -195,16 +169,6 @@ TSRM_API void *tsrm_get_ls_cache(void);
#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()
#define TSRMLS_CACHE_UPDATE()
#define TSRMLS_CACHE
#define TSRM_TLS
/* BC only */
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
+1
View File
@@ -0,0 +1 @@
#undef PTHREADS
+1 -1
View File
@@ -33,7 +33,7 @@ $(makefile_in_files): $(makefile_am_files)
aclocal.m4: configure.in acinclude.m4
aclocal
$(config_h_in): configure.in
$(config_h_in): configure.in acconfig.h
# explicitly remove target since autoheader does not seem to work
# correctly otherwise (timestamps are not updated)
@rm -f $@
+6 -2
View File
@@ -1,6 +1,10 @@
// vim:ft=javascript
// $Id$
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_win32.c");
ADD_FLAG("CFLAGS_BD_TSRM", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
if (CHECK_HEADER_ADD_INCLUDE("NewAPIs.h", "CFLAGS_PHP", php_usual_include_suspects)) {
// Need to add the flag directly, since TSRM doesn't include the config
// header
ADD_FLAG("CFLAGS_PHP", "/DHAVE_NEWAPIS_H=1");
}
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
-4
View File
@@ -7,10 +7,6 @@ AC_INIT(TSRM.c)
AM_INIT_AUTOMAKE(TSRM, 1.0, nodefine)
AM_CONFIG_HEADER(tsrm_config.h)
AH_TOP([
#undef PTHREADS
])
sinclude(tsrm.m4)
TSRM_BASIC_CHECKS
-197
View File
@@ -1,197 +0,0 @@
# =================================================================================
# http://www.gnu.org/software/autoconf-archive/ax_func_which_gethostbyname_r.html
# =================================================================================
#
# SYNOPSIS
#
# AX_FUNC_WHICH_GETHOSTBYNAME_R
#
# DESCRIPTION
#
# Determines which historical variant of the gethostbyname_r() call
# (taking three, five, or six arguments) is available on the system and
# defines one of the following macros accordingly:
#
# HAVE_FUNC_GETHOSTBYNAME_R_6
# HAVE_FUNC_GETHOSTBYNAME_R_5
# HAVE_FUNC_GETHOSTBYNAME_R_3
#
# as well as
#
# HAVE_GETHOSTBYNAME_R
#
# If used in conjunction with gethostname.c, the API demonstrated in
# test.c can be used regardless of which gethostbyname_r() is available.
# These example files can be found at
# http://www.csn.ul.ie/~caolan/publink/gethostbyname_r
#
# based on David Arnold's autoconf suggestion in the threads faq
#
# Originally named "AC_caolan_FUNC_WHICH_GETHOSTBYNAME_R". Rewritten for
# Autoconf 2.5x, and updated for 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Caolan McNamara <caolan@skynet.ie>
# Copyright (c) 2008 Daniel Richard G. <skunk@iskunk.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 7
AC_DEFUN([AX_FUNC_WHICH_GETHOSTBYNAME_R], [
AC_LANG_PUSH([C])
AC_MSG_CHECKING([how many arguments gethostbyname_r() takes])
AC_CACHE_VAL([ac_cv_func_which_gethostbyname_r], [
################################################################
ac_cv_func_which_gethostbyname_r=unknown
#
# ONE ARGUMENT (sanity check)
#
# This should fail, as there is no variant of gethostbyname_r() that takes
# a single argument. If it actually compiles, then we can assume that
# netdb.h is not declaring the function, and the compiler is thereby
# assuming an implicit prototype. In which case, we're out of luck.
#
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
(void)gethostbyname_r(name) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=no])
#
# SIX ARGUMENTS
# (e.g. Linux)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret, *retp;
char buf@<:@1024@:>@;
int buflen = 1024;
int my_h_errno;
(void)gethostbyname_r(name, &ret, buf, buflen, &retp, &my_h_errno) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=six])
fi
#
# FIVE ARGUMENTS
# (e.g. Solaris)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret;
char buf@<:@1024@:>@;
int buflen = 1024;
int my_h_errno;
(void)gethostbyname_r(name, &ret, buf, buflen, &my_h_errno) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=five])
fi
#
# THREE ARGUMENTS
# (e.g. AIX, HP-UX, Tru64)
#
if test "$ac_cv_func_which_gethostbyname_r" = "unknown"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
[
char *name = "www.gnu.org";
struct hostent ret;
struct hostent_data data;
(void)gethostbyname_r(name, &ret, &data) /* ; */
])],
[ac_cv_func_which_gethostbyname_r=three])
fi
################################################################
]) dnl end AC_CACHE_VAL
case "$ac_cv_func_which_gethostbyname_r" in
three|five|six)
AC_DEFINE([HAVE_GETHOSTBYNAME_R], [1],
[Define to 1 if you have some form of gethostbyname_r().])
;;
esac
case "$ac_cv_func_which_gethostbyname_r" in
three)
AC_MSG_RESULT([three])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_3], [1],
[Define to 1 if you have the three-argument form of gethostbyname_r().])
;;
five)
AC_MSG_RESULT([five])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_5], [1],
[Define to 1 if you have the five-argument form of gethostbyname_r().])
;;
six)
AC_MSG_RESULT([six])
AC_DEFINE([HAVE_FUNC_GETHOSTBYNAME_R_6], [1],
[Define to 1 if you have the six-argument form of gethostbyname_r().])
;;
no)
AC_MSG_RESULT([cannot find function declaration in netdb.h])
;;
unknown)
AC_MSG_RESULT([can't tell])
;;
*)
AC_MSG_ERROR([internal error])
;;
esac
AC_LANG_POP
]) dnl end AC_DEFUN
+30 -27
View File
@@ -66,7 +66,7 @@ dnl
dnl Check whether the current setup can use POSIX threads calls
dnl
AC_DEFUN([PTHREADS_CHECK_COMPILE], [
AC_LINK_IFELSE([ AC_LANG_SOURCE([
AC_TRY_RUN( [
#include <pthread.h>
#include <stddef.h>
@@ -80,11 +80,18 @@ int main() {
int data = 1;
pthread_mutexattr_init(&mattr);
return pthread_create(&thd, NULL, thread_routine, &data);
} ]) ], [
pthreads_checked=yes
} ], [
pthreads_working=yes
], [
pthreads_checked=no
]
pthreads_working=no
], [
dnl For cross compiling running this test is of no use. NetWare supports pthreads
pthreads_working=no
case $host_alias in
*netware*)
pthreads_working=yes
esac
]
) ] )dnl
dnl
dnl PTHREADS_CHECK()
@@ -122,34 +129,30 @@ else
CFLAGS="$CFLAGS $flag"
PTHREADS_CHECK_COMPILE
CFLAGS=$ac_save
if test "$pthreads_checked" = "yes"; then
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_cflags=$flag
break
fi
done
fi
])
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
ac_cv_pthreads_lib=
if test "$pthreads_working" != "yes"; then
for lib in pthread pthreads c_r; do
ac_save=$LIBS
LIBS="$LIBS -l$lib"
PTHREADS_CHECK_COMPILE
LIBS=$ac_save
if test "$pthreads_checked" = "yes"; then
ac_cv_pthreads_lib=$lib
break
fi
done
fi
])
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
pthreads_working="yes"
fi
fi
])
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
ac_cv_pthreads_lib=
if test "$pthreads_working" != "yes"; then
for lib in pthread pthreads c_r; do
ac_save=$LIBS
LIBS="$LIBS -l$lib"
PTHREADS_CHECK_COMPILE
LIBS=$ac_save
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_lib=$lib
break
fi
done
fi
])
if test "$pthreads_working" = "yes"; then
threads_result="POSIX-Threads found"
+1 -5
View File
@@ -1,4 +1,3 @@
m4_include([TSRM/m4/gethostbyname.m4])
dnl TSRM_CHECK_GCC_ARG(ARG, ACTION-IF-FOUND, ACTION-IF-NOT_FOUND)
AC_DEFUN([TSRM_CHECK_GCC_ARG],[
@@ -31,10 +30,6 @@ AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_CHECK_HEADERS(stdarg.h)
AC_CHECK_FUNCS(sigprocmask)
AX_FUNC_WHICH_GETHOSTBYNAME_R()
])
@@ -92,6 +87,7 @@ else
fi
])
AC_DEFUN([TSRM_THREADS_CHECKS],[
dnl For the thread implementations, we always use --with-*
+8 -1
View File
@@ -2,7 +2,6 @@
#define TSRM_CONFIG_W32_H
#include <../main/config.w32.h>
#include "Zend/zend_config.w32.h"
#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
@@ -12,4 +11,12 @@
#include <stdlib.h>
#include <crtdbg.h>
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif
#endif
+1 -1
View File
@@ -2,7 +2,7 @@
#define TSRM_CONFIG_COMMON_H
#ifndef __CYGWIN__
# ifdef _WIN32
# if WINNT|WIN32
# define TSRM_WIN32
# endif
#endif
+2 -2
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 6 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2017 The PHP Group |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
+2 -2
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 6 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2017 The PHP Group |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
+2 -2
View File
@@ -14,7 +14,7 @@ static inline int in_character_class(char ch, const char *delim)
return 0;
}
TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last)
char *tsrm_strtok_r(char *s, const char *delim, char **last)
{
char *token;
@@ -56,7 +56,7 @@ main()
printf ("Token = '%s'\n", token);
token = tsrm_strtok_r(NULL, "/\\", &last);
}
return 0;
}
+1 -3
View File
@@ -1,8 +1,6 @@
#ifndef TSRM_STRTOK_R
#define TSRM_STRTOK_R
#include "TSRM.h"
TSRM_API char *tsrm_strtok_r(char *s, const char *delim, char **last);
char *tsrm_strtok_r(char *s, const char *delim, char **last);
#endif
File diff suppressed because it is too large. Load diff
+351
View File
@@ -0,0 +1,351 @@
/*
+----------------------------------------------------------------------+
| PHP Version 6 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Sascha Schumann <sascha@schumann.cx> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef VIRTUAL_CWD_H
#define VIRTUAL_CWD_H
#include "TSRM.h"
#include "tsrm_config_common.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef ZTS
#define VIRTUAL_DIR
#endif
#ifndef TSRM_WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif
#if defined(__osf__) || defined(_AIX)
#include <errno.h>
#endif
#ifdef TSRM_WIN32
#include "readdir.h"
#include <sys/utime.h>
/* mode_t isn't defined on Windows */
typedef unsigned short mode_t;
#define DEFAULT_SLASH '\\'
#define DEFAULT_DIR_SEPARATOR ';'
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c) (*(c) == '/' || \
(*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))
#define DEFAULT_U_SLASH ((UChar)0x5c) /*'\\'*/
#define DEFAULT_U_DIR_SEPARATOR ((UChar)0x3b) /*';'*/
#define IS_U_SLASH(c) ((UChar32)(c) == (UChar32)0x2f /*'/'*/ || (UChar32)(c) == (UChar32)0x5c /*'\\'*/)
#define IS_U_SLASH_P(c) IS_SLASH(*(c))
/* COPY_WHEN_ABSOLUTE is 2 under Win32 because by chance both regular absolute paths
in the file system and UNC paths need copying of two characters */
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_UNC_PATH(path, len) \
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))
#elif defined(NETWARE)
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#define DEFAULT_SLASH '/'
#define DEFAULT_DIR_SEPARATOR ';'
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c) IS_SLASH(*(c))
#define DEFAULT_U_SLASH ((UChar)0x2f) /*'/'*/
#define DEFAULT_U_DIR_SEPARATOR ((UChar)0x3b) /*';'*/
#define IS_U_SLASH(c) ((UChar32)(c) == (UChar32)0x2f /*'/'*/ || (UChar32)(c) == (UChar32)0x5c /*'\\'*/)
#define IS_U_SLASH_P(c) IS_U_SLASH(*(c))
/* Colon indicates volume name, either first character should be forward slash or backward slash */
#define IS_ABSOLUTE_PATH(path, len) \
((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
#else
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#define DEFAULT_SLASH '/'
#ifdef __riscos__
#define DEFAULT_DIR_SEPARATOR ';'
#define DEFAULT_U_DIR_SEPARATOR ((UChar)0x3b) /*';'*/
#else
#define DEFAULT_DIR_SEPARATOR ':'
#define DEFAULT_U_DIR_SEPARATOR ((UChar)0x3a) /*':'*/
#endif
#define IS_SLASH(c) ((c) == '/')
#define IS_SLASH_P(c) IS_SLASH(*(c))
#define DEFAULT_U_SLASH ((UChar)0x2f) /*'/'*/
#define IS_U_SLASH(c) ((UChar32)(c) == (UChar32)0x2f /*'/'*/)
#define IS_U_SLASH_P(c) IS_U_SLASH(*(c))
#endif
#ifndef COPY_WHEN_ABSOLUTE
#define COPY_WHEN_ABSOLUTE(path) 0
#endif
#ifndef IS_ABSOLUTE_PATH
#define IS_ABSOLUTE_PATH(path, len) \
(IS_SLASH(path[0]))
#endif
#ifdef TSRM_EXPORTS
#define CWD_EXPORTS
#endif
#ifdef TSRM_WIN32
# ifdef CWD_EXPORTS
# define CWD_API __declspec(dllexport)
# else
# define CWD_API __declspec(dllimport)
# endif
#elif defined(__GNUC__) && __GNUC__ >= 4
# define CWD_API __attribute__ ((visibility("default")))
#else
# define CWD_API
#endif
#ifdef TSRM_WIN32
CWD_API int php_sys_stat(const char *path, struct stat *buf);
#else
# define php_sys_stat stat
#endif
typedef struct _cwd_state {
char *cwd;
int cwd_length;
} cwd_state;
typedef int (*verify_path_func)(const cwd_state *);
CWD_API void virtual_cwd_startup(void);
CWD_API void virtual_cwd_shutdown(void);
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
CWD_API int virtual_chdir(const char *path TSRMLS_DC);
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC);
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC);
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC);
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC);
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
#if !defined(TSRM_WIN32)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC);
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC);
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
#if defined(TSRM_WIN32)
/* these are not defined in win32 headers */
#ifndef W_OK
#define W_OK 0x02
#endif
#ifndef R_OK
#define R_OK 0x04
#endif
#ifndef X_OK
#define X_OK 0x01
#endif
#ifndef F_OK
#define F_OK 0x00
#endif
#endif
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
#endif
/* One of the following constants must be used as the last argument
in virtual_file_ex() call. */
#define CWD_EXPAND 0 /* expand "." and ".." but dont resolve symlinks */
#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC);
#define REALPATH_CACHE_TTL (2*60) /* 2 minutes */
#define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */
typedef struct _realpath_cache_bucket {
unsigned long key;
char *path;
int path_len;
char *realpath;
int realpath_len;
int is_dir;
time_t expires;
#ifdef PHP_WIN32
unsigned char is_rvalid;
unsigned char is_readable;
unsigned char is_wvalid;
unsigned char is_writable;
#endif
struct _realpath_cache_bucket *next;
} realpath_cache_bucket;
typedef struct _virtual_cwd_globals {
cwd_state cwd;
long realpath_cache_size;
long realpath_cache_size_limit;
long realpath_cache_ttl;
realpath_cache_bucket *realpath_cache[1024];
} virtual_cwd_globals;
#ifdef ZTS
extern ts_rsrc_id cwd_globals_id;
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
#else
extern virtual_cwd_globals cwd_globals;
# define CWDG(v) (cwd_globals.v)
#endif
CWD_API void realpath_cache_clean(TSRMLS_D);
CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC);
CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_len, time_t t TSRMLS_DC);
CWD_API int realpath_cache_size(TSRMLS_D);
CWD_API int realpath_cache_max_buckets(TSRMLS_D);
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(TSRMLS_D);
/* The actual macros to be used in programs using TSRM
* If the program defines VIRTUAL_DIR it will use the
* virtual_* functions
*/
#ifdef VIRTUAL_DIR
#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
/* Because open() has two modes, we have to macros to replace it */
#define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
#define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
#define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
#define VCWD_GETWD(buf)
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#if !defined(TSRM_WIN32)
# define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#endif
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
#define VCWD_OPENDIR(pathname) virtual_opendir(pathname TSRMLS_CC)
#define VCWD_POPEN(command, type) virtual_popen(command, type TSRMLS_CC)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
#endif
#endif
#else
#define VCWD_GETCWD(buff, size) getcwd(buff, size)
#define VCWD_FOPEN(path, mode) fopen(path, mode)
#define VCWD_OPEN(path, flags) open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode) open(path, flags, mode)
#define VCWD_CREAT(path, mode) creat(path, mode)
/* rename on windows will fail if newname already exists.
MoveFileEx has to be used */
#if defined(TSRM_WIN32)
# define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0 ? -1 : 0)
#else
# define VCWD_RENAME(oldname, newname) rename(oldname, newname)
#endif
#define VCWD_CHDIR(path) chdir(path)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf) getwd(buf)
#define VCWD_STAT(path, buff) php_sys_stat(path, buff)
#define VCWD_LSTAT(path, buff) lstat(path, buff)
#define VCWD_UNLINK(path) unlink(path)
#define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) rmdir(pathname)
#define VCWD_OPENDIR(pathname) opendir(pathname)
#define VCWD_POPEN(command, type) popen(command, type)
#if defined(TSRM_WIN32)
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
#else
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#endif
#define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC)
#if HAVE_UTIME
# ifdef TSRM_WIN32
# define VCWD_UTIME(path, time) win32_utime(path, time)
# else
# define VCWD_UTIME(path, time) utime(path, time)
# endif
#endif
#define VCWD_CHMOD(path, mode) chmod(path, mode)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
#endif
#endif
#endif
#endif /* VIRTUAL_CWD_H */
+46 -127
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 6 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2017 The PHP Group |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -32,7 +32,7 @@
#ifdef TSRM_WIN32
#include <Sddl.h>
#include "tsrm_win32.h"
#include "zend_virtual_cwd.h"
#include "tsrm_virtual_cwd.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
@@ -40,19 +40,16 @@ static ts_rsrc_id win32_globals_id;
static tsrm_win32_globals win32_globals;
#endif
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
{
#ifdef ZTS
TSRMLS_CACHE_UPDATE();
#endif
globals->process = NULL;
globals->shm = NULL;
globals->process_size = 0;
globals->shm_size = 0;
globals->comspec = _strdup("cmd.exe");
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
/* Set it to INVALID_HANDLE_VALUE
* It will be initialized correctly in tsrm_win32_access or set to
* It will be initialized correctly in tsrm_win32_access or set to
* NULL if no impersonation has been done.
* the impersonated token can't be set here as the impersonation
* will happen later, in fcgi_accept_request (or whatever is the
@@ -62,7 +59,7 @@ TSRMLS_CACHE_UPDATE();
globals->impersonation_token_sid = NULL;
}
static void tsrm_win32_dtor(tsrm_win32_globals *globals)
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
{
shm_pair *ptr;
@@ -95,32 +92,30 @@ TSRM_API void tsrm_win32_startup(void)
#ifdef ZTS
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
#else
tsrm_win32_ctor(&win32_globals);
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
#endif
}
TSRM_API void tsrm_win32_shutdown(void)
{
#ifndef ZTS
tsrm_win32_dtor(&win32_globals);
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
#endif
}
char * tsrm_win32_get_path_sid_key(const char *pathname)
char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC)
{
PSID pSid = TWG(impersonation_token_sid);
DWORD sid_len = pSid ? GetLengthSid(pSid) : 0;
TCHAR *ptcSid = NULL;
char *bucket_key = NULL;
size_t ptc_sid_len, pathname_len;
pathname_len = strlen(pathname);
if (!pSid) {
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pathname_len + 1);
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + 1);
if (!bucket_key) {
return NULL;
}
memcpy(bucket_key, pathname, pathname_len);
memcpy(bucket_key, pathname, strlen(pathname));
return bucket_key;
}
@@ -128,16 +123,14 @@ char * tsrm_win32_get_path_sid_key(const char *pathname)
return NULL;
}
ptc_sid_len = strlen(ptcSid);
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pathname_len + ptc_sid_len + 1);
bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + strlen(ptcSid) + 1);
if (!bucket_key) {
LocalFree(ptcSid);
return NULL;
}
memcpy(bucket_key, ptcSid, ptc_sid_len);
memcpy(bucket_key + ptc_sid_len, pathname, pathname_len + 1);
memcpy(bucket_key, ptcSid, strlen(ptcSid));
memcpy(bucket_key + strlen(ptcSid), pathname, strlen(pathname) + 1);
LocalFree(ptcSid);
return bucket_key;
@@ -146,8 +139,11 @@ char * tsrm_win32_get_path_sid_key(const char *pathname)
PSID tsrm_win32_get_token_sid(HANDLE hToken)
{
BOOL bSuccess = FALSE;
DWORD dwLength = 0;
PTOKEN_USER pTokenUser = NULL;
PSID sid;
PSID *ppsid = &sid;
DWORD sid_len;
PSID pResultSid = NULL;
@@ -197,7 +193,7 @@ Finished:
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
{
time_t t;
HANDLE thread_token = NULL;
HANDLE thread_token;
PSID token_sid;
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
@@ -208,16 +204,19 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
BYTE * psec_desc = NULL;
BOOL fAccess = FALSE;
BOOL bucket_key_alloc = FALSE;
realpath_cache_bucket * bucket = NULL;
char * real_path = NULL;
TSRMLS_FETCH();
if (mode == 1 /*X_OK*/) {
DWORD type;
return GetBinaryType(pathname, &type) ? 0 : -1;
} else {
if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
real_path = (char *)malloc(MAX_PATH);
if(tsrm_realpath(pathname, real_path) == NULL) {
if(tsrm_realpath(pathname, real_path TSRMLS_CC) == NULL) {
goto Finished;
}
pathname = real_path;
@@ -245,6 +244,7 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
was impersonating already, this function uses that impersonation context.
*/
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
DWORD err = GetLastError();
if (GetLastError() == ERROR_NO_TOKEN) {
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
TWG(impersonation_token) = NULL;
@@ -281,14 +281,14 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode)
if (CWDG(realpath_cache_size_limit)) {
t = time(0);
bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
if(bucket == NULL && real_path == NULL) {
/* We used the pathname directly. Call tsrm_realpath */
/* so that entry is created in realpath cache */
real_path = (char *)malloc(MAX_PATH);
if(tsrm_realpath(pathname, real_path) != NULL) {
if(tsrm_realpath(pathname, real_path TSRMLS_CC) != NULL) {
pathname = real_path;
bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC);
}
}
}
@@ -365,9 +365,6 @@ Finished_Impersonate:
}
Finished:
if(thread_token != NULL) {
CloseHandle(thread_token);
}
if(real_path != NULL) {
free(real_path);
real_path = NULL;
@@ -383,7 +380,7 @@ Finished:
}
static process_pair *process_get(FILE *stream)
static process_pair *process_get(FILE *stream TSRMLS_DC)
{
process_pair *ptr;
process_pair *newptr;
@@ -413,6 +410,7 @@ static shm_pair *shm_get(int key, void *addr)
{
shm_pair *ptr;
shm_pair *newptr;
TSRMLS_FETCH();
for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
if (!ptr->descriptor) {
@@ -437,7 +435,6 @@ static shm_pair *shm_get(int key, void *addr)
TWG(shm) = newptr;
ptr = newptr + TWG(shm_size);
TWG(shm_size)++;
memset(ptr, 0, sizeof(*ptr));
return ptr;
}
@@ -451,14 +448,13 @@ static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
TSRM_API FILE *popen(const char *command, const char *type)
{
return popen_ex(command, type, NULL, NULL);
}
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
{
FILE *stream = NULL;
int fno, type_len, read, mode;
int fno, type_len = strlen(type), read, mode;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
@@ -473,12 +469,14 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
HANDLE token_user = NULL;
BOOL asuser = TRUE;
TSRMLS_FETCH();
if (!type) {
return NULL;
}
/*The following two checks can be removed once we drop XP support */
type_len = (int)strlen(type);
type_len = strlen(type);
if (type_len <1 || type_len > 2) {
return NULL;
}
@@ -534,10 +532,6 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
if (!cmd) {
return NULL;
}
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
if (asuser) {
res = CreateProcessAsUser(token_user, NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
@@ -552,7 +546,7 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
}
CloseHandle(process.hThread);
proc = process_get(NULL);
proc = process_get(NULL TSRMLS_CC);
if (read) {
fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode);
@@ -572,8 +566,9 @@ TSRM_API int pclose(FILE *stream)
{
DWORD termstat = 0;
process_pair *process;
TSRMLS_FETCH();
if ((process = process_get(stream)) == NULL) {
if ((process = process_get(stream TSRMLS_CC)) == NULL) {
return 0;
}
@@ -599,50 +594,33 @@ TSRM_API int shmget(int key, int size, int flags)
return -1;
}
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
if (!shm_handle && !info_handle) {
if ((!shm_handle && !info_handle)) {
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
created = TRUE;
}
if (!shm_handle || !info_handle) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
if ((!shm_handle || !info_handle)) {
return -1;
}
} else {
if (flags & IPC_EXCL) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
return -1;
}
}
shm = shm_get(key, NULL);
if (!shm) {
CloseHandle(shm_handle);
CloseHandle(info_handle);
return -1;
}
shm->segment = shm_handle;
shm->info = info_handle;
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (NULL != shm->descriptor && created) {
if (created) {
shm->descriptor->shm_perm.key = key;
shm->descriptor->shm_segsz = size;
shm->descriptor->shm_ctime = time(NULL);
@@ -656,10 +634,8 @@ TSRM_API int shmget(int key, int size, int flags)
shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
}
if (NULL != shm->descriptor && (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz)) {
if (NULL != shm->segment) {
CloseHandle(shm->segment);
}
if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
CloseHandle(shm->segment);
UnmapViewOfFile(shm->descriptor);
CloseHandle(shm->info);
return -1;
@@ -676,21 +652,12 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags)
return (void*)-1;
}
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (NULL == shm->addr) {
int err = GetLastError();
/* Catch more errors */
if (ERROR_NOT_ENOUGH_MEMORY == err) {
_set_errno(ENOMEM);
}
return (void*)-1;
}
shm->descriptor->shm_atime = time(NULL);
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch++;
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
return shm->addr;
}
@@ -748,52 +715,4 @@ TSRM_API char *realpath(char *orig_path, char *buffer)
return buffer;
}
#if HAVE_UTIME
static zend_always_inline void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
ll = Int32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
/* }}} */
TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */
{
FILETIME mtime, atime;
HANDLE hFile;
hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
/* OPEN_ALWAYS mode sets the last error to ERROR_ALREADY_EXISTS but
the CreateFile operation succeeds */
if (GetLastError() == ERROR_ALREADY_EXISTS) {
SetLastError(0);
}
if ( hFile == INVALID_HANDLE_VALUE ) {
return -1;
}
if (!buf) {
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &mtime);
atime = mtime;
} else {
UnixTimeToFileTime(buf->modtime, &mtime);
UnixTimeToFileTime(buf->actime, &atime);
}
if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
return 1;
}
/* }}} */
#endif
#endif
+4 -8
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 7 |
| PHP Version 6 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2017 The PHP Group |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -23,9 +23,6 @@
#include "TSRM.h"
#include <windows.h>
#if HAVE_UTIME
# include <sys/utime.h>
#endif
struct ipc_perm {
int key;
@@ -71,8 +68,7 @@ typedef struct {
} tsrm_win32_globals;
#ifdef ZTS
# define TWG(v) TSRMG_STATIC(win32_globals_id, tsrm_win32_globals *, v)
TSRMLS_CACHE_EXTERN()
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
#else
# define TWG(v) (win32_globals.v)
#endif
@@ -94,7 +90,7 @@ TSRMLS_CACHE_EXTERN()
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
char * tsrm_win32_get_path_sid_key(const char *pathname );
char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC);
TSRM_API void tsrm_win32_startup(void);
TSRM_API void tsrm_win32_shutdown(void);
-850
View File
@@ -1,850 +0,0 @@
PHP 7.0 UPGRADE NOTES
1. Backward Incompatible Changes
2. New Features
3. Changes in SAPI modules
4. Deprecated Functionality
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
12. Windows Support
13. Other Changes
========================================
1. Backward Incompatible Changes
========================================
Language changes
================
Changes to variable handling
----------------------------
* Indirect variable, property and method references are now interpreted with
left-to-right semantics. Some examples:
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()
To restore the previous behavior add explicit curly braces:
${$foo['bar']['baz']}
$foo->{$bar['baz']}
$foo->{$bar['baz']}()
Foo::{$bar['baz']}()
* The global keyword now only accepts simple variables. Instead of
global $$foo->bar;
it is now required to write the following:
global ${$foo->bar};
* Parentheses around variables or function calls no longer have any influence
on behavior. For example the following code, where the result of a function
call is passed to a by-reference function
function getArray() { return [1, 2, 3]; }
$last = array_pop(getArray());
// Strict Standards: Only variables should be passed by reference
$last = array_pop((getArray()));
// Strict Standards: Only variables should be passed by reference
will now throw a strict standards error regardless of whether parentheses
are used. Previously no notice was generated in the second case.
* Array elements or object properties that are automatically created during
by-reference assignments will now result in a different order. For example
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
now results in the array ["a" => 1, "b" => 1], while previously the result
was ["b" => 1, "a" => 1];
Relevant RFCs:
* https://wiki.php.net/rfc/uniform_variable_syntax
* https://wiki.php.net/rfc/abstract_syntax_tree
Changes to list()
-----------------
* list() will no longer assign variables in reverse order. For example
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only
the **order** of the assignments changed, but the assigned values stay the
same. E.g. a normal usage like
list($a, $b, $c) = [1, 2, 3];
// $a = 1; $b = 2; $c = 3;
will retain its current behavior.
* Empty list() assignments are no longer allowed. As such all of the following
are invalid:
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
* list() no longer supports unpacking strings (while previously this was only
supported in some cases). The code
$string = "xy";
list($x, $y) = $string;
will now result in $x == null and $y == null (without notices) instead of
$x == "x" and $y == "y". Furthermore list() is now always guaranteed to
work with objects implementing ArrayAccess, e.g.
list($a, $b) = (object) new ArrayObject([0, 1]);
will now result in $a == 0 and $b == 1. Previously both $a and $b were null.
Relevant RFCs:
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency
Changes to foreach
------------------
* Iteration with foreach() no longer has any effect on the internal array
pointer, which can be accessed through the current()/next()/etc family of
functions. For example
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
will now print the value int(0) three times. Previously the output was int(1),
int(2) and bool(false).
* When iterating arrays by-value, foreach will now always operate on a copy of
the array, as such changes to the array during iteration will not influence
iteration behavior. For example
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}
will now print all three elements (0 1 2), while previously the second element
1 was skipped (0 2).
* When iterating arrays by-reference, modifications to the array will continue
to influence the iteration. However PHP will now do a better job of
maintaining a correct position in a number of cases. E.g. appending to an
array during by-reference iteration
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
will now iterate over the appended element as well. As such the output of this
example will now be "int(0) int(1)", while previously it was only "int(0)".
* Iteration of plain (non-Traversable) objects by-value or by-reference will
behave like by-reference iteration of arrays. This matches the previous
behavior apart from the more accurate position management mentioned in the
previous point.
* Iteration of Traversable objects remains unchanged.
Relevant RFC: https://wiki.php.net/rfc/php7_foreach
Changes to parameter handling
-----------------------------
* It is no longer possible to define two function parameters with the same name.
For example, the following method will trigger a compile-time error:
public function foo($a, $b, $unused, $unused) {
// ...
}
Code like this should be changed to use distinct parameter names, for example:
public function foo($a, $b, $unused1, $unused2) {
// ...
}
* The func_get_arg() and func_get_args() functions will no longer return the
original value that was passed to a parameter and will instead provide the
current value (which might have been modified). For example
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
will now print "2" instead of "1". This code should be changed to either
perform modifications only after calling func_get_arg(s)
function foo($x) {
var_dump(func_get_arg(0));
$x++;
}
or avoid modifying the parameters altogether:
function foo($x) {
$newX = $x + 1;
var_dump(func_get_arg(0));
}
* Similarly exception backtraces will no longer display the original value that
was passed to a function and show the modified value instead. For example
function foo($x) {
$x = 42;
throw new Exception;
}
foo("string");
will now result in the stack trace
Stack trace:
#0 file.php(4): foo(42)
#1 {main}
while previously it was:
Stack trace:
#0 file.php(4): foo('string')
#1 {main}
While this should not impact runtime behavior of your code, it is worthwhile
to be aware of this difference for debugging purposes.
The same limitation also applies to debug_backtrace() and other functions
inspecting function arguments.
Relevant RFC: https://wiki.php.net/phpng
Changes to integer handling
---------------------------
* Invalid octal literals (containing digits larger than 7) now produce compile
errors. For example, the following is no longer valid:
$i = 0781; // 8 is not a valid octal digit!
Previously the invalid digits (and any following valid digits) were simply
ignored. As such $i previously held the value 7, because the last two digits
were silently discarded.
* Bitwise shifts by negative numbers will now throw an ArithmeticError:
var_dump(1 >> -1);
// ArithmeticError: Bit shift by negative number
* Left bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0:
var_dump(1 << 64); // int(0)
Previously the behavior of this code was dependent on the used CPU
architecture. For example on x86 (including x86-64) the result was int(1),
because the shift operand was wrapped.
* Similarly right bitwise shifts by a number of bits beyond the bit width of an
integer will always result in 0 or -1 (depending on sign):
var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)
Relevant RFC: https://wiki.php.net/rfc/integer_semantics
Changes to string handling
--------------------------
* Strings that contain hexadecimal numbers are no longer considered to be
numeric and don't receive special treatment anymore. Some examples of the
new behavior:
var_dump("0x123" == "291"); // bool(false) (previously true)
var_dump(is_numeric("0x123")); // bool(false) (previously true)
var_dump("0xe" + "0x1"); // int(0) (previously 16)
var_dump(substr("foo", "0x1")); // string(3) "foo" (previously "oo")
// Notice: A non well formed numeric value encountered
filter_var() can be used to check if a string contains a hexadecimal number
or convert such a string into an integer:
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
* Due to the addition of the Unicode Codepoint Escape Syntax for double-quoted
strings and heredocs, "\u{" followed by an invalid sequence will now result in
an error:
$str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence
To avoid this the leading backslash should be escaped:
$str = "\\u{xyz}"; // Works fine
However, "\u" without a following { is unaffected. As such the following code
won't error and will work the same as before:
$str = "\u202e"; // Works fine
Relevant RFCs:
* https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings
* https://wiki.php.net/rfc/unicode_escape
Changes to error handling
-------------------------
* There are now two exception classes: Exception and Error. Both classes
implement a new interface Throwable. Type hints in exception handling code
may need to be changed to account for this.
* Some fatal errors and recoverable fatal errors now throw an Error instead.
As Error is a separate class from Exception, these exceptions will not be
caught by existing try/catch blocks.
For the recoverable fatal errors which have been converted into an exception,
it is no longer possible to silently ignore the error from an error handler.
In particular, it is no longer possible to ignore type hint failures.
* Parser errors now generate a ParseError that extends Error. Error
handling for eval()s on potentially invalid code should be changed to catch
ParseError in addition to the previous return value / error_get_last()
based handling.
* Constructors of internal classes will now always throw an exception on
failure. Previously some constructors returned NULL or an unusable object.
* The error level of some E_STRICT notices has been changed.
Relevant RFCs:
* https://wiki.php.net/rfc/engine_exceptions_for_php7
* https://wiki.php.net/rfc/throwable-interface
* https://wiki.php.net/rfc/internal_constructor_behaviour
* https://wiki.php.net/rfc/reclassify_e_strict
Other language changes
----------------------
* Removed support for static calls to non-static methods from an incompatible
$this context. In this case $this will not be defined, but the call will be
allowed with a deprecation notice. An example:
class A {
public function test() { var_dump($this); }
}
// Note: Does NOT extend A
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
// Deprecated: Non-static method A::test() should not be called statically
// Notice: Undefined variable $this
NULL
Note that this only applies to calls from an incompatible context. If class B
extended from A the call would be allowed without any notices.
* It is no longer possible to use the following class, interface and trait names
(case-insensitive):
bool
int
float
string
null
false
true
This applies to class/interface/trait declarations, class_alias() and use
statements.
Furthermore the following class, interface and trait names are now reserved
for future use, but do not yet throw an error when used:
resource
object
mixed
numeric
* The yield language construct no longer requires parentheses when used in an
expression context. It is now a right-associative operator with precedence
between the "print" and "=>" operators. This can result in different behavior
in some cases, for example:
echo yield -1;
// Was previously interpreted as
echo (yield) - 1;
// And is now interpreted as
echo yield (-1);
yield $foo or die;
// Was previously interpreted as
yield ($foo or die);
// And is now interpreted as
(yield $foo) or die;
Such cases can always be resolved by adding additional parentheses.
. Removed ASP (<%) and script (<script language=php>) tags.
(RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
. Removed support for assigning the result of new by reference.
. Removed support for scoped calls to non-static methods from an incompatible
$this context. See details in https://wiki.php.net/rfc/incompat_ctx.
. Removed support for #-style comments in ini files. Use ;-style comments
instead.
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
Standard library changes
========================
. substr() now returns an empty string instead of FALSE when the truncation happens on boundaries.
. call_user_method() and call_user_method_array() no longer exists.
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
output buffer is created in an output buffer handler.
. The internal sorting algorithm has been improved, what may result in
different sort order of elements that compare as equal.
. Removed dl() function on fpm-fcgi.
. setcookie() with an empty cookie name now issues a WARNING and doesn't send an empty set-cookie header line anymore.
Other
=====
- Curl:
. Removed support for disabling the CURLOPT_SAFE_UPLOAD option. All curl file
uploads must use the curl_file / CURLFile APIs.
. curl_getinfo($ch, CURLINFO_CERTINFO) returns certificate Subject and Issuer
as a string (PHP >= 5.6.25)
- Date:
. Removed $is_dst parameter from mktime() and gmmktime().
- DBA
. dba_delete() now returns false if the key was not found for the inifile
handler, too.
- GMP
. Requires libgmp version 4.2 or newer now.
. gmp_setbit() and gmp_clrbit() now return FALSE for negative indices, making
them consistent with other GMP functions.
- Intl:
. Removed deprecated aliases datefmt_set_timezone_id() and
IntlDateFormatter::setTimeZoneID(). Use datefmt_set_timezone() and
IntlDateFormatter::setTimeZone() instead.
- libxml:
. Added LIBXML_BIGLINES parser option. It's available starting with libxml 2.9.0
and adds suppport for line numbers >16-bit in the error reporting.
- Mcrypt
. Removed deprecated mcrypt_generic_end() alias in favor of
mcrypt_generic_deinit().
. Removed deprecated mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb()
functions in favor of mcrypt_encrypt() and mcrypt_decrypt() with an
MCRYPT_MODE_* flag.
- Session
. session_start() accepts all INI settings as array. e.g. ['cache_limiter'=>'private']
sets session.cache_limiter=private. It also supports 'read_and_close' which closes
session data immediately after read data.
. Save handler accepts validate_sid(), update_timestamp() which validates session
ID existence, updates timestamp of session data. Compatibility of old user defined
save handler is retained.
. SessionUpdateTimestampHandlerInterface is added. validateSid(), updateTimestamp()
is defined in the interface.
. session.lazy_write(default=On) INI setting enables only write session data when
session data is updated.
. session_regenerate_id() saves current $_SESSION before creating new session ID.
- Opcache
. Removed opcache.load_comments configuration directive. Now doc comments
loading costs nothing and always enabled.
- OpenSSL:
. Removed the "rsa_key_size" SSL context option in favor of automatically
setting the appropriate size given the negotiated crypto algorithm.
. Removed "CN_match" and "SNI_server_name" SSL context options. Use automatic
detection or the "peer_name" option instead.
- PCRE:
. Removed support for /e (PREG_REPLACE_EVAL) modifier. Use
preg_replace_callback() instead.
- PDO_pgsql:
. Removed PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT attribute in favor of
ATTR_EMULATE_PREPARES.
- Standard:
. Removed string category support in setlocale(). Use the LC_* constants
instead.
. Removed set_magic_quotes_runtime() and its alias magic_quotes_runtime().
- JSON:
. Rejected RFC 7159 incompatible number formats in json_decode string -
top level (07, 0xff, .1, -.1) and all levels ([1.], [1.e1])
. Calling json_decode with 1st argument equal to empty PHP string or value that
after casting to string is empty string (NULL, FALSE) results in JSON syntax error.
- Stream:
. Removed set_socket_blocking() in favor of its alias stream_set_blocking().
- XML:
. xml_set_object() now requires to manually unset the $parser when finished,
to avoid memory leaks.
- XSL:
. Removed xsl.security_prefs ini option. Use XsltProcessor::setSecurityPrefs()
instead.
========================================
2. New Features
========================================
- Core
. Added group use declarations.
(RFC: https://wiki.php.net/rfc/group_use_declarations)
. Added null coalesce operator (??).
(RFC: https://wiki.php.net/rfc/isset_ternary)
. Support for strings with length >= 2^31 bytes in 64 bit builds.
. Closure::call() method added (works only with userland classes).
. Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings
and heredocs.
. define() now supports arrays as constant values, fixing an oversight where
define() did not support arrays yet const syntax did.
. Added the comparison operator (<=>), aka the spaceship operator.
(RFC: https://wiki.php.net/rfc/combined-comparison-operator)
. Added the yield from operator for delegating Generators like coroutines.
(RFC: https://wiki.php.net/rfc/generator-delegation)
. Reserved keywords can now be used in various new contexts.
(RFC: https://wiki.php.net/rfc/context_sensitive_lexer)
. Added support for scalar type declarations and strict mode using
declare(strict_types=1) (RFC: https://wiki.php.net/rfc/scalar_type_hints_v5)
. Added support for cryptographically secure user land RNG
(RFC: https://wiki.php.net/rfc/easy_userland_csprng)
- Opcache
. Added second level file based opcode cache. It may be enabled by setting
opcache.file_cache=<DIR> configuration directive in php.ini. The second
level cache may improve performance when SHM is full, at server restart or
SHM reset. In addition, it's possibe to use file cache without SHM at all,
using opcache.file_cache_only=1 (this may be useful for sharing hosting),
and disable file cache consistency check, to speedup loading at the cost of
safety, using opcache.file_cache_consistency_checks=0.
. Added ability to move PHP code pages (PHP TEXT segment) into HUGE pages.
It's possible to enable/disable this feature in php.ini through
opcache.huge_code_pages=0/1. OS should be configured to provide huge pages.
. Added Windows only opcache.file_cache_fallback=1 ini option, which implies
the implemented fallback mechanism. When OPcache was not able to reattach
the shared memory segment to the desired address and opcache.file_cache
is on, opcache.file_cache_only=1 will be automatically enforced.
- OpenSSL
. Added "alpn_protocols" SSL context option allowing encrypted client/server
streams to negotiate alternative protocols using the ALPN TLS extension when
built against OpenSSL 1.0.2 or newer. Negotiated protocol information is
accessible through stream_get_meta_data() output.
- Reflection
. Added a ReflectionGenerator class (yield from Traces, current file/line,
etc.)
. Added a ReflectionType class to better support the new return type and
scalar type declarations features. The new ReflectionParameter::getType()
and ReflectionFunctionAbstract::getReturnType() methods both return an
instance of ReflectionType.
- Stream:
. New Windows only stream context options was added to allow blocking reads
on pipes. To enable it, pass array("pipe" => array("blocking" => true))
when creating the stream context. Be aware, that this option can under
circumstances cause dead locks on the pipe buffer. However it can be useful
in several CLI use case scenarios.
========================================
3. Changes in SAPI modules
========================================
- FPM
. Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes).
. Listen = port now listen on all addresses (IPv6 and IPv4-mapped).
========================================
4. Deprecated Functionality
========================================
- Core
. PHP 4 style constructors, where the constructor name is the same as the
class name, are now deprecated.
. Static calls to non-static methods are now deprecated.
- OpenSSL
. The "capture_session_meta" SSL context option is now deprecated. Meta
data concerning active crypto on a stream resource is now accessible
through the return result from stream_get_meta_data().
========================================
5. Changed Functions
========================================
- unserialize():
. Added second parameter for unserialize function
(RFC: https://wiki.php.net/rfc/secure_unserialize) allowing to specify
acceptable classes:
unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
- proc_open():
. The maximum number of pipes used by proc_open() was previously limited by
hardcoded value of 16. This limit is now removed and the number of pipes is
effectively limited by the amount of memory available to PHP.
. New Windows only configuration option "blocking_pipes" can be used to
force blocking reads on child process pipes. This covers several
edge cases in CLI usage however can lead to dead locks. Also, this
correlates with the new stream context options for pipes.
- array_column():
The function now supports an array of objects as well as two-dimensional
arrays. Only public properties are considered, and objects that make use of
__get() for dynamic properties must also implement __isset().
- stream_context_create()
It accepts now a Windows only configuration
array("pipe" => array("blocking" => <boolean>)) which forces blocking reads
on pipes. This option should be used carefully because due to the
platform restrictions dead locks on pipe buffers are possible.
- dirname()
A new optional argument ($levels) allow to go up various times
dirname(dirname($foo)) => dirname($foo, 2);
- debug_zval_dump
It prints now "int" instead of "long", and "float" instead of "double".
- getenv()
Since 7.0.9, getenv() has optional second parameter, making it only
consider local environment and not SAPI environment if true.
- fopen()
Since 7.0.16, mode 'e' was added, which sets the close-on-exec flag
on the opened file descriptor. This mode is only available in PHP compiled on
POSIX.1-2008 conform systems.
========================================
6. New Functions
========================================
- GMP
. Added gmp_random_seed().
- PCRE:
. Added preg_replace_callback_array function
(RFC: https://wiki.php.net/rfc/preg_replace_callback_array)
- Standard
. Added intdiv() function for integer division.
. Added error_clear_last() function to reset error state.
- Zip:
. Added ZipArchive::setCompressionIndex() and ZipArchive::setCompressionName()
for setting the compression method.
- Zlib:
. Added deflate_init(), deflate_add(), inflate_init(), inflate_add()
functions allowing incremental/streaming compression/decompression.
========================================
7. New Classes and Interfaces
========================================
- ReflectionGenerator
- ReflectionType
========================================
8. Removed Extensions and SAPIs
========================================
- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/nsapi
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/mysql
- ext/sybase_ct
- ext/ereg
For more details see
https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts
https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7
NOTE: NSAPI was not voted in the RFC, however it was removed afterwards. It turned
out, that the corresponding SDK isn't available anymore.
========================================
9. Other Changes to Extensions
========================================
- Mhash
Mhash is not an extension anymore, use function_exists("mhash") to check whether
it is avaliable.
- PDO_Firebird
As of PHP 7.0.16, the fetched data for integer fields is aware of the Firebird
datatypes. Previously all integers was fetched as strings, starting with the
aforementioned PHP version integer fields are translated to the PHP integer
datatype. The 64-bit integers are still fetched as strings in 32-bit PHP
builds.
- GD
The bundled libgd requires libwebp instead of libvpx for the WebP functionality.
- Openssl
minimum supported OpenSSL version series was raised to 0.9.8
- Shmop
The shmop identifiers have been changed from ints to resources of type shmop.
========================================
10. New Global Constants
========================================
- Core
. PHP_INT_MIN added.
- PCRE
. This error constant is added to signal errors due to stack size limitations
when PCRE JIT support is enabled:
. PREG_JIT_STACKLIMIT_ERROR
- Zlib
. These constants are added to control flush behavior with the new
incremental deflate_add() and inflate_add() functions:
. ZLIB_NO_FLUSH
. ZLIB_PARTIAL_FLUSH
. ZLIB_SYNC_FLUSH
. ZLIB_FULL_FLUSH
. ZLIB_BLOCK
. ZLIB_FINISH
- GD
. IMG_WEBP (>= 7.0.10)
. T1Lib support removed, thus lifting the optional dependency on T1Lib, the
following is therefore not available anymore:
Functions:
- imagepsbbox()
- imagepsencodefont()
- imagepsextendedfont()
- imagepsfreefont()
- imagepsloadfont()
- imagepsslantfont()
- imagepstext()
Resources:
- 'gd PS font'
- 'gd PS encoding'
- Zip
. Filename encoding flags, as of 7.0.8
- ZipArchive::FL_ENC_GUESS
- ZipArchive::FL_ENC_RAW
- ZipArchive::FL_ENC_STRICT
- ZipArchive::FL_ENC_UTF_8
- ZipArchive::FL_ENC_CP437
========================================
11. Changes to INI File Handling
========================================
- Core
. Removed asp_tags ini directive. Trying to enable it will result in a fatal
error.
. Removed always_populate_raw_post_data ini directive.
. realpath_cache_size set to 4096k by default
========================================
12. Windows Support
========================================
- Core
. Support for native 64 bit integers in 64 bit builds.
. Support for large files in 64 bit builds.
. Support for getrusage()
- ftp
. The ftp extension is always shipped shared
. For SSL support, the dependency on the openssl extension was abolished. Instead
it depends alone on the openssl library. If it's present at the compile time,
ftp_ssl_connect() is enabled automatically.
- imap
. Static building of ext/imap is disabled
- odbc
. The odbc extension is always shipped shared
========================================
13. Other Changes
========================================
- Core
. Instead of being undefined and platform-dependent, NaN and Infinity will
always be zero when cast to integer.
. Calling a method on a non-object now raises a catchable error instead of a
fatal error; see: https://wiki.php.net/rfc/catchable-call-to-member-of-non-object
. Error messages for zend_parse_parameters, type hints and conversions now
always say "integer" and "float" instead of "long" and "double".
. Output buffering now continues to work for an aborted connection if
ignore_user_abort is set to true.
. Zend Extensions API was extended with zend_extension.op_array_persist_calc()
and zend_extensions.op_array_persist() handlers. They allow to store (or
reset) associated with op_array addition information in Opcache Shared
Memory.
. zend_internal_function.reserved[] array was introduced to allow association
of aditional information with internal functions. In PHP-5 it was possible
to use zend_function.op_array.reserved[] even for internal functions, but
now we don't allocate extra space.
- CURL
. curl_getinfo($ch, CURLINFO_CERTINFO) returns certificate Subject and Issuer
as a string (PHP >= 7.0.10)
-324
View File
@@ -1,324 +0,0 @@
PHP 7.0 INTERNALS UPGRADE NOTES
0. Wiki Examples
1. Internal API changes
e. New data types
f. zend_parse_parameters() specs
g. sprintf() formats
h. HashTable API
i. New portable macros for large file support
j. New portable macros for integers
k. get_class_entry object handler info
l. get_class_name object handler info
m. Other portable macros info
n. ZEND_ENGINE_2 removal
o. Updated final class modifier
p. TSRM changes
q. gc_collect_cycles() is now hookable
r. PDO uses size_t for lengths
s. Resource API changes
t. Optimized strings concatenation.
u. Streams changes
v. Sort algorithm changes
2. Build system changes
a. Unix build system changes
b. Windows build system changes
3. Module changes
================
0. Wiki Examples
================
The wiki contains multiple examples and further explanations of the internal
changes. See: https://wiki.php.net/phpng-upgrading
========================
1. Internal API changes
========================
e. New data types
String
Besides the old way of accepting the strings with 's', the new 'S' ZPP spec
was introduced. It expects an argument of the type zend_string *. String lengths
in it are bound to the size_t datatype.
Integer types
Integers do no more depend on the firm 'long' type. Instead a platform
dependent integer type is used, it is called zend_long. That datatype is
defined dynamically to guarantee the consistent 64 bit support. The zval
field representing user land integer it bound to zend_long.
Signed integer is defined as zend_long, unsigned integer as zend_ulong
inside Zend.
Other datatypes
zend_off_t - portable off_t analogue
zend_stat_t - portable 'struct stat' analogue
These datatypes are declared to be portable across platforms. Thus, direct
usage of the functions like fseek, stat, etc. as well as direct usage of
off_t and struct stat is strongly not recommended. Instead the portable
macros should be used.
zend_fseek - portable fseek equivalent
zend_ftell - portable ftell equivalent
zend_lseek - portable lseek equivalent
zend_fstat - portable fstat equivalent
zend_stat - portable stat equivalent
f. zend_parse_parameters() specs
The new spec 'S' introduced, which expects an argument of type zend_string *.
The 'l' spec expects a parameter of the type zend_long, not long anymore.
The 's' spec expects parameters of the type char * and size_t, no int anymore.
g. sprintf() formats
New printf modifier 'p' was implemented to platform independently output zend_long,
zend_ulong and php_size_t datatypes. That modifier can be used with 'd', 'u', 'x' and 'o'
printf format specs with spprintf, snprintf and the wrapping printf implementations.
%pu is sufficient for both zend_ulong and php_size_t. the code using %p spec to output
pointer address might need to be enclosed into #ifdef when it unlickily followed by 'd',
'u', 'x' or 'o'.
The only exceptions are the snprintf and zend_sprintf functions yet, because in some cases
they can use the implemenations available on the system, not the PHP one. With snprintf the
macros ZEND_LONG_FMT and ZEND_ULONG_FMT should be used.
h. HashTable API
Datatype for array indexes was changed to zend_ulong, for string keys to zend_string *.
i. New portable macros for large file support
Function(s) Alias Comment
stat, _stat64 zend_stat for use with zend_stat_t
fstat, _fstat64 zend_fstat for use with zend_stat_t
lseek, _lseeki64 zend_lseek for use with zend_off_t
ftell, _ftelli64 zend_ftell for use with zend_off_t
fseek, _fseeki64 zend_fseek for use with zend_off_t
j. New portable macros for integers
Function(s) Alias Comment
snprintf with "%ld" or "%lld", _ltoa_s, _i64toa_s ZEND_LTOA for use with zend_long
atol, atoll, _atoi64 ZEND_ATOL for use with zend_long
strtol, strtoll, _strtoi64 ZEND_STRTOL for use with zend_long
strtoul, strtoull, _strtoui64 ZEND_STRTOUL for use with zend_long
abs, llabs, _abs64 ZEND_ABS for use with zend_long
- ZEND_LONG_MAX replaces LONG_MAX where appropriate
- ZEND_LONG_MIN replaces LONG_MIN where appropriate
- ZEND_ULONG_MAX replaces ULONG_MAX where appropriate
- SIZEOF_ZEND_LONG reworked SIZEOF_ZEND_LONG representing the size of zend_long datatype
- ZEND_SIZE_MAX Max value of size_t
- Z_L casts an integral constant to zend_long
- Z_UL casts an integral constant to zend_ulong
The macro ZEND_ENABLE_ZVAL_LONG64 reveals whether zval operates on 64 or 32 bit integer.
k. The get_class_entry object handler is no longer available. Instead
zend_object.ce is always used.
l. The get_class_name object handler is now only used for displaying class
names in debugging functions like var_dump(). It is no longer used in
get_class(), get_parent_class() or similar.
The handler is now obligatory, no longer accepts a `parent` argument and
must return a non-NULL zend_string*, which will be released by the caller.
m. Other portable macros info
ZEND_SECURE_ZERO - zeroes chunk of memory
ZEND_VALID_SOCKET - validates a php_socket_t variable
ZEND_FASTCALL is defined to use __vectorcall convention on VS2013 and above
ZEND_NORETURN is defined as __declspec(noreturn) on VS
n. The ZEND_ENGINE_2 macro has been removed. A ZEND_ENGINE_3 macro has been added.
o. Removed ZEND_ACC_FINAL_CLASS in favour of ZEND_ACC_FINAL, turning final class
modifier now a different class entry flag. Update your extensions.
p. TSRM changes
The TSRM layer undergone significant changes. It is not necessary anymore to
pass the tsrm_ls pointer explicitly. The TSRMLS_* macros should not be used
in any new developments.
The recommended way accessing globals in TS builds is by implementing it
to use a local thread unique pointer to the corresponding data pool. These
are the new macros that serve to achieve this goal:
- ZEND_TSRMG - based on TSRMG and if static pointer for data pool access is
implemented, will use it
- ZEND_TSRMLS_CACHE_EXTERN - to be used in a header shared across multiple
C/C++ files
- ZEND_TSRMLS_CACHE_DEFINE - to be used in the main extension C/C++ file
- ZEND_TSRMLS_CACHE_UPDATE - to be integrated at the top of the globals
ctor or RINIT function
- ZEND_ENABLE_STATIC_TSRMLS_CACHE - to be used in the config.[m4|w32] for
enabling the globals access per thread unique pointer
- TSRMLS_CACHE - expands to the variable name which links to the thread
unique data pool
Note that usually it will work without implementing the globals access per
a thread unique pointer, however it might cause a slowdown. The reason is
that the access model to the extension/SAPI own globals as well as the
access to the core globals is determined in the compilation phase depending
on whether ZEND_ENABLE_STATIC_TSRMLS_CACHE macro is defined.
Due to the current compiler evolution state, the TSRMLS_CACHE pointer
(when implemented) has to be present and updated in every binary unit which
is not compiled statically into PHP. So any DLL, DSO, EXE, etc. has to take
care about defining and updating it's TSRMLS cache. An update should happen
before any globals was accessed.
Porting an extension or SAPI is usually as easy as removing all the TSRMLS_*
occurrences and integrating the macros mentioned above. However if tsrm_ls
is used explicitly, its usage can be considered obsolete in most cases.
Additionally, if an extension triggers its own threads, TSRMLS_CACHE shouldn't
be passed to that threads directly.
When working with CTOR/DTOR for the extension globals, only the data passed
as parameters should be touched. For example, don't use code like
free(MYEXT_G(vars)); inside globals destructor, as it possibly can destroy
the data from a wrong thread. Instead use the pointer to the data delivered
into the destructor. So the previous example could look like
free(my_struct->vars); given the income was casted to (struct my_struct *).
A new macro was introduced to simplify the declaration to the extension
globals. A simplified declaration looks as follows
#define MYEXT_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(myext, v)
Another new macro ZEND_MODULE_GLOBALS_BULK(myext) delivers the corresponding
globals struct as a whole.
Two new storage specifiers was introduced.
ZEND_EXT_TLS - expand to an appropriate thread specific storage specifier in
the thread safe build, expands to empty in a non thread safe
build.
ZEND_TLS - expands to an appropriate thread specific storage specifier
with static visibility in the thread safe build, expands to
static specifier in a non thread safe build.
Variables declared with these storage specifiers can not be shared across
threads. While ZEND_TLS enforces the local scope visibility, ZEND_EXT_TLS
pertains to the visiblity across several compilation units. In both cases,
there's no portable way to achieve the visibility across shared objects.
Thus, these specifiers are not compatible with ZEND_API and PHPAPI specifiers.
q. gc_collect_cycles() is now a function pointer, and can be replaced in the
same manner as zend_execute_ex() if needed (for example, to include the
time spent in the garbage collector in a profiler). The default
implementation has been renamed to zend_gc_collect_cycles(), and is
exported with ZEND_API.
r. In accordance with general use of size_t as string length, all PDO API
functions now use size_t for string length.
s. Removed ZEND_REGISTER/FETCH_RESOURCE, use zend_fetch_resource and
and zend_register_resource instead, zend_fetch_resource accepts a zend_resource *
as first argument, if you still need to fetch a resource from zval, use
zend_fetch_resource_ex. More details can be found in Zend/zend_list.c.
t. Optimized strings concatenation.
ZEND_ADD_STRING/VAR/CHAR are replaced with ZEND_ROPE_INIT, ZEND_ROPE_ADD,
ZEND_ROPE_END.
Instead of reallocation and copying string on each ZEND_ADD_STRING/VAR/CAHR,
collect all the strings and then allocate and construct the resulting string once.
u. Streams changes
- It is possible to do blocking reads on Windows pipes. It can be done either
using context stream option PHP_STREAM_OPTION_PIPE_BLOCKING or
adding STREAM_USE_BLOCKING_PIPE when opening the stream.
v. Sort algorithm changes
- Improved zend_qsort(using hybrid sorting algo) for better performance,
and also renamed zend_qsort to zend_sort.
- Added stable sorting algo zend_insert_sort.
w. Tick functions internal API change
Tick functions have different declaration now. They expect a single
parameter while before they were parameterless. When registering the
tick function a value for this parameter must be passed. This value will be
provided to the tick function on every execution.
========================
2. Build system changes
========================
a. Unix build system changes
b. Windows build system changes
- Besides Visual Studio, building with Clang or Intel Composer is now
possible. To enable an alternative toolset, add the option
--with-toolset=[vs,clang,icc] to the configure line. The default
toolset is vs. Still clang or icc need the correct environment
which involves many tools from the vs toolset.
The toolset option is supported by phpize as well.
AWARENESS The only recommended and supported toolset to produce production
ready binaries is Visual Studio. Still other compilers can be used now for
testing and analyzing purposes.
- configure.js now produces response files which are passed to the linker
and library manager. This solves the issues with the long command lines
which can exceed the OS limit.
- with clang toolset, an option --with-uncritical-warn-choke is available,
which suppresses the most frequent false positive warnings
- the --with-mp option will by default utilize all the available cores. It's
enabled by default for release builds and can be disabled with the special
"disable" keyword.
========================
3. Module changes
========================
Session:
- PS_MOD_UPDATE_TIMESTAMP() session save handler definition is added. New
save handler should use PS_MOD_UPDATE_TIMESTAMP() definition. Save handler
must not refer/change PS() variables directly from save handler. Use
parameters.
- PS_MOD()/PS_MOD_SID() macro exist only for transition. Beware these
save handlers are less secure and slower than PS_MOD_UPDATE_TIMESTAMP().
- PS(invalid_session_id) was removed. It was never worked as it supposed.
To report invalid session ID, use PS_VALIDATE_SID() handler.
- PS_VALIDATE_SID() defines session ID validation handler. This handler
must validate if requested session ID exists in session data storage or not.
Do not access PS(id) directly, but use this handler and it's parameter.
- PS_UPDATE_TIMESTAMP() defines timestamp updating handler. This handler
must update session data timestamp for GC if it is needed. e.g. Memcache
updates timestamp on read, so it does not need to update timestamp. Return
SUCCESS simply for this case.
- PS_CREATE_SID() should check session ID collision. Return NULL for failure.
- More documentation can be found in ext/session/mod_files.c as comments.
mod_files.c may be used as reference implementation.
Openssl:
- several ext/openssl functions require the inclusion of the applink shim
as documented in the OpenSSL FAQ https://www.openssl.org/support/faq.html#PROG2
to properly work on Windows. While this primarily affects the OpenSSL
functionality, the shim needs to be included into the executable file
which loads the extension DLL, not into the extension DLL itself. Alternatively
it can be compiled and linked with the main program as a separate object file.
More information and explanation in the linked OpenSSL FAQ.
Thus, this primarily affects any WAMP or other redistributions bundling the
official PHP release zipballs or building from sources. The applink shim is
already integrated with all the PHP executables from the official distribution
starting with 7.0.0beta1.
+41998
View File
File diff suppressed because it is too large. Load diff
+6 -8
View File
@@ -10,17 +10,15 @@ libZend_la_SOURCES=\
zend_ini_parser.y zend_ini_scanner.l \
zend_alloc.c zend_compile.c zend_constants.c \
zend_execute.c zend_execute_API.c zend_highlight.c zend_llist.c \
zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
zend_list.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_sort.c zend_objects.c zend_object_handlers.c \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_qsort.c zend_objects.c zend_object_handlers.c \
zend_objects_API.c zend_ts_hash.c zend_stream.c \
zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \
zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
zend_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c
zend_strtod.c zend_strtod.c zend_strtol.c zend_closures.c zend_float.c
libZend_la_CFLAGS = -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
@@ -33,7 +31,7 @@ zend_ini_scanner.lo: zend_ini_parser.h
# Language parser/scanner rules
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
$(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
zend_language_parser.h: zend_language_parser.c
zend_language_parser.c: $(srcdir)/zend_language_parser.y
@@ -45,7 +43,7 @@ zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o zend_ini_parser.c
zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
$(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
zend_ini_parser.h: zend_ini_parser.c
+1 -10
View File
@@ -9,7 +9,7 @@ allocation overhead and speedup memory management.
The new manager's "configure" has no "--disable-zend-memory-manager" option,
but it has "--enable-malloc-mm" instead. It is enabled by default in DEBUG
build and disabled by default in RELEASE build. When enabled it allows selecting
build and disabled by default in RELEASE build. when enabled it allows selecting
between malloc and emalloc at runtime so you can use internal and external memory
debuggers without recompilation.
@@ -24,15 +24,6 @@ Zend MM disabled:
$ USE_ZEND_ALLOC=0 valgrind --leak-check=full sapi/cli/php -r 'leak();'
Shared extensions:
------------------
Since PHP 5.3.11 it is possible to prevent shared extensions from unloading so
that valgrind can correctly track the memory leaks in shared extensions. For
this there is the ZEND_DONT_UNLOAD_MODULES environment variable. If set, then
DL_UNLOAD() is skipped during the shutdown of shared extensions.
Tweaking:
---------
+1 -1
View File
@@ -6,7 +6,7 @@ fields and using different execution methods (call threading, switch threading
and direct threading). As a result ZE2 got more than 20% speedup on raw PHP
code execution (with specialized executor and direct threading execution
method). As in most PHP applications raw execution speed isn't the limiting
factor but system calls and database calls are, your mileage with this patch
factor but system calls and database callls are, your mileage with this patch
will vary.
Most parts of the old zend_execute.c go into zend_vm_def.h. Here you can
+1 -1
View File
@@ -1,5 +1,5 @@
Title: Zend 2.0 Namespaces
Version: $Id$
Version: $Revision$
Status: declined
Maintainer: Stig S. Bakken <ssb@php.net>
Created: 2001-09-08
+4 -4
View File
@@ -1,5 +1,5 @@
Title: Loose type requirements for functions
Version: $Id$
Version: $Revision$
Status: draft
Maintainer: Brian Moon <brianm@dealnews.com>
Created: 2001-09-17
@@ -9,11 +9,11 @@ Modified: 2001-09-17
1. Background/Need
==================
Many internal functions of PHP will reject parameters because of their
Many internal function of PHP will reject parameters because of their
type (the array and variable function come to mind). For userland
this is not an easy task as there is no uniform way to do it. An
addition to the engine for requiring loose types would allow
developers to know that the data passed to their functions are of the
delevopers to know that the data passed to their functions is of the
correct type and reduce the need for duplicating the same code in
every function to check for the type of data.
@@ -57,7 +57,7 @@ function foo (array $var){
===========
Mis-matches in type should be reported as fatal errors and should halt
the execution of a script as that function cannot be run and code
the execution of a script as that function can not be run and code
following could not reliably run.
+4 -4
View File
@@ -435,7 +435,7 @@ Changes in the Zend Engine 2.0
that of other object-oriented languages, such as Java: When the
last reference to an object is destroyed the object's
destructor, which is a class method name __destruct() that
receives no parameters, is called before the object is freed
recieves no parameters, is called before the object is freed
from memory.
Example:
@@ -1103,7 +1103,7 @@ Changes in the Zend Engine 1.0
Use ob_start() to begin output buffering, ob_end_flush() to end
buffering and send out the buffered contents, ob_end_clean() to
end buffering without sending the buffered contents, and
ob_get_contents() to retrieve the current contents of the output
ob_get_contents() to retreive the current contents of the output
buffer. Header information (header(), content type, cookies) are
not buffered. By turning on output buffering, you can
effectively send header information all throughout your file,
@@ -1136,7 +1136,7 @@ Changes in the Zend Engine 1.0
(supports breakpoints, expression evaluation, step-in/over,
function call backtrace, and more).
The Zend Engine claims 100% compatibility with the engine of PHP
The Zend Engine claims 100% compatability with the engine of PHP
3.0, and is shamelessly lying about it. Here's why:
* Static variable initializers only accept scalar values
@@ -1161,6 +1161,6 @@ Changes in the Zend Engine 1.0
printed the letter { and the contents of the variable $somevar in
PHP 3.0), it will result in a parse error with the Zend Engine.
In this case, you would have to change the code to print
"\{$somevar"; This incompatibility is due to the full variable
"\{$somevar"; This incompatability is due to the full variable
reference within quoted strings feature added in the Zend
Engine.
+602
View File
@@ -0,0 +1,602 @@
# Microsoft Developer Studio Project File - Name="Zend" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Zend - Win32 Release_inline
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Zend.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Zend.mak" CFG="Zend - Win32 Release_inline"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Zend - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Zend - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "Zend - Win32 Release_inline" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Zend - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D ZEND_DEBUG=0 /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D "ZEND_WIN32" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug"
# ADD RSC /l 0x40d /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug" /D "_LIB" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D ZEND_DEBUG=1 /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_Debug"
# ADD RSC /l 0x40d /d "_Debug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Zend___Win32_Release_inline"
# PROP BASE Intermediate_Dir "Zend___Win32_Release_inline"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_inline"
# PROP Intermediate_Dir "Release_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D ZEND_DEBUG=0 /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D "WIN32" /D "_MBCS" /D "ZEND_WIN32" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug"
# ADD RSC /l 0x40d /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Zend - Win32 Release"
# Name "Zend - Win32 Debug"
# Name "Zend - Win32 Release_inline"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\zend.c
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.c
# End Source File
# Begin Source File
SOURCE=.\zend_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.c
# End Source File
# Begin Source File
SOURCE=.\zend_closures.c
# End Source File
# Begin Source File
SOURCE=.\zend_compile.c
# End Source File
# Begin Source File
SOURCE=.\zend_constants.c
# End Source File
# Begin Source File
SOURCE=.\zend_default_classes.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.c
# End Source File
# Begin Source File
SOURCE=.\zend_float.c
# End Source File
# Begin Source File
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.c
# End Source File
# Begin Source File
SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini_parser.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.c
# End Source File
# Begin Source File
SOURCE=.\zend_interfaces.c
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.c"
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.c"
# End Source File
# Begin Source File
SOURCE=.\zend_list.c
# End Source File
# Begin Source File
SOURCE=.\zend_llist.c
# End Source File
# Begin Source File
SOURCE=.\zend_object_handlers.c
# End Source File
# Begin Source File
SOURCE=.\zend_objects.c
# End Source File
# Begin Source File
SOURCE=.\zend_objects_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_opcode.c
# End Source File
# Begin Source File
SOURCE=.\zend_operators.c
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_qsort.c
# End Source File
# Begin Source File
SOURCE=.\zend_reflection_api.c
# End Source File
# Begin Source File
SOURCE=.\zend_sprintf.c
# End Source File
# Begin Source File
SOURCE=.\zend_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_stream.c
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.c
# End Source File
# Begin Source File
SOURCE=.\zend_ts_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_variables.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\FlexLexer.h
# End Source File
# Begin Source File
SOURCE=.\zend.h
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.h
# End Source File
# Begin Source File
SOURCE=.\zend_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.h
# End Source File
# Begin Source File
SOURCE=.\zend_compile.h
# End Source File
# Begin Source File
SOURCE=.\zend_config.w32.h
# End Source File
# Begin Source File
SOURCE=.\zend_constants.h
# End Source File
# Begin Source File
SOURCE=.\zend_default_classes.h
# End Source File
# Begin Source File
SOURCE=.\zend_errors.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute_locks.h
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.h
# End Source File
# Begin Source File
SOURCE=.\zend_fast_cache.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals_macros.h
# End Source File
# Begin Source File
SOURCE=.\zend_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.h
# End Source File
# Begin Source File
SOURCE=.\zend_indent.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini_parser.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.h
# End Source File
# Begin Source File
SOURCE=.\zend_interfaces.h
# End Source File
# Begin Source File
SOURCE=.\zend_istdiostream.h
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.h"
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.h"
# End Source File
# Begin Source File
SOURCE=.\zend_list.h
# End Source File
# Begin Source File
SOURCE=.\zend_llist.h
# End Source File
# Begin Source File
SOURCE=.\zend_modules.h
# End Source File
# Begin Source File
SOURCE=.\zend_object_handlers.h
# End Source File
# Begin Source File
SOURCE=.\zend_objects.h
# End Source File
# Begin Source File
SOURCE=.\zend_objects_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_operators.h
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_qsort.h
# End Source File
# Begin Source File
SOURCE=.\zend_reflection_api.h
# End Source File
# Begin Source File
SOURCE=.\zend_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_stream.h
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.h
# End Source File
# Begin Source File
SOURCE=.\zend_ts_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_variables.h
# End Source File
# End Group
# Begin Group "Parsers"
# PROP Default_Filter "y"
# Begin Source File
SOURCE=.\zend_ini_parser.y
!IF "$(CFG)" == "Zend - Win32 Release"
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputDir=.
InputPath=.\zend_ini_parser.y
BuildCmds= \
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
!ENDIF
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.y"
!IF "$(CFG)" == "Zend - Win32 Release"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Scanners"
# PROP Default_Filter "l"
# Begin Source File
SOURCE=.\flex.skl
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.l
!IF "$(CFG)" == "Zend - Win32 Release"
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputPath=.\zend_ini_scanner.l
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
!ENDIF
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.l"
!IF "$(CFG)" == "Zend - Win32 Release"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Text Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\ZEND_BUGS
# End Source File
# Begin Source File
SOURCE=.\ZEND_CHANGES
# End Source File
# Begin Source File
SOURCE=.\ZEND_TODO
# End Source File
# End Group
# Begin Group "Resources"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\zend.ico
# End Source File
# End Group
# End Target
# End Project
+39 -88
View File
@@ -100,7 +100,7 @@ AC_FUNC_ALLOCA
AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite fpclass sigsetjmp)
AC_ZEND_BROKEN_SPRINTF
AC_CHECK_DECLS([isfinite, isnan, isinf], [], [], [[#include <math.h>]])
AC_CHECK_FUNCS(finite isfinite isinf isnan)
ZEND_FP_EXCEPT
@@ -153,6 +153,14 @@ AC_ARG_ENABLE(debug,
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
AC_ARG_WITH(zend-vm,
[ --with-zend-vm=TYPE Set virtual machine dispatch method. Type is
one of "CALL", "SWITCH" or "GOTO" [TYPE=CALL]],[
PHP_ZEND_VM=$withval
],[
PHP_ZEND_VM=CALL
])
AC_ARG_ENABLE(maintainer-zts,
[ --enable-maintainer-zts Enable thread safety - for code maintainers only!!],[
ZEND_MAINTAINER_ZTS=$enableval
@@ -168,6 +176,9 @@ AC_ARG_ENABLE(inline-optimization,
ZEND_INLINE_OPTIMIZATION=yes
])
AC_MSG_CHECKING([virtual machine dispatch method])
AC_MSG_RESULT($PHP_ZEND_VM)
AC_MSG_CHECKING(whether to enable thread-safety)
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
@@ -177,15 +188,39 @@ AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
AC_MSG_CHECKING(whether to enable Zend debugging)
AC_MSG_RESULT($ZEND_DEBUG)
case $PHP_ZEND_VM in
SWITCH)
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_SWITCH,[virtual machine dispatch method])
;;
GOTO)
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_GOTO,[virtual machine dispatch method])
;;
*)
PHP_ZEND_VM=CALL
AC_DEFINE(ZEND_VM_KIND,ZEND_VM_KIND_CALL,[virtual machine dispatch method])
;;
esac
if test "$ZEND_DEBUG" = "yes"; then
AC_DEFINE(ZEND_DEBUG,1,[ ])
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
if test "$CFLAGS" = "-g -O2"; then
CFLAGS=-g
fi
test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
changequote({,})
if test -n "$GCC"; then
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
"$CC" --help=warnings|grep -q -- '-Wpointer-arith[ \t]' && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wpointer-arith"
"$CC" --help=warnings|grep -q -- '-Wdeclaration-after-statement[ \t]' && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wdeclaration-after-statement"
test "$USE_MAINTAINER_MODE" = "yes" && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
fi
changequote([,])
else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
@@ -368,28 +403,8 @@ int main()
AC_CHECK_FUNCS(mremap)
AC_ARG_ENABLE(zend-signals,
[ --enable-zend-signals Use zend signal handling],[
ZEND_SIGNALS=$enableval
],[
ZEND_SIGNALS=no
])
AC_CHECK_FUNC(sigaction, [
AC_DEFINE(HAVE_SIGACTION, 1, [Whether sigaction() is available])
], [
ZEND_SIGNALS=no
])
if test "$ZEND_SIGNALS" = "yes"; then
AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
CFLAGS="$CFLAGS -DZEND_SIGNALS"
fi
AC_MSG_CHECKING(whether to enable zend signal handling)
AC_MSG_RESULT($ZEND_SIGNALS)
])
AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[
@@ -401,68 +416,4 @@ if test -r "/dev/urandom" && test -c "/dev/urandom"; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING(whether /dev/arandom exists)
if test -r "/dev/arandom" && test -c "/dev/arandom"; then
AC_DEFINE([HAVE_DEV_ARANDOM], 1, [Define if the target system has /dev/arandom device])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_ARG_ENABLE(gcc-global-regs,
[ --disable-gcc-global-regs
whether to enable GCC global register variables],[
ZEND_GCC_GLOBAL_REGS=$enableval
],[
ZEND_GCC_GLOBAL_REGS=yes
])
AC_MSG_CHECKING(for global register variables support)
if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
AC_TRY_COMPILE([
#if defined(__GNUC__)
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
# define ZEND_VM_FP_GLOBAL_REG "%esi"
# define ZEND_VM_IP_GLOBAL_REG "%edi"
#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
# define ZEND_VM_FP_GLOBAL_REG "%r14"
# define ZEND_VM_IP_GLOBAL_REG "%r15"
#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)
# define ZEND_VM_FP_GLOBAL_REG "r28"
# define ZEND_VM_IP_GLOBAL_REG "r29"
#elif defined(__IBMC__) && ZEND_GCC_VERSION >= 4002 && defined(__powerpc64__)
# define ZEND_VM_FP_GLOBAL_REG "r28"
# define ZEND_VM_IP_GLOBAL_REG "r29"
#else
# error "global register variables are not supported"
#endif
typedef int (*opcode_handler_t)(void);
register void *FP __asm__(ZEND_VM_FP_GLOBAL_REG);
register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG);
int emu(const opcode_handler_t *ip, void *fp) {
const opcode_handler_t *orig_ip = IP;
void *orig_fp = FP;
IP = ip;
FP = fp;
while ((*ip)());
FP = orig_fp;
IP = orig_ip;
}
], [
], [
ZEND_GCC_GLOBAL_REGS=yes
], [
ZEND_GCC_GLOBAL_REGS=no
])
fi
if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
else
HAVE_GCC_GLOBAL_REGS=no
fi
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
+735
View File
@@ -0,0 +1,735 @@
# Microsoft Developer Studio Project File - Name="ZendTS" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=ZendTS - Win32 Release_TSDbg
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ZendTS.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ZendTS.mak" CFG="ZendTS - Win32 Release_TSDbg"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ZendTS - Win32 Release_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "ZendTS - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "ZendTS - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
!MESSAGE "ZendTS - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Release_TS"
# PROP BASE Intermediate_Dir "Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug_TS" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Debug_TS"
# PROP BASE Intermediate_Dir "Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug_TS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug_TS" /D ZEND_DEBUG=1 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_Debug_TS"
# ADD RSC /l 0x40d /d "_Debug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "ZendTS___Win32_Release_TS_inline"
# PROP BASE Intermediate_Dir "ZendTS___Win32_Release_TS_inline"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_TS_inline"
# PROP Intermediate_Dir "Release_TS_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /FR /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "ZendTS___Win32_Release_TSDbg"
# PROP BASE Intermediate_Dir "ZendTS___Win32_Release_TSDbg"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_TSDbg"
# PROP Intermediate_Dir "Release_TSDbg"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "ZendTS - Win32 Release_TS"
# Name "ZendTS - Win32 Debug_TS"
# Name "ZendTS - Win32 Release_TS_inline"
# Name "ZendTS - Win32 Release_TSDbg"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\zend.c
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.c
# End Source File
# Begin Source File
SOURCE=.\zend_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.c
# End Source File
# Begin Source File
SOURCE=.\zend_closures.c
# End Source File
# Begin Source File
SOURCE=.\zend_compile.c
# End Source File
# Begin Source File
SOURCE=.\zend_constants.c
# End Source File
# Begin Source File
SOURCE=.\zend_default_classes.c
# End Source File
# Begin Source File
SOURCE=.\zend_exceptions.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.c
# End Source File
# Begin Source File
SOURCE=.\zend_float.c
# End Source File
# Begin Source File
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.c
# End Source File
# Begin Source File
SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini_parser.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.c
# End Source File
# Begin Source File
SOURCE=.\zend_interfaces.c
# End Source File
# Begin Source File
SOURCE=.\zend_iterators.c
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.c"
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.c"
# End Source File
# Begin Source File
SOURCE=.\zend_list.c
# End Source File
# Begin Source File
SOURCE=.\zend_llist.c
# End Source File
# Begin Source File
SOURCE=.\zend_object_handlers.c
# End Source File
# Begin Source File
SOURCE=.\zend_objects.c
# End Source File
# Begin Source File
SOURCE=.\zend_objects_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_opcode.c
# End Source File
# Begin Source File
SOURCE=.\zend_operators.c
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_qsort.c
# End Source File
# Begin Source File
SOURCE=.\zend_reflection_api.c
# End Source File
# Begin Source File
SOURCE=.\zend_sprintf.c
# End Source File
# Begin Source File
SOURCE=.\zend_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_stream.c
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.c
# End Source File
# Begin Source File
SOURCE=.\zend_ts_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_variables.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\FlexLexer.h
# End Source File
# Begin Source File
SOURCE=.\zend.h
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.h
# End Source File
# Begin Source File
SOURCE=.\zend_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.h
# End Source File
# Begin Source File
SOURCE=.\zend_compile.h
# End Source File
# Begin Source File
SOURCE=.\zend_config.w32.h
# End Source File
# Begin Source File
SOURCE=.\zend_constants.h
# End Source File
# Begin Source File
SOURCE=.\zend_default_classes.h
# End Source File
# Begin Source File
SOURCE=.\zend_errors.h
# End Source File
# Begin Source File
SOURCE=.\zend_exceptions.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute.h
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.h
# End Source File
# Begin Source File
SOURCE=.\zend_fast_cache.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals_macros.h
# End Source File
# Begin Source File
SOURCE=.\zend_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.h
# End Source File
# Begin Source File
SOURCE=.\zend_indent.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini_parser.h
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.h
# End Source File
# Begin Source File
SOURCE=.\zend_interfaces.h
# End Source File
# Begin Source File
SOURCE=.\zend_istdiostream.h
# End Source File
# Begin Source File
SOURCE=.\zend_iterators.h
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.h"
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.h"
# End Source File
# Begin Source File
SOURCE=.\zend_list.h
# End Source File
# Begin Source File
SOURCE=.\zend_llist.h
# End Source File
# Begin Source File
SOURCE=.\zend_modules.h
# End Source File
# Begin Source File
SOURCE=.\zend_object_handlers.h
# End Source File
# Begin Source File
SOURCE=.\zend_objects.h
# End Source File
# Begin Source File
SOURCE=.\zend_objects_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_operators.h
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_qsort.h
# End Source File
# Begin Source File
SOURCE=.\zend_reflection_api.h
# End Source File
# Begin Source File
SOURCE=.\zend_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_stream.h
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.h
# End Source File
# Begin Source File
SOURCE=.\zend_ts_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_variables.h
# End Source File
# End Group
# Begin Group "Parsers"
# PROP Default_Filter "y"
# Begin Source File
SOURCE=.\zend_ini_parser.y
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputDir=.
InputPath=.\zend_ini_parser.y
BuildCmds= \
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputDir=.
InputPath=.\zend_ini_parser.y
BuildCmds= \
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputDir=.
InputPath=.\zend_ini_parser.y
BuildCmds= \
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
# Begin Custom Build
InputDir=.
InputPath=.\zend_ini_parser.y
BuildCmds= \
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=".\zend_language_parser.y"
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
# Begin Custom Build
InputDir=.
InputPath=".\zend_language_parser.y"
BuildCmds= \
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Scanners"
# PROP Default_Filter "l"
# Begin Source File
SOURCE=.\flex.skl
# End Source File
# Begin Source File
SOURCE=.\zend_ini_scanner.l
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputPath=.\zend_ini_scanner.l
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputPath=.\zend_ini_scanner.l
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputPath=.\zend_ini_scanner.l
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
# Begin Custom Build
InputPath=.\zend_ini_scanner.l
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=".\zend_language_scanner.l"
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
# Begin Custom Build
InputPath=".\zend_language_scanner.l"
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Text Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\LICENSE
# End Source File
# Begin Source File
SOURCE=.\ZEND_BUGS
# End Source File
# Begin Source File
SOURCE=.\ZEND_CHANGES
# End Source File
# End Group
# Begin Group "Resources"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\zend.ico
# End Source File
# End Group
# End Target
# End Project
+127
View File
@@ -0,0 +1,127 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#if defined(__GNUC__) && __GNUC__ >= 4
# define ZEND_API __attribute__ ((visibility("default")))
# define ZEND_DLEXPORT __attribute__ ((visibility("default")))
#else
# define ZEND_API
# define ZEND_DLEXPORT
#endif
#define ZEND_DLIMPORT
@TOP@
#undef uint
#undef ulong
/* Define if you want to enable memory limit support */
#define MEMORY_LIMIT 0
@BOTTOM@
#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#if ZEND_BROKEN_SPRINTF
int zend_sprintf(char *buffer, const char *format, ...);
#else
# define zend_sprintf sprintf
#endif
#include <math.h>
/* To enable the is_nan, is_infinite and is_finite PHP functions */
#ifdef NETWARE
#define HAVE_ISNAN 1
#define HAVE_ISINF 1
#define HAVE_ISFINITE 1
#endif
#ifndef zend_isnan
#ifdef HAVE_ISNAN
#define zend_isnan(a) isnan(a)
#elif defined(HAVE_FPCLASS)
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
#else
#define zend_isnan(a) 0
#endif
#endif
#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
#ifdef HAVE_FINITE
#define zend_finite(a) finite(a)
#elif defined(HAVE_ISFINITE) || defined(isfinite)
#define zend_finite(a) isfinite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
#endif
#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */
#ifdef NETWARE
#ifdef USE_WINSOCK
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
#endif
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+10 -19
View File
@@ -3,13 +3,8 @@ dnl
dnl This file contains local autoconf functions.
AC_DEFUN([LIBZEND_BISON_CHECK],[
# we only support certain bison versions;
# min: 2.4 (i.e. 204, major * 100 + minor for easier comparison)
bison_version_min="204"
# non-working versions, e.g. "3.0 3.2";
# remove "none" when introducing the first incompatible bison version an
# separate any following additions by spaces
bison_version_exclude=""
# we only support certain bison versions
bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1"
# for standalone build of Zend Engine
test -z "$SED" && SED=sed
@@ -17,27 +12,23 @@ AC_DEFUN([LIBZEND_BISON_CHECK],[
bison_version=none
if test "$YACC"; then
AC_CACHE_CHECK([for bison version], php_cv_bison_version, [
bison_version_vars=`$YACC --version 2> /dev/null | grep 'GNU Bison' | cut -d ' ' -f 4 | $SED -e 's/\./ /g' | tr -d a-z`
bison_version_vars=`bison --version 2> /dev/null | grep 'GNU Bison' | cut -d ' ' -f 4 | $SED -e 's/\./ /' | tr -d a-z`
php_cv_bison_version=invalid
if test -n "$bison_version_vars"; then
set $bison_version_vars
bison_version="${1}.${2}"
bison_version_num="`expr ${1} \* 100 + ${2}`"
if test $bison_version_num -ge $bison_version_min; then
php_cv_bison_version="$bison_version (ok)"
for bison_check_version in $bison_version_exclude; do
if test "$bison_version" = "$bison_check_version"; then
php_cv_bison_version=invalid
break
fi
done
fi
for bison_check_version in $bison_version_list; do
if test "$bison_version" = "$bison_check_version"; then
php_cv_bison_version="$bison_check_version (ok)"
break
fi
done
fi
])
fi
case $php_cv_bison_version in
""|invalid[)]
bison_msg="This bison version is not supported for regeneration of the Zend/PHP parsers (found: $bison_version, min: $bison_version_min, excluded: $bison_version_exclude)."
bison_msg="bison versions supported for regeneration of the Zend/PHP parsers: $bison_version_list (found: $bison_version)."
AC_MSG_WARN([$bison_msg])
YACC="exit 0;"
;;
+1 -3
View File
@@ -1,8 +1,6 @@
<?php
if (function_exists("date_default_timezone_set")) {
date_default_timezone_set("UTC");
}
date_default_timezone_set('UTC');
function simple() {
$a = 0;
for ($i = 0; $i < 1000000; $i++)
+1 -1
View File
@@ -33,7 +33,7 @@ $(makefile_in_files): $(makefile_am_files)
aclocal.m4: configure.in acinclude.m4
aclocal
$(config_h_in): configure.in
$(config_h_in): configure.in acconfig.h
# explicitly remove target since autoheader does not seem to work
# correctly otherwise (timestamps are not updated)
@rm -f $@
-99
View File
@@ -11,105 +11,6 @@ AM_PROG_CC_STDC
ZEND_VERSION=$VERSION
AC_ZEND_C_BIGENDIAN
AH_TOP([
#if defined(__GNUC__) && __GNUC__ >= 4
# define ZEND_API __attribute__ ((visibility("default")))
# define ZEND_DLEXPORT __attribute__ ((visibility("default")))
#else
# define ZEND_API
# define ZEND_DLEXPORT
#endif
#define ZEND_DLIMPORT
#undef uint
#undef ulong
/* Define if you want to enable memory limit support */
#define MEMORY_LIMIT 0
])
AH_BOTTOM([
#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#if ZEND_BROKEN_SPRINTF
int zend_sprintf(char *buffer, const char *format, ...);
#else
# define zend_sprintf sprintf
#endif
#include <math.h>
/* To enable the is_nan, is_infinite and is_finite PHP functions */
#ifdef NETWARE
#define HAVE_DECL_ISNAN 1
#define HAVE_DECL_ISINF 1
#define HAVE_DECL_ISFINITE 1
#endif
#ifndef zend_isnan
#if HAVE_DECL_ISNAN
#define zend_isnan(a) isnan(a)
#elif defined(HAVE_FPCLASS)
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
#else
#define zend_isnan(a) ((a) != (a))
#endif
#endif
#if HAVE_DECL_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 || (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
#if HAVE_DECL_ISFINITE
#define zend_finite(a) isfinite(a)
#elif defined(HAVE_FINITE)
#define zend_finite(a) finite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
#endif
#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */
#ifdef NETWARE
#ifdef USE_WINSOCK
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
#endif
#endif
])
dnl We want this one before the checks, so the checks can modify CFLAGS.
test -z "$CFLAGS" && auto_cflags=1
-358
View File
@@ -1,358 +0,0 @@
<?php
function hallo() {
}
function simpleucall($n) {
for ($i = 0; $i < $n; $i++)
hallo();
}
function simpleudcall($n) {
for ($i = 0; $i < $n; $i++)
hallo2();
}
function hallo2() {
}
function simpleicall($n) {
for ($i = 0; $i < $n; $i++)
func_num_args();
}
class Foo {
static $a = 0;
public $b = 0;
const TEST = 0;
static function read_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = self::$a;
}
}
static function write_static($n) {
for ($i = 0; $i < $n; ++$i) {
self::$a = 0;
}
}
static function isset_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = isset(self::$a);
}
}
static function empty_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = empty(self::$a);
}
}
static function f() {
}
static function call_static($n) {
for ($i = 0; $i < $n; ++$i) {
self::f();
}
}
function read_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$x = $this->b;
}
}
function write_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$this->b = 0;
}
}
function assign_add_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$this->b += 2;
}
}
function pre_inc_prop($n) {
for ($i = 0; $i < $n; ++$i) {
++$this->b;
}
}
function pre_dec_prop($n) {
for ($i = 0; $i < $n; ++$i) {
--$this->b;
}
}
function post_inc_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$this->b++;
}
}
function post_dec_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$this->b--;
}
}
function isset_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$x = isset($this->b);
}
}
function empty_prop($n) {
for ($i = 0; $i < $n; ++$i) {
$x = empty($this->b);
}
}
function g() {
}
function call($n) {
for ($i = 0; $i < $n; ++$i) {
$this->g();
}
}
function read_const($n) {
for ($i = 0; $i < $n; ++$i) {
$x = $this::TEST;
}
}
}
function read_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = Foo::$a;
}
}
function write_static($n) {
for ($i = 0; $i < $n; ++$i) {
Foo::$a = 0;
}
}
function isset_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = isset(Foo::$a);
}
}
function empty_static($n) {
for ($i = 0; $i < $n; ++$i) {
$x = empty(Foo::$a);
}
}
function call_static($n) {
for ($i = 0; $i < $n; ++$i) {
Foo::f();
}
}
function create_object($n) {
for ($i = 0; $i < $n; ++$i) {
$x = new Foo();
}
}
define('TEST', null);
function read_const($n) {
for ($i = 0; $i < $n; ++$i) {
$x = TEST;
}
}
function read_auto_global($n) {
for ($i = 0; $i < $n; ++$i) {
$x = $_GET;
}
}
$g_var = 0;
function read_global_var($n) {
for ($i = 0; $i < $n; ++$i) {
$x = $GLOBALS['g_var'];
}
}
function read_hash($n) {
$hash = array('test' => 0);
for ($i = 0; $i < $n; ++$i) {
$x = $hash['test'];
}
}
function read_str_offset($n) {
$str = "test";
for ($i = 0; $i < $n; ++$i) {
$x = $str[1];
}
}
function issetor($n) {
$val = array(0,1,2,3,4,5,6,7,8,9);
for ($i = 0; $i < $n; ++$i) {
$x = $val ?: null;
}
}
function issetor2($n) {
$f = false; $j = 0;
for ($i = 0; $i < $n; ++$i) {
$x = $f ?: $j + 1;
}
}
function ternary($n) {
$val = array(0,1,2,3,4,5,6,7,8,9);
$f = false;
for ($i = 0; $i < $n; ++$i) {
$x = $f ? null : $val;
}
}
function ternary2($n) {
$f = false; $j = 0;
for ($i = 0; $i < $n; ++$i) {
$x = $f ? $f : $j + 1;
}
}
/*****/
function empty_loop($n) {
for ($i = 0; $i < $n; ++$i) {
}
}
function getmicrotime()
{
$t = gettimeofday();
return ($t['sec'] + $t['usec'] / 1000000);
}
function start_test()
{
ob_start();
return getmicrotime();
}
function end_test($start, $name, $overhead = null)
{
global $total;
global $last_time;
$end = getmicrotime();
ob_end_clean();
$last_time = $end-$start;
$total += $last_time;
$num = number_format($last_time,3);
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
if (is_null($overhead)) {
echo $name.$pad.$num."\n";
} else {
$num2 = number_format($last_time - $overhead,3);
echo $name.$pad.$num." ".$num2."\n";
}
ob_start();
return getmicrotime();
}
function total()
{
global $total;
$pad = str_repeat("-", 24);
echo $pad."\n";
$num = number_format($total,3);
$pad = str_repeat(" ", 24-strlen("Total")-strlen($num));
echo "Total".$pad.$num."\n";
}
const N = 5000000;
$t0 = $t = start_test();
empty_loop(N);
$t = end_test($t, 'empty_loop');
$overhead = $last_time;
simpleucall(N);
$t = end_test($t, 'func()', $overhead);
simpleudcall(N);
$t = end_test($t, 'undef_func()', $overhead);
simpleicall(N);
$t = end_test($t, 'int_func()', $overhead);
Foo::read_static(N);
$t = end_test($t, '$x = self::$x', $overhead);
Foo::write_static(N);
$t = end_test($t, 'self::$x = 0', $overhead);
Foo::isset_static(N);
$t = end_test($t, 'isset(self::$x)', $overhead);
Foo::empty_static(N);
$t = end_test($t, 'empty(self::$x)', $overhead);
read_static(N);
$t = end_test($t, '$x = Foo::$x', $overhead);
write_static(N);
$t = end_test($t, 'Foo::$x = 0', $overhead);
isset_static(N);
$t = end_test($t, 'isset(Foo::$x)', $overhead);
empty_static(N);
$t = end_test($t, 'empty(Foo::$x)', $overhead);
Foo::call_static(N);
$t = end_test($t, 'self::f()', $overhead);
call_static(N);
$t = end_test($t, 'Foo::f()', $overhead);
$x = new Foo();
$x->read_prop(N);
$t = end_test($t, '$x = $this->x', $overhead);
$x->write_prop(N);
$t = end_test($t, '$this->x = 0', $overhead);
$x->assign_add_prop(N);
$t = end_test($t, '$this->x += 2', $overhead);
$x->pre_inc_prop(N);
$t = end_test($t, '++$this->x', $overhead);
$x->pre_dec_prop(N);
$t = end_test($t, '--$this->x', $overhead);
$x->post_inc_prop(N);
$t = end_test($t, '$this->x++', $overhead);
$x->post_dec_prop(N);
$t = end_test($t, '$this->x--', $overhead);
$x->isset_prop(N);
$t = end_test($t, 'isset($this->x)', $overhead);
$x->empty_prop(N);
$t = end_test($t, 'empty($this->x)', $overhead);
$x->call(N);
$t = end_test($t, '$this->f()', $overhead);
$x->read_const(N);
$t = end_test($t, '$x = Foo::TEST', $overhead);
create_object(N);
$t = end_test($t, 'new Foo()', $overhead);
read_const(N);
$t = end_test($t, '$x = TEST', $overhead);
read_auto_global(N);
$t = end_test($t, '$x = $_GET', $overhead);
read_global_var(N);
$t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead);
read_hash(N);
$t = end_test($t, '$x = $hash[\'v\']', $overhead);
read_str_offset(N);
$t = end_test($t, '$x = $str[0]', $overhead);
issetor(N);
$t = end_test($t, '$x = $a ?: null', $overhead);
issetor2(N);
$t = end_test($t, '$x = $f ?: tmp', $overhead);
ternary(N);
$t = end_test($t, '$x = $f ? $f : $a', $overhead);
ternary2(N);
$t = end_test($t, '$x = $f ? $f : tmp', $overhead);
total($t0, "Total");
+2 -2
View File
@@ -35,7 +35,7 @@ var_dump(func_num_args());
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
int(0)
int(1)
@@ -44,7 +44,7 @@ int(0)
int(2)
int(0)
Warning: Missing argument 2 for test3()%s
Warning: Missing argument 2 for test3() in %s on line %d
int(1)
int(2)
int(1)
+2 -2
View File
@@ -42,7 +42,7 @@ var_dump(func_get_arg(1));
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: func_get_arg(): The argument number should be >= 0 in %s on line %d
bool(false)
@@ -85,7 +85,7 @@ bool(false)
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
bool(false)
Warning: Missing argument 2 for test3()%s
Warning: Missing argument 2 for test3() in %s on line %d
int(1)
Warning: func_get_arg(): Argument 1 not passed to function in %s on line %d
+2 -2
View File
@@ -36,7 +36,7 @@ var_dump(func_get_args());
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
array(0) {
}
array(1) {
@@ -60,7 +60,7 @@ array(2) {
array(0) {
}
Warning: Missing argument 2 for test3()%s
Warning: Missing argument 2 for test3() in %s on line %d
array(1) {
[0]=>
int(1)
+1 -1
View File
@@ -12,7 +12,7 @@ var_dump(strncmp("qwerty", "qwerty123", 7));
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: strncmp() expects exactly 3 parameters, 2 given in %s on line %d
NULL
int(0)
+2 -2
View File
@@ -14,11 +14,11 @@ var_dump(strcasecmp("01", "01"));
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: strcasecmp() expects exactly 2 parameters, 1 given in %s on line %d
NULL
int(0)
int(-3)
int(-1)
int(-1)
int(0)
int(0)
+3 -3
View File
@@ -15,17 +15,17 @@ var_dump(strncasecmp("01", "01", 1000));
echo "Done\n";
?>
--EXPECTF--
--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(-1)
int(0)
int(0)
int(2)
int(1)
int(0)
int(0)
Done
+9 -9
View File
@@ -21,7 +21,7 @@ var_dump(each($a));
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: each() expects exactly 1 parameter, 0 given in %s on line %d
NULL
@@ -33,31 +33,31 @@ NULL
array(4) {
[1]=>
int(1)
["value"]=>
[u"value"]=>
int(1)
[0]=>
int(0)
["key"]=>
[u"key"]=>
int(0)
}
array(4) {
[1]=>
int(1)
["value"]=>
[u"value"]=>
int(1)
[0]=>
string(1) "a"
["key"]=>
string(1) "a"
unicode(1) "a"
[u"key"]=>
unicode(1) "a"
}
array(4) {
[1]=>
int(1)
["value"]=>
[u"value"]=>
int(1)
[0]=>
int(0)
["key"]=>
[u"key"]=>
int(0)
}
Done
+6 -4
View File
@@ -22,7 +22,7 @@ var_dump(constant("test const"));
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: define() expects at least 2 parameters, 0 given in %s on line %d
NULL
@@ -33,7 +33,7 @@ bool(true)
Warning: define() expects parameter 3 to be boolean, array given in %s on line %d
NULL
Warning: define() expects parameter 1 to be string, array given in %s on line %d
Warning: define() expects parameter 1 to be string (Unicode or binary), array given in %s on line %d
NULL
bool(true)
bool(true)
@@ -41,9 +41,11 @@ bool(true)
Notice: Constant test const already defined in %s on line %d
bool(false)
bool(true)
Warning: Constants may only evaluate to scalar values or arrays in %s on line %d
Warning: Constants may only evaluate to scalar values in %s on line %d
bool(false)
Warning: Constants may only evaluate to scalar values in %s on line %d
bool(false)
int(1)
int(2)
+10 -10
View File
@@ -29,20 +29,20 @@ var_dump(get_class($f2));
echo "Done\n";
?>
--EXPECTF--
Deprecated: Non-static method foo::bar() should not be called statically in %s on line %d
string(3) "foo"
--EXPECTF--
Strict Standards: Non-static method foo::bar() should not be called statically in %s on line %d
unicode(3) "foo"
Deprecated: Non-static method foo::bar() should not be called statically in %s on line %d
string(3) "foo"
string(3) "foo"
string(3) "foo"
Strict Standards: Non-static method foo::bar() should not be called statically in %s on line %d
unicode(3) "foo"
unicode(3) "foo"
unicode(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
Warning: get_class() expects parameter 1 to be object, Unicode string given in %s on line %d
bool(false)
string(3) "foo"
string(4) "foo2"
unicode(3) "foo"
unicode(4) "foo2"
Done
+4 -4
View File
@@ -41,13 +41,13 @@ var_dump(get_parent_class(1));
echo "Done\n";
?>
--EXPECTF--
--EXPECT--
bool(false)
bool(false)
string(3) "foo"
string(3) "foo"
unicode(3) "foo"
unicode(3) "foo"
bool(false)
string(3) "foo"
unicode(3) "foo"
bool(false)
bool(false)
bool(false)
+1 -1
View File
@@ -52,7 +52,7 @@ $bar->test();
echo "Done\n";
?>
--EXPECTF--
--EXPECTF--
Warning: property_exists() expects exactly 2 parameters, 0 given in %s on line %d
NULL
Loaded 100 of 14985 files, more files were not shown because too many files have changed in this diff. Show more