dmitry Thu Jul 17 09:52:51 2008 UTC
Added files:
/php-src/ext/curl/tests curl_006.phpt
/php-src/ext/filter/tests callback_closure.phpt
/php-src/ext/mysqli/tests
mysqli_set_local_infile_handler_closures.phpt
/php-src/ext/pcntl/tests signal_closure_handler.phpt
/php-src/ext/session/tests save_handler_closures.inc
session_set_save_handler_closures.phpt
/php-src/ext/sqlite/tests sqlite_closures_001.phpt
sqlite_closures_002.phpt
/php-src/ext/standard/tests/assert assert_closures.phpt
/php-src/ext/standard/tests/general_functions closures_001.phpt
closures_002.phpt
ob_start_closures.phpt
/php-src/ext/xml/tests xml_closures_001.phpt
Modified files:
/php-src/ext/mysqli mysqli_api.c
/php-src/ext/standard basic_functions.c
/php-src/ext/xml xml.c
Log:
support for closures
http://cvs.php.net/viewvc.cgi/php-src/ext/mysqli/mysqli_api.c?r1=1.165&r2=1.166&diff_format=u
Index: php-src/ext/mysqli/mysqli_api.c
diff -u php-src/ext/mysqli/mysqli_api.c:1.165
php-src/ext/mysqli/mysqli_api.c:1.166
--- php-src/ext/mysqli/mysqli_api.c:1.165 Thu Apr 24 14:04:58 2008
+++ php-src/ext/mysqli/mysqli_api.c Thu Jul 17 09:52:51 2008
@@ -17,7 +17,7 @@
| Ulf Wendel <[EMAIL PROTECTED]>
|
+----------------------------------------------------------------------+
- $Id: mysqli_api.c,v 1.165 2008/04/24 14:04:58 andrey Exp $
+ $Id: mysqli_api.c,v 1.166 2008/07/17 09:52:51 dmitry Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -1457,7 +1457,7 @@
{
MY_MYSQL *mysql;
zval *mysql_link;
- zval callback_name, *p_callback_name;
+ zval callback_name;
zval *callback_func;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
"Oz", &mysql_link, mysqli_link_class_entry,
@@ -1467,7 +1467,7 @@
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link",
MYSQLI_STATUS_VALID);
- if (UG(unicode)) {
+ if (UG(unicode) && Z_TYPE_P(callback_func) != IS_ARRAY &&
Z_TYPE_P(callback_func) != IS_OBJECT) {
convert_to_string(callback_func);
}
@@ -1477,6 +1477,7 @@
zval_dtor(&callback_name);
RETURN_FALSE;
}
+ zval_dtor(&callback_name);
/* save callback function */
if (!mysql->li_read) {
@@ -1484,8 +1485,7 @@
} else {
zval_dtor(mysql->li_read);
}
- p_callback_name = &callback_name;
- ZVAL_ZVAL(mysql->li_read, p_callback_name, 0, 0);
+ ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0);
RETURN_TRUE;
}
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.900&r2=1.901&diff_format=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.900
php-src/ext/standard/basic_functions.c:1.901
--- php-src/ext/standard/basic_functions.c:1.900 Sat May 24 14:36:16 2008
+++ php-src/ext/standard/basic_functions.c Thu Jul 17 09:52:51 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.900 2008/05/24 14:36:16 pajoye Exp $ */
+/* $Id: basic_functions.c,v 1.901 2008/07/17 09:52:51 dmitry Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -5390,6 +5390,10 @@
zval result;
zend_compare_arrays(&result, func1, func2 TSRMLS_CC);
ret = (Z_LVAL(result) == 0);
+ } else if (Z_TYPE_P(func1) == IS_OBJECT && Z_TYPE_P(func2) ==
IS_OBJECT) {
+ zval result;
+ zend_compare_objects(&result, func1, func2 TSRMLS_CC);
+ ret = (Z_LVAL(result) == 0);
} else {
ret = 0;
}
@@ -6109,7 +6113,7 @@
RETURN_FALSE;
}
- if (Z_TYPE_P(tick_fe.arguments[0]) != IS_ARRAY) {
+ if (Z_TYPE_P(tick_fe.arguments[0]) != IS_ARRAY &&
Z_TYPE_P(tick_fe.arguments[0]) != IS_OBJECT) {
convert_to_text_ex(&tick_fe.arguments[0]);
}
http://cvs.php.net/viewvc.cgi/php-src/ext/xml/xml.c?r1=1.178&r2=1.179&diff_format=u
Index: php-src/ext/xml/xml.c
diff -u php-src/ext/xml/xml.c:1.178 php-src/ext/xml/xml.c:1.179
--- php-src/ext/xml/xml.c:1.178 Sat Jul 5 20:19:47 2008
+++ php-src/ext/xml/xml.c Thu Jul 17 09:52:51 2008
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: xml.c,v 1.178 2008/07/05 20:19:47 felipe Exp $ */
+/* $Id: xml.c,v 1.179 2008/07/17 09:52:51 dmitry Exp $ */
#define IS_EXT_MODULE
@@ -515,7 +515,7 @@
}
/* IS_ARRAY might indicate that we're using array($obj, 'method')
syntax */
- if (Z_TYPE_PP(data) != IS_ARRAY) {
+ if (Z_TYPE_PP(data) != IS_ARRAY && Z_TYPE_PP(data) != IS_OBJECT) {
convert_to_text_ex(data);
if (((Z_TYPE_PP(data)==IS_UNICODE) && (Z_USTRLEN_PP(data) ==
0)) ||
((Z_TYPE_PP(data)==IS_STRING) && (Z_STRLEN_PP(data) ==
0))) {
http://cvs.php.net/viewvc.cgi/php-src/ext/curl/tests/curl_006.phpt?view=markup&rev=1.1
Index: php-src/ext/curl/tests/curl_006.phpt
+++ php-src/ext/curl/tests/curl_006.phpt
--TEST--
Test curl_opt() function with CURLOPT_WRITEFUNCTION paremter set to a closure
--SKIPIF--
<?php if (!extension_loaded("curl") || false ===
getenv(b'PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?>
--FILE--
<?php
/* Prototype : bool curl_setopt(resource ch, int option, mixed value)
* Description: Set an option for a cURL transfer
* Source code: ext/curl/interface.c
* Alias to functions:
*/
$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
// start testing
echo '*** Testing curl_setopt($ch, CURLOPT_WRITEFUNCTION, <closure>); ***' .
"\n";
$url = "{$host}/get.php?test=get";
$ch = curl_init();
ob_start(); // start output buffering
curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
echo 'Data: '.$data;
return strlen ($data);
});
curl_exec($ch);
curl_close($ch);
?>
===DONE===
--EXPECTF--
*** Testing curl_setopt($ch, CURLOPT_WRITEFUNCTION, <closure>); ***
Data: Hello World!
Hello World!===DONE===
http://cvs.php.net/viewvc.cgi/php-src/ext/filter/tests/callback_closure.phpt?view=markup&rev=1.1
Index: php-src/ext/filter/tests/callback_closure.phpt
+++ php-src/ext/filter/tests/callback_closure.phpt
--TEST--
callback function is a closure
--SKIPIF--
<?php if (!extension_loaded("filter")) die("skip"); ?>
--FILE--
<?php
$callback = function ($var) {
return $var;
};
$var = "test";
var_dump(filter_var($var, FILTER_CALLBACK, array('options'=> $callback)));
?>
--EXPECT--
string(4) "test"
http://cvs.php.net/viewvc.cgi/php-src/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt?view=markup&rev=1.1
Index: php-src/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
+++ php-src/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
--TEST--
mysqli_set_local_infile_handler() - use closures as handler
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('skipifemb.inc');
require_once('skipifconnectfailure.inc');
if (!function_exists('mysqli_set_local_infile_handler'))
die("skip - function not available.");
require_once('connect.inc');
if (!$TEST_EXPERIMENTAL)
die("skip - experimental (= unsupported) feature");
if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket))
die("skip Cannot connect to MySQL");
if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) {
mysqli_close($link);
die("skip Cannot check if Server variable 'local_infile' is set to
'ON'");
}
$row = mysqli_fetch_assoc($res);
mysqli_free_result($res);
mysqli_close($link);
if ('ON' != $row['Value'])
die(sprintf("skip Server variable 'local_infile' seems not set to 'ON',
found '%s'",
$row['Value']));
?>
--INI--
mysqli.allow_local_infile=1
--FILE--
<?php
require_once('connect.inc');
require_once('local_infile_tools.inc');
require_once('table.inc');
$callback_replace_buffer = function ($fp, &$buffer, $buflen, &$error) {
static $invocation = 0;
printf("Callback: %d\n", $invocation++);
flush();
$buffer = fread($fp, $buflen);
if ($invocation > 10)
return 0;
return strlen($buffer);
};
$file = create_standard_csv(1);
if (!try_handler(20, $link, $file, $callback_replace_buffer, null))
printf("[008] Failure\n");
mysqli_close($link);
print "done!";
?>
--EXPECTF--
Callback set to 'Closure object'
Callback: 0
Callback: 1
done!
http://cvs.php.net/viewvc.cgi/php-src/ext/pcntl/tests/signal_closure_handler.phpt?view=markup&rev=1.1
Index: php-src/ext/pcntl/tests/signal_closure_handler.phpt
+++ php-src/ext/pcntl/tests/signal_closure_handler.phpt
--TEST--
Closures as a signal handler
--SKIPIF--
<?php
if (!extension_loaded("pcntl")) print "skip";
if (!function_exists("pcntl_signal")) print "skip pcntl_signal() not
available";
if (!function_exists("posix_kill")) print "skip posix_kill() not
available";
if (!function_exists("posix_getpid")) print "skip posix_getpid() not
available";
?>
--FILE--
<?php
declare (ticks = 1);
pcntl_signal(SIGTERM, function ($signo) { echo "Signal handler called!\n"; });
echo "Start!\n";
posix_kill(posix_getpid(), SIGTERM);
$i = 0; // dummy
echo "Done!\n";
?>
--EXPECT--
Start!
Signal handler called!
Done!
http://cvs.php.net/viewvc.cgi/php-src/ext/session/tests/save_handler_closures.inc?view=markup&rev=1.1
Index: php-src/ext/session/tests/save_handler_closures.inc
+++ php-src/ext/session/tests/save_handler_closures.inc
<?php
require_once 'save_handler.inc';
foreach (array ('open', 'close', 'read', 'write', 'destroy', 'gc') as $fn) {
${$fn.'_closure'} = function () use ($fn) { return call_user_func_array
($fn, func_get_args ()); };
}
?>
http://cvs.php.net/viewvc.cgi/php-src/ext/session/tests/session_set_save_handler_closures.phpt?view=markup&rev=1.1
Index: php-src/ext/session/tests/session_set_save_handler_closures.phpt
+++ php-src/ext/session/tests/session_set_save_handler_closures.phpt
--TEST--
Test session_set_save_handler() function : using closures as callbacks
--INI--
session.save_path=
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php
ob_start();
/*
* Prototype : bool session_set_save_handler(callback $open, callback $close,
callback $read, callback $write, callback $destroy, callback $gc)
* Description : Sets user-level session storage functions
* Source code : ext/session/session.c
*/
echo "*** Testing session_set_save_handler() : using closures as callbacks
***\n";
require_once "save_handler_closures.inc";
var_dump(session_module_name());
var_dump(session_module_name(FALSE));
var_dump(session_module_name("blah"));
var_dump(session_module_name("foo"));
$path = dirname(__FILE__);
session_save_path($path);
session_set_save_handler($open_closure, $close_closure, $read_closure,
$write_closure, $destroy_closure, $gc_closure);
session_start();
$_SESSION["Blah"] = "Hello World!";
$_SESSION["Foo"] = FALSE;
$_SESSION["Guff"] = 1234567890;
var_dump($_SESSION);
session_write_close();
session_unset();
var_dump($_SESSION);
echo "Starting session again..!\n";
session_id($session_id);
session_set_save_handler($open_closure, $close_closure, $read_closure,
$write_closure, $destroy_closure, $gc_closure);
session_start();
var_dump($_SESSION);
session_write_close();
ob_end_flush();
?>
--EXPECTF--
*** Testing session_set_save_handler() : using closures as callbacks ***
unicode(%d) "%s"
Warning: session_module_name(): Cannot find named PHP session module () in %s
on line %d
bool(false)
Warning: session_module_name(): Cannot find named PHP session module (blah) in
%s on line %d
bool(false)
Warning: session_module_name(): Cannot find named PHP session module (foo) in
%s on line %d
bool(false)
Open [%s,PHPSESSID]
Read [%s,%s]
array(3) {
[u"Blah"]=>
unicode(12) "Hello World!"
[u"Foo"]=>
bool(false)
[u"Guff"]=>
int(1234567890)
}
Write [%s,%s,Blah|U:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
Notice: fwrite(): %d character unicode buffer downcoded for binary stream
runtime_encoding in %s on line %d
Close [%s,PHPSESSID]
array(3) {
[u"Blah"]=>
unicode(12) "Hello World!"
[u"Foo"]=>
bool(false)
[u"Guff"]=>
int(1234567890)
}
Starting session again..!
Open [%s,PHPSESSID]
Read [%s,%s]
array(3) {
[u"Blah"]=>
unicode(12) "Hello World!"
[u"Foo"]=>
bool(false)
[u"Guff"]=>
int(1234567890)
}
Write [%s,%s,Blah|U:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
Notice: fwrite(): %d character unicode buffer downcoded for binary stream
runtime_encoding in %s on line %d
Close [%s,PHPSESSID]
http://cvs.php.net/viewvc.cgi/php-src/ext/sqlite/tests/sqlite_closures_001.phpt?view=markup&rev=1.1
Index: php-src/ext/sqlite/tests/sqlite_closures_001.phpt
+++ php-src/ext/sqlite/tests/sqlite_closures_001.phpt
--TEST--
sqlite: aggregate functions with closures
--INI--
sqlite.assoc_case=0
--SKIPIF--
<?php # vim:ft=php
if (!extension_loaded("sqlite")) print "skip"; ?>
--FILE--
<?php
include "blankdb.inc";
$data = array(
"one",
"two",
"three"
);
sqlite_query("CREATE TABLE strings(a)", $db);
foreach ($data as $str) {
sqlite_query("INSERT INTO strings VALUES('" .
sqlite_escape_string($str) . "')", $db);
}
function cat_step(&$context, $string)
{
$context .= $string;
}
function cat_fin(&$context)
{
return $context;
}
sqlite_create_aggregate($db, "cat", function (&$context, $string) {
$context .= $string;
}, function (&$context) {
return $context;
});
$r = sqlite_query("SELECT cat(a) from strings", $db);
while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
var_dump($row);
}
sqlite_close($db);
echo "DONE!\n";
?>
--EXPECT--
array(1) {
[0]=>
unicode(11) "onetwothree"
}
DONE!
http://cvs.php.net/viewvc.cgi/php-src/ext/sqlite/tests/sqlite_closures_002.phpt?view=markup&rev=1.1
Index: php-src/ext/sqlite/tests/sqlite_closures_002.phpt
+++ php-src/ext/sqlite/tests/sqlite_closures_002.phpt
--TEST--
sqlite: regular functions with closures
--INI--
sqlite.assoc_case=0
--SKIPIF--
<?php # vim:ft=php
if (!extension_loaded("sqlite")) print "skip"; ?>
--FILE--
<?php
include "blankdb.inc";
$data = array(
array("one", "uno"),
array("two", "dos"),
array("three", "tres"),
);
sqlite_query("CREATE TABLE strings(a,b)", $db);
foreach ($data as $row) {
sqlite_query("INSERT INTO strings VALUES('" .
sqlite_escape_string($row[0]) . "','" . sqlite_escape_string($row[1]) . "')",
$db);
}
sqlite_create_function($db, "implode", function () {
$args = func_get_args();
$sep = array_shift($args);
return implode($sep, $args);
});
$r = sqlite_query("SELECT implode('-', a, b) from strings", $db);
while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
var_dump($row);
}
sqlite_close($db);
echo "DONE!\n";
?>
--EXPECT--
array(1) {
[0]=>
unicode(7) "one-uno"
}
array(1) {
[0]=>
unicode(7) "two-dos"
}
array(1) {
[0]=>
unicode(10) "three-tres"
}
DONE!
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/assert/assert_closures.phpt?view=markup&rev=1.1
Index: php-src/ext/standard/tests/assert/assert_closures.phpt
+++ php-src/ext/standard/tests/assert/assert_closures.phpt
--TEST--
assert() - basic - accept closures as callback.
--INI--
assert.active = 1
assert.warning = 1
assert.bail = 0
assert.quiet_eval = 0
--FILE--
<?php
assert_options(ASSERT_CALLBACK, function () { echo "Hello World!\n"; });
assert(0);
?>
--EXPECTF--
Hello World!
Warning: assert(): Assertion failed in %s on line %d
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/closures_001.phpt?view=markup&rev=1.1
Index: php-src/ext/standard/tests/general_functions/closures_001.phpt
+++ php-src/ext/standard/tests/general_functions/closures_001.phpt
--TEST--
register_shutdown_function() & closure
--FILE--
<?php
register_shutdown_function(function () { echo "Hello World!\n"; });
echo "Done\n";
?>
--EXPECTF--
Done
Hello World!
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/closures_002.phpt?view=markup&rev=1.1
Index: php-src/ext/standard/tests/general_functions/closures_002.phpt
+++ php-src/ext/standard/tests/general_functions/closures_002.phpt
--TEST--
register_tick_function() & closure
--FILE--
<?php
declare (ticks = 1);
$i = 0;
register_tick_function(function () use (&$i) { $i++; });
echo "Test\n";
echo "$i\n";
echo "$i\n";
var_dump ($i != 0);
echo "$i\n";
echo "Done\n";
?>
--EXPECTF--
Test
%d
%d
bool(true)
%d
Done
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/ob_start_closures.phpt?view=markup&rev=1.1
Index: php-src/ext/standard/tests/general_functions/ob_start_closures.phpt
+++ php-src/ext/standard/tests/general_functions/ob_start_closures.phpt
--TEST--
Test ob_start() function : closures as output handlers
--INI--
output_buffering=0
--FILE--
<?php
echo "*** Testing ob_start() : closures as output handlers ***\n";
ob_start(function ($output) {
return 'Output (1): ' . $output;
});
ob_start(function ($output) {
return 'Output (2): ' . $output;
});
echo "Test\nWith newlines\n";
$str1 = ob_get_contents ();
ob_end_flush();
$str2 = ob_get_contents ();
ob_end_flush();
echo $str1, $str2;
?>
===DONE===
--EXPECT--
*** Testing ob_start() : closures as output handlers ***
Output (1): Output (2): Test
With newlines
Test
With newlines
Output (2): Test
With newlines
===DONE===
http://cvs.php.net/viewvc.cgi/php-src/ext/xml/tests/xml_closures_001.phpt?view=markup&rev=1.1
Index: php-src/ext/xml/tests/xml_closures_001.phpt
+++ php-src/ext/xml/tests/xml_closures_001.phpt
--TEST--
XML parser test using closures as callbacks
--SKIPIF--
<?php include("skipif.inc"); ?>
--INI--
magic_quotes_runtime=0
--FILE--
<?php
chdir(dirname(__FILE__));
$start_element = function ($xp, $elem, $attribs)
{
print "<$elem";
if (sizeof($attribs)) {
while (list($k, $v) = each($attribs)) {
print " $k=\"$v\"";
}
}
print ">\n";
};
$end_element = function ($xp, $elem)
{
print "</$elem>\n";
};
$xp = xml_parser_create();
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xp, $start_element, $end_element);
$fp = fopen("xmltest.xml", "r");
while ($data = fread($fp, 4096)) {
xml_parse($xp, $data, feof($fp));
}
xml_parser_free($xp);
?>
--EXPECT--
<root id="elem1">
<elem1>
<elem2>
<elem3>
<elem4>
</elem4>
</elem3>
</elem2>
</elem1>
</root>
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php