mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-10 02:30:50 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54715b2765 |
No files matched your search
+1
-1
@@ -41,7 +41,7 @@ AC_CONFIG_HEADER(main/php_config.h)
|
||||
MAJOR_VERSION=5
|
||||
MINOR_VERSION=0
|
||||
RELEASE_VERSION=0
|
||||
EXTRA_VERSION="b2-dev"
|
||||
EXTRA_VERSION="b1"
|
||||
VERSION="$MAJOR_VERSION.$MINOR_VERSION.$RELEASE_VERSION$EXTRA_VERSION"
|
||||
|
||||
dnl Define where extension directories are located in the configure context
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
#ifndef _INCLUDED_IMAP_H
|
||||
#define _INCLUDED_IMAP_H
|
||||
|
||||
#if COMPILE_DL
|
||||
#undef HAVE_IMAP
|
||||
#define HAVE_IMAP 1
|
||||
#endif
|
||||
|
||||
#if HAVE_IMAP
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
#include "build-defs.h"
|
||||
#endif
|
||||
|
||||
/* Functions accessable to PHP */
|
||||
extern zend_module_entry imap_module_entry;
|
||||
#define imap_module_ptr &imap_module_entry
|
||||
|
||||
extern PHP_MINIT_FUNCTION(imap);
|
||||
extern PHP_RINIT_FUNCTION(imap);
|
||||
extern PHP_RSHUTDOWN_FUNCTION(imap);
|
||||
PHP_MINFO_FUNCTION(imap);
|
||||
PHP_FUNCTION(imap_open);
|
||||
PHP_FUNCTION(imap_popen);
|
||||
PHP_FUNCTION(imap_reopen);
|
||||
PHP_FUNCTION(imap_num_msg);
|
||||
PHP_FUNCTION(imap_num_recent);
|
||||
PHP_FUNCTION(imap_headers);
|
||||
PHP_FUNCTION(imap_headerinfo);
|
||||
PHP_FUNCTION(imap_rfc822_parse_headers);
|
||||
PHP_FUNCTION(imap_body);
|
||||
PHP_FUNCTION(imap_fetchstructure);
|
||||
PHP_FUNCTION(imap_fetchbody);
|
||||
PHP_FUNCTION(imap_expunge);
|
||||
PHP_FUNCTION(imap_delete);
|
||||
PHP_FUNCTION(imap_undelete);
|
||||
PHP_FUNCTION(imap_check);
|
||||
PHP_FUNCTION(imap_close);
|
||||
PHP_FUNCTION(imap_mail_copy);
|
||||
PHP_FUNCTION(imap_mail_move);
|
||||
PHP_FUNCTION(imap_createmailbox);
|
||||
PHP_FUNCTION(imap_renamemailbox);
|
||||
PHP_FUNCTION(imap_deletemailbox);
|
||||
PHP_FUNCTION(imap_listmailbox);
|
||||
PHP_FUNCTION(imap_scanmailbox);
|
||||
PHP_FUNCTION(imap_subscribe);
|
||||
PHP_FUNCTION(imap_unsubscribe);
|
||||
PHP_FUNCTION(imap_append);
|
||||
PHP_FUNCTION(imap_ping);
|
||||
PHP_FUNCTION(imap_base64);
|
||||
PHP_FUNCTION(imap_qprint);
|
||||
PHP_FUNCTION(imap_8bit);
|
||||
PHP_FUNCTION(imap_binary);
|
||||
PHP_FUNCTION(imap_mailboxmsginfo);
|
||||
PHP_FUNCTION(imap_rfc822_write_address);
|
||||
PHP_FUNCTION(imap_rfc822_parse_adrlist);
|
||||
PHP_FUNCTION(imap_setflag_full);
|
||||
PHP_FUNCTION(imap_clearflag_full);
|
||||
PHP_FUNCTION(imap_sort);
|
||||
PHP_FUNCTION(imap_fetchheader);
|
||||
PHP_FUNCTION(imap_fetchtext);
|
||||
PHP_FUNCTION(imap_uid);
|
||||
PHP_FUNCTION(imap_msgno);
|
||||
PHP_FUNCTION(imap_list);
|
||||
PHP_FUNCTION(imap_list_full);
|
||||
PHP_FUNCTION(imap_listscan);
|
||||
PHP_FUNCTION(imap_lsub);
|
||||
PHP_FUNCTION(imap_lsub_full);
|
||||
PHP_FUNCTION(imap_create);
|
||||
PHP_FUNCTION(imap_rename);
|
||||
PHP_FUNCTION(imap_status);
|
||||
PHP_FUNCTION(imap_bodystruct);
|
||||
PHP_FUNCTION(imap_fetch_overview);
|
||||
PHP_FUNCTION(imap_mail_compose);
|
||||
PHP_FUNCTION(imap_alerts);
|
||||
PHP_FUNCTION(imap_errors);
|
||||
PHP_FUNCTION(imap_last_error);
|
||||
PHP_FUNCTION(imap_mail);
|
||||
PHP_FUNCTION(imap_search);
|
||||
PHP_FUNCTION(imap_utf8);
|
||||
PHP_FUNCTION(imap_utf7_decode);
|
||||
PHP_FUNCTION(imap_utf7_encode);
|
||||
PHP_FUNCTION(imap_mime_header_decode);
|
||||
#else
|
||||
#define imap_module_ptr NULL
|
||||
#endif /* HAVE_IMAP */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define phpext_imap_ptr imap_module_ptr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
dnl By default we'll compile and link against the bundled PCRE library
|
||||
dnl if DIR is supplied, we'll use that for linking
|
||||
|
||||
PHP_ARG_WITH(pcre-regex,for PCRE support,
|
||||
[ --without-pcre-regex Do not include Perl Compatible Regular Expressions
|
||||
support. Use --with-pcre-regex=DIR to specify DIR
|
||||
where PCRE's include and library files are located,
|
||||
if not using bundled library.],yes)
|
||||
|
||||
if test "$PHP_PCRE_REGEX" != "no"; then
|
||||
if test "$PHP_PCRE_REGEX" = "yes"; then
|
||||
PHP_NEW_EXTENSION(pcre, pcrelib/maketables.c pcrelib/get.c pcrelib/study.c pcrelib/pcre.c php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -I@ext_srcdir@/pcrelib)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/pcrelib)
|
||||
AC_DEFINE(HAVE_BUNDLED_PCRE, 1, [ ])
|
||||
else
|
||||
for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre; do
|
||||
test -f $i/pcre.h && PCRE_INCDIR=$i
|
||||
done
|
||||
|
||||
if test -z "$PCRE_INCDIR"; then
|
||||
AC_MSG_ERROR([Could not find pcre.h in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
for j in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/lib; do
|
||||
test -f $j/libpcre.a -o -f $j/libpcre.$SHLIB_SUFFIX_NAME && PCRE_LIBDIR=$j
|
||||
done
|
||||
|
||||
if test -z "$PCRE_LIBDIR" ; then
|
||||
AC_MSG_ERROR([Could not find libpcre.(a|$SHLIB_SUFFIX_NAME) in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
pcre_major=`grep PCRE_MAJOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
pcre_minor=`grep PCRE_MINOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
changequote([,])
|
||||
pcre_minor_length=`echo "$pcre_minor" | wc -c | sed -e 's/[^0-9]//g'`
|
||||
if test "$pcre_minor_length" -eq 2 ; then
|
||||
pcre_minor="$pcre_minor"0
|
||||
fi
|
||||
pcre_version=$pcre_major$pcre_minor
|
||||
if test "$pcre_version" -lt 208; then
|
||||
AC_MSG_ERROR([The PCRE extension requires PCRE library version >= 2.08])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(pcre, $PCRE_LIBDIR, PCRE_SHARED_LIBADD)
|
||||
|
||||
AC_DEFINE(HAVE_PCRE, 1, [ ])
|
||||
PHP_ADD_INCLUDE($PCRE_INCDIR)
|
||||
PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DSUPPORT_UTF8 -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10)
|
||||
fi
|
||||
PHP_SUBST(PCRE_SHARED_LIBADD)
|
||||
fi
|
||||
Whitespace-only changes.
@@ -1,8 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
LTLIBRARY_NAME = libsoap.la
|
||||
LTLIBRARY_SOURCES = soap.c php_sdl.c php_schema.c php_xml.c php_encoding.c php_http.c php_packet_soap.c
|
||||
LTLIBRARY_SHARED_NAME = soap.la
|
||||
LTLIBRARY_SHARED_LIBADD = $(SOAP_SHARED_LIBADD)
|
||||
|
||||
include $(top_srcdir)/build/dynlib.mk
|
||||
@@ -1,39 +0,0 @@
|
||||
TODO:
|
||||
make sure soap 1.1 and 1.2 is supported fully
|
||||
Better WSDL support Client and server (how much validation is needed here?)
|
||||
UDDI??
|
||||
make internal refrences for soap encoding (use seralization logic)
|
||||
add ini option for always soap_error_handler
|
||||
provide user space overriding of serialization certin objects and types
|
||||
serialization in general needs to be polished/finished... all xsd types
|
||||
make perstistant objects and work with or without register_globals on
|
||||
look to see if php-soap will work with out always_populate_raw_post_data on
|
||||
see if client will work with ssl.. should be eaiser with php_streams
|
||||
work on soap seralizer (php serialization)
|
||||
work on a soap-service 'regiestry' and 'proxy' (apache soap style)
|
||||
convert all string mainpulation to use smart_str
|
||||
make the 'soap' packet abstract.. maybe incorperate xml-rpc
|
||||
make the transport layer abstract.. what other transport layers are needed?... who uses smtp? what about jabber?
|
||||
make $soap_object->data = 'text'; maybe invoke a set_*() and/or get_*() method
|
||||
when using wsdls and function names are similar find the best match
|
||||
void test(int);
|
||||
void test(string);
|
||||
maybe use the same alogrithim as ext/java.
|
||||
investigate further http keep_alive... inital testing proved slower.. maybe php_streams will speed things up..
|
||||
provide schema 1999/2001 support....
|
||||
through memory leak testing
|
||||
possible using shared memory for sdl caching...
|
||||
api for clearing/checking sdl caching...
|
||||
make php-soap work as a standalone server using php_streams and the new socket extension
|
||||
http authication
|
||||
proxy support
|
||||
wsdl generation static and auto (.net style (http://server.com/soapserver.php?WSDL)) using phpdoc parsing engine
|
||||
interpo testing...
|
||||
BENCHMARKING...... lets prove how fast it is.
|
||||
do some more work on website
|
||||
|
||||
does this list stop... what exactly have i done?
|
||||
im sure im forgetting 20 thousand more things....
|
||||
|
||||
|
||||
- brad
|
||||
@@ -1,33 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension soap
|
||||
|
||||
PHP_ARG_ENABLE(soap, whether to enable soap support,
|
||||
[ --enable-soap[=DIR] Enable soap support. DIR is libxml2
|
||||
library directory.])
|
||||
|
||||
if test "$PHP_SOAP" != "no"; then
|
||||
if test "$PHP_SOAP" = "yes"; then
|
||||
for i in /usr/local /usr; do
|
||||
if test -d "$i/include/libxml2/libxml"; then
|
||||
XML2_INCDIR=$i/include/libxml2
|
||||
XML2_LIBDIR=$i/lib
|
||||
fi
|
||||
done
|
||||
else
|
||||
if test -d "$PHP_SOAP/include/libxml2/libxml"; then
|
||||
XML2_INCDIR=$PHP_SOAP/include/libxml2
|
||||
XML2_LIBDIR=$PHP_SOAP/lib
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$XML2_INCDIR"; then
|
||||
AC_MSG_ERROR(Cannot find libxml2 header. Please specify correct libxml2 installation path)
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_PHP_SOAP,1,[Whether you have soap module])
|
||||
|
||||
PHP_ADD_INCLUDE($XML2_INCDIR)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(xml2,$XML2_LIBDIR,SOAP_SHARED_LIBADD)
|
||||
PHP_NEW_EXTENSION(soap, soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c, $ext_shared)
|
||||
PHP_SUBST(SOAP_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
class Interop_Base
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,102 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Round 2 Interop Client Tests</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a href="index.php">Back to Interop Index</a><br>
|
||||
<p> </p>
|
||||
<?php
|
||||
require_once 'SOAP/interop/client_round2_interop.php';
|
||||
|
||||
$iop = new Interop_Client();
|
||||
|
||||
function endpointList($test,$sel_endpoint)
|
||||
{
|
||||
global $iop;
|
||||
$iop->getEndpoints($test);
|
||||
echo "<select name='endpoint'>\n";
|
||||
foreach ($iop->endpoints as $epname => $epinfo) {
|
||||
$selected = '';
|
||||
if ($sel_endpoint == $epname) $selected = ' SELECTED';
|
||||
echo "<option value='$epname'$selected>$epname</option>\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
}
|
||||
function methodList($test,$sel_method)
|
||||
{
|
||||
global $iop;
|
||||
|
||||
$ml = $iop->getMethodList($test);
|
||||
echo "<select name='method'>\n";
|
||||
foreach ($ml as $method) {
|
||||
$selected = '';
|
||||
if ($sel_method == $method) $selected = ' SELECTED';
|
||||
echo "<option value='$method'$selected>$method</option>\n";
|
||||
}
|
||||
echo "<option value='ALL'>Run All Methods</option>\n";
|
||||
echo "</select>\n";
|
||||
}
|
||||
|
||||
function endpointTestForm($test, $endpoint, $method, $paramType, $useWSDL)
|
||||
{
|
||||
global $PHP_SELF;
|
||||
if (!$test) $test = 'base';
|
||||
echo "Round 2 '$test' Selected<br>\n";
|
||||
echo "Select endpoint and method to run:<br>\n";
|
||||
echo "<form action='$PHP_SELF' method='post'>\n";
|
||||
echo "<input type='hidden' name='test' value='$test'>\n";
|
||||
endpointList($test, $endpoint);
|
||||
methodList($test, $method);
|
||||
echo "<select name='paramType'><option value='soapval'>soap value</option>";
|
||||
echo "<option value='php'".($paramType=='php'?' selected':'').">php internal type</option></select>\n";
|
||||
echo "<select name='useWSDL'><option value='0'>go Direct</option><option value='1'".($useWSDL?' selected':'').">use WSDL</option></select>\n";
|
||||
echo "<input type='submit' value='Go'>\n";
|
||||
echo "</form><br>\n";
|
||||
}
|
||||
|
||||
function testSelectForm($selected_test = NULL)
|
||||
{
|
||||
global $iop, $PHP_SELF;
|
||||
echo "Select a Round 2 test case to run:<br>\n";
|
||||
echo "<form action='$PHP_SELF' method='post'>\n";
|
||||
echo "<select name='test'>\n";
|
||||
foreach ($iop->tests as $test) {
|
||||
$selected = '';
|
||||
if ($selected_test == $test) $selected = ' SELECTED';
|
||||
echo "<option value='$test'$selected>$test</option>\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
echo "<input type='submit' value='Go'>\n";
|
||||
echo "</form><br>\n";
|
||||
}
|
||||
|
||||
testSelectForm($_POST['test']);
|
||||
endpointTestForm($_POST['test'],$_POST['endpoint'],$_POST['method'],$_POST['paramType'],$_POST['useWSDL']);
|
||||
|
||||
if ($_POST['test'] && array_key_exists('endpoint', $_POST) && array_key_exists('method', $_POST)) {
|
||||
// here we execute the orders
|
||||
echo "<h2>Calling {$_POST['method']} at {$_POST['endpoint']}</h2>\n";
|
||||
echo "NOTE: wire's are slightly modified to display better in web browsers.<br>\n";
|
||||
|
||||
$iop->currentTest = $_POST['test']; // see $tests above
|
||||
$iop->paramType = $_POST['paramType']; // 'php' or 'soapval'
|
||||
$iop->useWSDL = $_POST['useWSDL']; // 1= do wsdl tests
|
||||
$iop->numServers = 0; // 0 = all
|
||||
$iop->specificEndpoint = $_POST['endpoint']; // test only this endpoint
|
||||
$iop->testMethod = $_POST['method']=='ALL'?'':$_POST['method']; // test only this method
|
||||
$iop->skipEndpointList = array(); // endpoints to skip
|
||||
$this->nosave = 0; // 1= disable saving results to database
|
||||
// debug output
|
||||
$iop->show = 1;
|
||||
$iop->debug = 1;
|
||||
$iop->showFaults = 0; // used in result table output
|
||||
echo '<pre>';
|
||||
$iop->doTest(); // run a single set of tests using above options
|
||||
echo '</pre>';
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,796 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
require_once 'DB.php'; // PEAR/DB
|
||||
require_once 'base.php';
|
||||
require_once 'client_round2_params.php';
|
||||
require_once 'test.utility.php';
|
||||
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
class Interop_Client extends Interop_Base
|
||||
{
|
||||
// database DNS
|
||||
var $DSN = 'mysql://user@localhost/interop2';
|
||||
|
||||
// our central interop server, where we can get the list of endpoints
|
||||
var $interopServer = "http://www.whitemesa.net/interopInfo";
|
||||
|
||||
// our local endpoint, will always get added to the database for all tests
|
||||
var $localEndpoint;
|
||||
|
||||
// specify testing
|
||||
var $currentTest = 'base'; // see $tests above
|
||||
var $paramType = 'php'; // 'php' or 'soapval'
|
||||
var $useWSDL = 0; // 1= do wsdl tests
|
||||
var $numServers = 0; // 0 = all
|
||||
var $specificEndpoint = ''; // test only this endpoint
|
||||
var $testMethod = ''; // test only this method
|
||||
var $skipEndpointList = array(); // endpoints to skip
|
||||
var $nosave = 0;
|
||||
var $startAt = ''; // start in list at this endpoint
|
||||
// debug output
|
||||
var $show = 1;
|
||||
var $debug = 0;
|
||||
var $showFaults = 0; // used in result table output
|
||||
|
||||
// PRIVATE VARIABLES
|
||||
var $dbc = NULL;
|
||||
var $totals = array();
|
||||
var $tests = array('base','GroupB', 'GroupC');
|
||||
var $paramTypes = array('php', 'soapval');
|
||||
var $endpoints = array();
|
||||
|
||||
function Interop_Client() {
|
||||
// set up the database connection
|
||||
$this->dbc = DB::connect($this->DSN, true);
|
||||
// if it errors out, just ignore it and rely on regular methods
|
||||
if (DB::isError($this->dbc)) {
|
||||
echo $this->dbc->getMessage();
|
||||
$this->dbc = NULL;
|
||||
}
|
||||
// set up local endpoint
|
||||
$this->localEndpoint['base'] = array(
|
||||
'endpointName'=>'PEAR SOAP',
|
||||
'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
|
||||
'wsdlURL'=>'http://localhost/soap_interop/interop.wsdl'
|
||||
);
|
||||
$this->localEndpoint['GroupB'] = array(
|
||||
'endpointName'=>'PEAR SOAP',
|
||||
'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
|
||||
'wsdlURL'=>'http://localhost/soap_interop/interopB.wsdl'
|
||||
);
|
||||
$this->localEndpoint['GroupC'] = array(
|
||||
'endpointName'=>'PEAR SOAP',
|
||||
'endpointURL'=>'http://localhost/soap_interop/server_round2.php',
|
||||
'wsdlURL'=>'http://localhost/soap_interop/echoheadersvc.wsdl'
|
||||
);
|
||||
}
|
||||
|
||||
function _fetchEndpoints(&$soapclient, $test) {
|
||||
$this->_getEndpoints($test, 1);
|
||||
|
||||
// retreive endpoints from the endpoint server
|
||||
$endpointArray = $soapclient->call("GetEndpointInfo",array("groupName"=>$test),"http://soapinterop.org/info/","http://soapinterop.org/info/");
|
||||
if (PEAR::isError($endpointArray)) {
|
||||
print $soapclient->wire;
|
||||
print_r($endpointArray);
|
||||
return;
|
||||
}
|
||||
|
||||
// add our local endpoint
|
||||
if ($this->localEndpoint[$test]) {
|
||||
array_push($endpointArray, $this->localEndpoint[$test]);
|
||||
}
|
||||
|
||||
if (!$endpointArray) return;
|
||||
|
||||
// reset the status to zero
|
||||
$res = $this->dbc->query("update endpoints set status = 0 where class='$test'");
|
||||
if (DB::isError($res)) {
|
||||
die ($res->getMessage());
|
||||
}
|
||||
if (is_object($res)) $res->free();
|
||||
// save new endpoints into database
|
||||
foreach($endpointArray as $k => $v){
|
||||
if (array_key_exists($v['endpointName'],$this->endpoints)) {
|
||||
$res = $this->dbc->query("update endpoints set endpointURL='{$v['endpointURL']}', wsdlURL='{$v['wsdlURL']}', status=1 where id={$this->endpoints[$v['endpointName']]['id']}");
|
||||
} else {
|
||||
$res = $this->dbc->query("insert into endpoints (endpointName,endpointURL,wsdlURL,class) values('{$v['endpointName']}','{$v['endpointURL']}','{$v['wsdlURL']}','$test')");
|
||||
}
|
||||
if (DB::isError($res)) {
|
||||
die ($res->getMessage());
|
||||
}
|
||||
if (is_object($res)) $res->free();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fetchEndpoints
|
||||
* retreive endpoints interop server
|
||||
*
|
||||
* @return boolean result
|
||||
* @access private
|
||||
*/
|
||||
function fetchEndpoints($test = NULL) {
|
||||
// fetch from the interop server
|
||||
$soapclient = new SoapObject($this->interopServer);
|
||||
|
||||
if ($test) {
|
||||
$this->_fetchEndpoints($soapclient, $test);
|
||||
} else {
|
||||
foreach ($this->tests as $test) {
|
||||
$this->_fetchEndpoints($soapclient, $test);
|
||||
}
|
||||
$test = 'base';
|
||||
}
|
||||
|
||||
// retreive all endpoints now
|
||||
$this->currentTest = $test;
|
||||
return $this->_getEndpoints($test);
|
||||
}
|
||||
|
||||
/**
|
||||
* getEndpoints
|
||||
* retreive endpoints from either database or interop server
|
||||
*
|
||||
* @param string base (see local var $tests)
|
||||
* @param boolean all (if false, only get valid endpoints, status=1)
|
||||
* @return boolean result
|
||||
* @access private
|
||||
*/
|
||||
function getEndpoints($base = 'base', $all = 0) {
|
||||
if (!$this->_getEndpoints($base, $all)) {
|
||||
return $this->fetchEndpoints($base);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _getEndpoints
|
||||
* retreive endpoints from database
|
||||
*
|
||||
* @param string base (see local var $tests)
|
||||
* @param boolean all (if false, only get valid endpoints, status=1)
|
||||
* @return boolean result
|
||||
* @access private
|
||||
*/
|
||||
function _getEndpoints($base = "", $all = 0) {
|
||||
$this->endpoints = array();
|
||||
|
||||
// build sql
|
||||
$sql = "select * from endpoints ";
|
||||
if ($base) {
|
||||
$sql .= "where class='$base' ";
|
||||
if (!$all) $sql .= "and status=1";
|
||||
} else
|
||||
if (!$all) $sql .= "where status=1";
|
||||
|
||||
$db_ep = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
|
||||
if (DB::isError($db_ep)) {
|
||||
echo $sql."\n";
|
||||
echo $db_ep->getMessage();
|
||||
return FALSE;
|
||||
}
|
||||
// rearange the array
|
||||
foreach ($db_ep as $entry) {
|
||||
$this->endpoints[$entry['endpointName']] = $entry;
|
||||
}
|
||||
if (count($this->endpoints) > 0) {
|
||||
$this->currentTest = $base;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* getResults
|
||||
* retreive results from the database, stuff them into the endpoint array
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function getResults($test = 'base', $type = 'php', $wsdl = 0) {
|
||||
// be sure we have the right endpoints for this test result
|
||||
$this->getEndpoints($test);
|
||||
|
||||
// retreive the results and put them into the endpoint info
|
||||
$sql = "select * from results where class='$test' and type='$type' and wsdl=$wsdl";
|
||||
$results = $this->dbc->getAll($sql,NULL, DB_FETCHMODE_ASSOC );
|
||||
foreach ($results as $result) {
|
||||
// find the endpoint
|
||||
foreach ($this->endpoints as $epn => $epi) {
|
||||
if ($epi['id'] == $result['endpoint']) {
|
||||
// store the info
|
||||
$this->endpoints[$epn]['methods'][$result['function']] = $result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* saveResults
|
||||
* save the results of a method test into the database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _saveResults($endpoint_id, &$soap_test) {
|
||||
if ($this->nosave) return;
|
||||
|
||||
$result = $soap_test->result;
|
||||
$wire = $result['wire'];
|
||||
if ($result['success']) {
|
||||
$success = 'OK';
|
||||
$error = '';
|
||||
} else {
|
||||
$success = $result['fault']->faultcode;
|
||||
$error = $result['fault']->faultstring;
|
||||
if (!$wire) $wire= $result['fault']->detail;
|
||||
}
|
||||
|
||||
$test_name = $soap_test->test_name;
|
||||
// add header info to the test name
|
||||
if ($soap_test->headers) {
|
||||
foreach ($soap_test->headers as $h) {
|
||||
$destination = 0;
|
||||
if (get_class($h) == 'soap_header') {
|
||||
if ($h->attributes['SOAP-ENV:actor'] == 'http://schemas.xmlsoap.org/soap/actor/next') $destination = 1;
|
||||
$test_name .= ":{$h->name},$destination,{$h->attributes['SOAP-ENV:mustUnderstand']}";
|
||||
} else {
|
||||
if (!$h[3] || $h[3] == 'http://schemas.xmlsoap.org/soap/actor/next') $destination = 1;
|
||||
if (!$h[2]) $h[2] = 0;
|
||||
$qn = new QName($h[0]);
|
||||
$test_name .= ":{$qn->name},$destination,".(int)$h[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "delete from results where endpoint=$endpoint_id ".
|
||||
"and class='$this->currentTest' and type='$this->paramType' ".
|
||||
"and wsdl=$this->useWSDL and function=".
|
||||
$this->dbc->quote($test_name);
|
||||
#echo "\n".$sql;
|
||||
$res = $this->dbc->query($sql);
|
||||
if (DB::isError($res)) {
|
||||
die ($res->getMessage());
|
||||
}
|
||||
if (is_object($res)) $res->free();
|
||||
|
||||
$sql = "insert into results (endpoint,stamp,class,type,wsdl,function,result,error,wire) ".
|
||||
"values($endpoint_id,".time().",'$this->currentTest',".
|
||||
"'$this->paramType',$this->useWSDL,".
|
||||
$this->dbc->quote($test_name).",".
|
||||
$this->dbc->quote($success).",".
|
||||
$this->dbc->quote($error).",".
|
||||
($wire?$this->dbc->quote($wire):"''").")";
|
||||
#echo "\n".$sql;
|
||||
$res = $this->dbc->query($sql);
|
||||
|
||||
if (DB::isError($res)) {
|
||||
die ($res->getMessage());
|
||||
}
|
||||
if (is_object($res)) $res->free();
|
||||
}
|
||||
|
||||
/**
|
||||
* decodeSoapval
|
||||
* decodes a soap value to php type, used for test result comparisions
|
||||
*
|
||||
* @param SOAP_Value soapval
|
||||
* @return mixed result
|
||||
* @access public
|
||||
*/
|
||||
function decodeSoapval($soapval)
|
||||
{
|
||||
if (gettype($soapval) == "object" &&
|
||||
(strcasecmp(get_class($soapval),"soapparam") == 0 ||
|
||||
strcasecmp(get_class($soapval),"soapvar") == 0)) {
|
||||
if (strcasecmp(get_class($soapval),"soapparam") == 0)
|
||||
$val = $soapval->param_data->enc_value;
|
||||
else
|
||||
$val = $soapval->enc_value;
|
||||
} else {
|
||||
$val = $soapval;
|
||||
}
|
||||
if (is_array($val)) {
|
||||
foreach($val as $k => $v) {
|
||||
if (gettype($v) == "object" &&
|
||||
(strcasecmp(get_class($soapval),"soapparam") == 0 ||
|
||||
strcasecmp(get_class($soapval),"soapvar") == 0)) {
|
||||
$val[$k] = $this->decodeSoapval($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* compareResult
|
||||
* compare two php types for a match
|
||||
*
|
||||
* @param string expect
|
||||
* @param string test_result
|
||||
* @return boolean result
|
||||
* @access public
|
||||
*/
|
||||
function compareResult($expect, $result, $type = NULL)
|
||||
{
|
||||
$ok = 0;
|
||||
$expect_type = gettype($expect);
|
||||
$result_type = gettype($result);
|
||||
if ($expect_type == "array" && $result_type == "array") {
|
||||
# compare arrays
|
||||
$ok = array_compare($expect, $result);
|
||||
} else {
|
||||
if ($type == 'boolean')
|
||||
$ok = boolean_compare($expect, $result);
|
||||
else
|
||||
$ok = string_compare($expect, $result);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* doEndpointMethod
|
||||
* run a method on an endpoint and store it's results to the database
|
||||
*
|
||||
* @param array endpoint_info
|
||||
* @param SOAP_Test test
|
||||
* @return boolean result
|
||||
* @access public
|
||||
*/
|
||||
function doEndpointMethod(&$endpoint_info, &$soap_test) {
|
||||
$ok = FALSE;
|
||||
|
||||
// prepare a holder for the test results
|
||||
$soap_test->result['class'] = $this->currentTest;
|
||||
$soap_test->result['type'] = $this->paramType;
|
||||
$soap_test->result['wsdl'] = $this->useWSDL;
|
||||
|
||||
if ($this->useWSDL) {
|
||||
if (array_key_exists('wsdlURL',$endpoint_info)) {
|
||||
if (!array_key_exists('client',$endpoint_info)) {
|
||||
$endpoint_info['client'] = new SoapObject($endpoint_info['wsdlURL']);
|
||||
}
|
||||
$soap =& $endpoint_info['client'];
|
||||
|
||||
# XXX how do we determine a failure on retreiving/parsing wsdl?
|
||||
if ($soap->wsdl->fault) {
|
||||
$fault = $soap->wsdl->fault->getFault();
|
||||
$soap_test->setResult(0,'WSDL',
|
||||
$fault->faultstring."\n\n".$fault->detail,
|
||||
$fault->faultstring,
|
||||
$fault
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
$fault = new SoapFault('WSDL',"no WSDL defined for $endpoint");
|
||||
$soap_test->setResult(0,'WSDL',
|
||||
$fault->faultstring,
|
||||
$fault->faultstring,
|
||||
$fault
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
$namespace = false;
|
||||
$soapaction = false;
|
||||
} else {
|
||||
$namespace = $soapaction = 'http://soapinterop.org/';
|
||||
// hack to make tests work with MS SoapToolkit
|
||||
// it's the only one that uses this soapaction, and breaks if
|
||||
// it isn't right. Can't wait for soapaction to be fully depricated
|
||||
if ($this->currentTest == 'base' &&
|
||||
strstr($endpoint_info['endpointName'],'MS SOAP ToolKit 2.0')) {
|
||||
$soapaction = 'urn:soapinterop';
|
||||
}
|
||||
if (!array_key_exists('client',$endpoint_info)) {
|
||||
$endpoint_info['client'] = new SoapObject($endpoint_info['endpointURL'],$soapaction);
|
||||
}
|
||||
$soap = $endpoint_info['client'];
|
||||
}
|
||||
// add headers to the test
|
||||
if ($soap_test->headers) {
|
||||
// $header is already a SOAP_Header class
|
||||
foreach ($soap_test->headers as $header) {
|
||||
$soap->addHeader($header);
|
||||
}
|
||||
}
|
||||
// XXX no way to set encoding
|
||||
// this lets us set UTF-8, US-ASCII or other
|
||||
//$soap->setEncoding($soap_test->encoding);
|
||||
|
||||
if ($this->useWSDL) {
|
||||
$args = '';
|
||||
foreach ($soap_test->method_params as $pname => $param) {
|
||||
$arg = '$soap_test->method_params["'.$pname.'"]';
|
||||
$args .= $args?','.$arg:$arg;
|
||||
}
|
||||
$return = eval('return $soap->'.$soap_test->method_name.'('.$args.');');
|
||||
} else {
|
||||
$return = $soap->__call($soap_test->method_name,$soap_test->method_params,$soapaction, $namespace);
|
||||
}
|
||||
|
||||
// save the wire
|
||||
$wire = $soap->__getlastrequest()."\n\n".$soap->__getlastresponse();
|
||||
$wire = str_replace('>',">\n",$wire);
|
||||
$wire = str_replace('" ',"\" \n",$wire);
|
||||
#print $wire;
|
||||
|
||||
if(!$soap->__isfault()){
|
||||
if (is_array($soap_test->method_params) && count($soap_test->method_params) == 1) {
|
||||
$sent = array_shift($soap_test->method_params);
|
||||
} else {
|
||||
$sent = $soap_test->method_params;
|
||||
}
|
||||
|
||||
// compare header results
|
||||
$header_result = array();
|
||||
$headers_ok = TRUE;
|
||||
|
||||
# XXX need to implement header support!
|
||||
#
|
||||
#if ($soap_test->headers) {
|
||||
# // $header is already a SOAP_Header class
|
||||
# foreach ($soap_test->headers as $header) {
|
||||
# if (get_class($header) != 'soap_header') {
|
||||
# // assume it's an array
|
||||
# $header = new SOAP_Header($header[0], NULL, $header[1], $header[2], $header[3], $header[4]);
|
||||
# }
|
||||
# $expect = $soap_test->headers_expect[$header->name];
|
||||
# $header_result[$header->name] = array();
|
||||
# // XXX need to fix need_result to identify the actor correctly
|
||||
# $need_result = $hresult ||
|
||||
# ($header->attributes['SOAP-ENV:actor'] == 'http://schemas.xmlsoap.org/soap/actor/next'
|
||||
# && $header->attributes['SOAP-ENV:mustUnderstand']);
|
||||
# if ($expect) {
|
||||
# $hresult = $soap->headers[key($expect)];
|
||||
# $ok = !$need_result || $this->compareResult($hresult ,$expect[key($expect)]);
|
||||
# } else {
|
||||
# $hresult = $soap->headers[$header->name];
|
||||
# $expect = $this->decodeSoapval($header);
|
||||
# $ok = !$need_result || $this->compareResult($hresult ,$expect);
|
||||
# }
|
||||
# $header_result[$header->name]['ok'] = $ok;
|
||||
# if (!$ok) $headers_ok = FALSE;
|
||||
# }
|
||||
#}
|
||||
|
||||
# we need to decode what we sent so we can compare!
|
||||
$sent_d = $this->decodeSoapval($sent);
|
||||
|
||||
$soap_test->result['sent'] = $sent;
|
||||
$soap_test->result['return'] = $return;
|
||||
// compare the results with what we sent
|
||||
$ok = $this->compareResult($sent_d,$return, $sent->type);
|
||||
if (!$ok && $soap_test->expect) {
|
||||
$ok = $this->compareResult($soap_test->expect,$return);
|
||||
}
|
||||
|
||||
if($ok){
|
||||
if (!$headers_ok) {
|
||||
$fault = new SoapFault('HEADER','The returned result did not match what we expected to receive');
|
||||
$soap_test->setResult(0,$fault->faultcode,
|
||||
$wire,
|
||||
$fault->faultstring,
|
||||
$fault
|
||||
);
|
||||
} else {
|
||||
$soap_test->setResult(1,'OK',$wire);
|
||||
$success = TRUE;
|
||||
}
|
||||
} else {
|
||||
$fault = new SoapFault('RESULT','The returned result did not match what we expected to receive');
|
||||
$soap_test->setResult(0,$fault->faultcode,
|
||||
$wire,
|
||||
$fault->faultstring,
|
||||
$fault
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$fault = $soap->__getfault();
|
||||
if ($soap_test->expect_fault) {
|
||||
$ok = 1;
|
||||
$res = 'OK';
|
||||
} else {
|
||||
$ok = 0;
|
||||
$res =$fault->faultcode;
|
||||
}
|
||||
$soap_test->setResult($ok,$res, $wire,$fault->faultstring, $fault);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* doTest
|
||||
* run a single round of tests
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function doTest() {
|
||||
global $soap_tests;
|
||||
// get endpoints for this test
|
||||
$this->getEndpoints($this->currentTest);
|
||||
#clear totals
|
||||
$this->totals = array();
|
||||
|
||||
$i = 0;
|
||||
foreach($this->endpoints as $endpoint => $endpoint_info){
|
||||
|
||||
// if we specify an endpoint, skip until we find it
|
||||
if ($this->specificEndpoint && $endpoint != $this->specificEndpoint) continue;
|
||||
if ($this->useWSDL && !$endpoint_info['endpointURL']) continue;
|
||||
|
||||
$skipendpoint = FALSE;
|
||||
$this->totals['servers']++;
|
||||
#$endpoint_info['tests'] = array();
|
||||
|
||||
if ($this->show) print "Processing $endpoint at {$endpoint_info['endpointURL']}<br>\n";
|
||||
|
||||
foreach($soap_tests[$this->currentTest] as $soap_test) {
|
||||
//foreach(array_keys($method_params[$this->currentTest][$this->paramType]) as $method)
|
||||
|
||||
// only run the type of test we're looking for (php or soapval)
|
||||
if ($soap_test->type != $this->paramType) continue;
|
||||
|
||||
// if we haven't reached our startpoint, skip
|
||||
if ($this->startAt && $this->startAt != $endpoint_info['endpointName']) continue;
|
||||
$this->startAt = '';
|
||||
|
||||
// if this is in our skip list, skip it
|
||||
if (in_array($endpoint, $this->skipEndpointList)) {
|
||||
$skipendpoint = TRUE;
|
||||
$skipfault = new SoapFault('SKIP','endpoint skipped');
|
||||
$soap_test->setResult(0,$fault->faultcode, '',
|
||||
$skipfault->faultstring,
|
||||
$skipfault
|
||||
);
|
||||
#$endpoint_info['tests'][] = &$soap_test;
|
||||
#$soap_test->showTestResult($this->debug);
|
||||
#$this->_saveResults($endpoint_info['id'], $soap_test->method_name);
|
||||
$soap_test->result = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we're looking for a specific method, skip unless we have it
|
||||
if ($this->testMethod && !strstr($this->testMethod,$soap_test->test_name)) continue;
|
||||
if ($this->testMethod && $this->currentTest == 'GroupC') {
|
||||
// we have to figure things out now
|
||||
if (!preg_match('/(.*):(.*),(\d),(\d)/',$this->testMethod, $m)) continue;
|
||||
|
||||
// is the header in the headers list?
|
||||
$gotit = FALSE;
|
||||
foreach ($soap_test->headers as $header) {
|
||||
if (get_class($header) == 'soap_header') {
|
||||
if ($header->name == $m[2]) {
|
||||
$gotit = $header->attributes['SOAP-ENV:actor'] == ($m[3]?SOAP_TEST_ACTOR_NEXT:SOAP_TEST_ACTOR_OTHER);
|
||||
$gotit = $gotit && $header->attributes['SOAP-ENV:mustUnderstand'] == $m[4];
|
||||
}
|
||||
} else {
|
||||
if ($header[0] == $m[2]) {
|
||||
$gotit = $gotit && $header[3] == ($m[3]?SOAP_TEST_ACTOR_NEXT:SOAP_TEST_ACTOR_OTHER);
|
||||
$gotit = $gotit && $header[4] == $m[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$gotit) continue;
|
||||
}
|
||||
|
||||
// if we are skipping the rest of the tests (due to error) note a fault
|
||||
if ($skipendpoint) {
|
||||
$soap_test->setResult(0,$fault->faultcode, '',
|
||||
$skipfault->faultstring,
|
||||
$skipfault
|
||||
);
|
||||
#$endpoint_info['tests'][] = &$soap_test;
|
||||
$this->totals['fail']++;
|
||||
} else {
|
||||
// run the endpoint test
|
||||
if ($this->doEndpointMethod($endpoint_info, $soap_test)) {
|
||||
$this->totals['success']++;
|
||||
} else {
|
||||
$skipendpoint = $soap_test->result['fault']->faultcode=='HTTP'
|
||||
&& strstr($soap_test->result['fault']->faultstring,'Connect Error');
|
||||
$skipfault = $soap_test->result['fault'];
|
||||
$this->totals['fail']++;
|
||||
}
|
||||
#$endpoint_info['tests'][] = &$soap_test;
|
||||
}
|
||||
$soap_test->showTestResult($this->debug);
|
||||
$this->_saveResults($endpoint_info['id'], $soap_test);
|
||||
$soap_test->result = NULL;
|
||||
$this->totals['calls']++;
|
||||
}
|
||||
if ($this->numservers && ++$i >= $this->numservers) break;
|
||||
}
|
||||
}
|
||||
|
||||
function doGroupTests() {
|
||||
$dowsdl = array(0,1);
|
||||
foreach($dowsdl as $usewsdl) {
|
||||
$this->useWSDL = $usewsdl;
|
||||
foreach($this->paramTypes as $ptype) {
|
||||
// skip a pointless test
|
||||
if ($usewsdl && $ptype == 'soapval') break;
|
||||
$this->paramType = $ptype;
|
||||
$this->doTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* doTests
|
||||
* go all out. This takes time.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function doTests() {
|
||||
// the mother of all interop tests
|
||||
$dowsdl = array(0,1);
|
||||
foreach($this->tests as $test) {
|
||||
$this->currentTest = $test;
|
||||
foreach($dowsdl as $usewsdl) {
|
||||
$this->useWSDL = $usewsdl;
|
||||
foreach($this->paramTypes as $ptype) {
|
||||
// skip a pointless test
|
||||
if ($usewsdl && $ptype == 'soapval') break;
|
||||
$this->paramType = $ptype;
|
||||
$this->doTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ***********************************************************
|
||||
// output functions
|
||||
|
||||
/**
|
||||
* getResults
|
||||
* retreive results from the database, stuff them into the endpoint array
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function getMethodList($test = 'base') {
|
||||
// retreive the results and put them into the endpoint info
|
||||
$sql = "select distinct(function) from results where class='$test' order by function";
|
||||
$results = $this->dbc->getAll($sql);
|
||||
$ar = array();
|
||||
foreach($results as $result) {
|
||||
$ar[] = $result[0];
|
||||
}
|
||||
return $ar;
|
||||
}
|
||||
|
||||
function outputTable()
|
||||
{
|
||||
$methods = $this->getMethodList($this->currentTest);
|
||||
if (!$methods) return;
|
||||
$this->getResults($this->currentTest,$this->paramType,$this->useWSDL);
|
||||
|
||||
echo "<b>Testing $this->currentTest ";
|
||||
if ($this->useWSDL) echo "using WSDL ";
|
||||
else echo "using Direct calls ";
|
||||
echo "with $this->paramType values</b><br>\n";
|
||||
|
||||
// calculate totals for this table
|
||||
$this->totals['success'] = 0;
|
||||
$this->totals['fail'] = 0;
|
||||
$this->totals['servers'] = 0; #count($this->endpoints);
|
||||
foreach ($this->endpoints as $endpoint => $endpoint_info) {
|
||||
if (count($endpoint_info['methods']) > 0) {
|
||||
$this->totals['servers']++;
|
||||
foreach ($methods as $method) {
|
||||
$r = $endpoint_info['methods'][$method]['result'];
|
||||
if ($r == 'OK') $this->totals['success']++;
|
||||
else $this->totals['fail']++;
|
||||
}
|
||||
} else {
|
||||
unset($this->endpoints[$endpoint]);
|
||||
}
|
||||
}
|
||||
$this->totals['calls'] = count($methods) * $this->totals['servers'];
|
||||
|
||||
if ($this->totals['fail'] == $this->totals['calls']) {
|
||||
// assume tests have not run, skip outputing table
|
||||
print "No Data Available<br>\n";
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\n\n<b>Servers: {$this->totals['servers']} Calls: {$this->totals['calls']} Success: {$this->totals['success']} Fail: {$this->totals['fail']}</b><br>\n";
|
||||
|
||||
echo "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n";
|
||||
echo "<tr><td class=\"BLANK\">Endpoint</td>\n";
|
||||
foreach ($methods as $method) {
|
||||
$info = split(':', $method);
|
||||
echo "<td class='BLANK' valign='top'>";
|
||||
foreach ($info as $m) {
|
||||
$hi = split(',',$m);
|
||||
echo '<b>'.$hi[0]."</b><br>\n";
|
||||
if (count($hi) > 1) {
|
||||
echo " Actor=".($hi[1]?'Target':'Not Target')."<br>\n";
|
||||
echo " MustUnderstand=$hi[2]<br>\n";
|
||||
}
|
||||
}
|
||||
echo "</td>\n";
|
||||
}
|
||||
echo "</tr>\n";
|
||||
$faults = array();
|
||||
$fi = 0;
|
||||
foreach ($this->endpoints as $endpoint => $endpoint_info) {
|
||||
if (array_key_exists('wsdlURL',$endpoint_info)) {
|
||||
echo "<tr><td class=\"BLANK\"><a href=\"{$endpoint_info['wsdlURL']}\">$endpoint</a></td>\n";
|
||||
} else {
|
||||
echo "<tr><td class=\"BLANK\">$endpoint</td>\n";
|
||||
}
|
||||
foreach ($methods as $method) {
|
||||
$id = $endpoint_info['methods'][$method]['id'];
|
||||
$r = $endpoint_info['methods'][$method]['result'];
|
||||
$e = $endpoint_info['methods'][$method]['error'];
|
||||
if ($e) {
|
||||
$faults[$fi++] = $e;
|
||||
}
|
||||
if ($r) {
|
||||
echo "<td class='$r'><a href='$PHP_SELF?wire=$id'>$r</a></td>\n";
|
||||
} else {
|
||||
echo "<td class='untested'>untested</td>\n";
|
||||
}
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table><br>\n";
|
||||
if ($this->showFaults && count($faults) > 0) {
|
||||
echo "<b>ERROR Details:</b><br>\n<ul>\n";
|
||||
# output more error detail
|
||||
foreach ($faults as $fault) {
|
||||
echo '<li>'.HTMLSpecialChars($fault)."</li>\n";
|
||||
}
|
||||
}
|
||||
echo "</ul><br><br>\n";
|
||||
}
|
||||
|
||||
function outputTables() {
|
||||
// the mother of all interop tests
|
||||
$dowsdl = array(0,1);
|
||||
foreach($this->tests as $test) {
|
||||
$this->currentTest = $test;
|
||||
foreach($dowsdl as $usewsdl) {
|
||||
$this->useWSDL = $usewsdl;
|
||||
foreach($this->paramTypes as $ptype) {
|
||||
// skip a pointless test
|
||||
if ($usewsdl && $ptype == 'soapval') break;
|
||||
$this->paramType = $ptype;
|
||||
$this->outputTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showWire($id) {
|
||||
$results = $this->dbc->getAll("select * from results where id=$id",NULL, DB_FETCHMODE_ASSOC );
|
||||
#$wire = preg_replace("/>/",">\n",$results[0]['wire']);
|
||||
$wire = $results[0]['wire'];
|
||||
echo "<pre>\n".HTMLSpecialChars($wire)."</pre>\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,636 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
define('SOAP_TEST_ACTOR_NEXT','http://schemas.xmlsoap.org/soap/actor/next');
|
||||
define('SOAP_TEST_ACTOR_OTHER','http://some/other/actor');
|
||||
|
||||
class SOAP_Test {
|
||||
var $type = 'php';
|
||||
var $test_name = NULL;
|
||||
var $method_name = NULL;
|
||||
var $method_params = NULL;
|
||||
var $expect = NULL;
|
||||
var $expect_fault = FALSE;
|
||||
var $headers = NULL;
|
||||
var $headers_expect = NULL;
|
||||
var $result = array();
|
||||
var $show = 1;
|
||||
var $debug = 0;
|
||||
var $encoding = 'UTF-8';
|
||||
|
||||
function SOAP_Test($methodname, $params, $expect = NULL) {
|
||||
# XXX we have to do this to make php-soap happy with NULL params
|
||||
if (!$params) $params = array();
|
||||
|
||||
if (strchr($methodname,'(')) {
|
||||
preg_match('/(.*)\((.*)\)/',$methodname,$matches);
|
||||
$this->test_name = $methodname;
|
||||
$this->method_name = $matches[1];
|
||||
} else {
|
||||
$this->test_name = $this->method_name = $methodname;
|
||||
}
|
||||
$this->method_params = $params;
|
||||
$this->expect = $expect;
|
||||
|
||||
// determine test type
|
||||
if ($params) {
|
||||
$v = array_values($params);
|
||||
if (gettype($v[0]) == 'object' &&
|
||||
(get_class($v[0]) == 'soapvar' || get_class($v[0]) == 'soapparam'))
|
||||
$this->type = 'soapval';
|
||||
}
|
||||
}
|
||||
|
||||
function setResult($ok, $result, $wire, $error = '', $fault = NULL)
|
||||
{
|
||||
$this->result['success'] = $ok;
|
||||
$this->result['result'] = $result;
|
||||
$this->result['error'] = $error;
|
||||
$this->result['wire'] = $wire;
|
||||
$this->result['fault'] = $fault;
|
||||
}
|
||||
|
||||
/**
|
||||
* showMethodResult
|
||||
* print simple output about a methods result
|
||||
*
|
||||
* @param array endpoint_info
|
||||
* @param string method
|
||||
* @access public
|
||||
*/
|
||||
function showTestResult($debug = 0) {
|
||||
// debug output
|
||||
if ($debug) $this->show = 1;
|
||||
if ($debug) {
|
||||
echo str_repeat("-",50)."<br>\n";
|
||||
}
|
||||
|
||||
echo "testing $this->test_name : ";
|
||||
if ($this->headers) {
|
||||
foreach ($this->headers as $h) {
|
||||
if (get_class($h) == 'soap_header') {
|
||||
|
||||
echo "\n {$h->name},{$h->attributes['SOAP-ENV:actor']},{$h->attributes['SOAP-ENV:mustUnderstand']} : ";
|
||||
} else {
|
||||
if (!$h[4]) $h[4] = SOAP_TEST_ACTOR_NEXT;
|
||||
if (!$h[3]) $h[3] = 0;
|
||||
echo "\n $h[0],$h[4],$h[3] : ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print "method params: ";
|
||||
print_r($this->params);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
$ok = $this->result['success'];
|
||||
if ($ok) {
|
||||
print "SUCCESS\n";
|
||||
} else {
|
||||
$fault = $this->result['fault'];
|
||||
if ($fault) {
|
||||
print "FAILED: {$fault->faultcode} {$fault->faultstring}\n";
|
||||
} else {
|
||||
print "FAILED: ".$this->result['result']."\n";
|
||||
}
|
||||
}
|
||||
if ($debug) {
|
||||
echo "<pre>\n".htmlentities($this->result['wire'])."</pre>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# XXX I know this isn't quite right, need to deal with this better
|
||||
function make_2d($x, $y)
|
||||
{
|
||||
for ($_x = 0; $_x < $x; $_x++) {
|
||||
for ($_y = 0; $_y < $y; $_y++) {
|
||||
$a[$_x][$_y] = "x{$_x}y{$_y}";
|
||||
}
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
function soap_value($name, $value, $type) {
|
||||
return new soapparam(new soapvar($value,$type),$name);
|
||||
}
|
||||
|
||||
class SOAPStruct {
|
||||
var $varString;
|
||||
var $varInt;
|
||||
var $varFloat;
|
||||
function SOAPStruct($s, $i, $f) {
|
||||
$this->varString = $s;
|
||||
$this->varInt = $i;
|
||||
$this->varFloat = $f;
|
||||
}
|
||||
}
|
||||
|
||||
//***********************************************************
|
||||
// Base echoString
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString', array('inputString' => 'hello world!'));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString', array('inputString' => soap_value('inputString','hello world',XSD_STRING)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => ""));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString(null)', array('inputString' => soap_value('inputString','',XSD_STRING)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => 'hello world\nline 2\n'));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoString(entities)', array('inputString' => soap_value('inputString','hello world\nline 2\n',XSD_STRING)));
|
||||
$test = new SOAP_Test('echoString(utf-8)', array('inputString' => utf8_encode('ỗÈéóÒ₧⅜ỗỸ')));
|
||||
$test->encoding = 'UTF-8';
|
||||
$soap_tests['base'][] = $test;
|
||||
$test = new SOAP_Test('echoString(utf-8)', array('inputString' => soap_value('inputString',utf8_encode('ỗÈéóÒ₧⅜ỗỸ'),XSD_STRING)));
|
||||
$test->encoding = 'UTF-8';
|
||||
$soap_tests['base'][] = $test;
|
||||
|
||||
//***********************************************************
|
||||
// Base echoStringArray
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStringArray',
|
||||
array('inputStringArray' => array('good','bad')));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStringArray',
|
||||
array('inputStringArray' =>
|
||||
soap_value('inputStringArray',array('good','bad'),SOAP_ENC_ARRAY)));
|
||||
|
||||
// null array test
|
||||
# XXX NULL Arrays not supported
|
||||
#$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => NULL));
|
||||
#$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => soap_value('inputStringArray',NULL,XSD_STRING)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoInteger
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoInteger', array('inputInteger' => 34345));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoInteger', array('inputInteger' => soap_value('inputInteger',12345,XSD_INT)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoIntegerArray
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoIntegerArray', array('inputIntegerArray' => array(1,234324324,2)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoIntegerArray',
|
||||
array('inputIntegerArray' =>
|
||||
soap_value('inputIntegerArray',
|
||||
array(new soapvar(12345,XSD_INT),new soapvar(654321,XSD_INT)),
|
||||
SOAP_ENC_ARRAY)));
|
||||
#
|
||||
#// null array test
|
||||
# XXX NULL Arrays not supported
|
||||
#$soap_tests['base'][] = new SOAP_Test('echoIntegerArray(null)', array('inputIntegerArray' => NULL));
|
||||
#$soap_tests['base'][] = new SOAP_Test('echoIntegerArray(null)', array('inputIntegerArray' => new SOAP_Value('inputIntegerArray','Array',NULL)));
|
||||
#
|
||||
//***********************************************************
|
||||
// Base echoFloat
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoFloat', array('inputFloat' => 342.23));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoFloat', array('inputFloat' => soap_value('inputFloat',123.45,XSD_FLOAT)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoFloatArray
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoFloatArray', array('inputFloatArray' => array(1.3223,34.2,325.325)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoFloatArray',
|
||||
array('inputFloatArray' =>
|
||||
soap_value('inputFloatArray',
|
||||
array(new soapvar(123.45,XSD_FLOAT),new soapvar(654.321,XSD_FLOAT)),
|
||||
SOAP_ENC_ARRAY)));
|
||||
//***********************************************************
|
||||
// Base echoStruct
|
||||
|
||||
$soapstruct = new SOAPStruct('arg',34,325.325);
|
||||
# XXX no way to set a namespace!!!
|
||||
$soapsoapstruct = soap_value('inputStruct',$soapstruct,SOAP_ENC_OBJECT);
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStruct', array('inputStruct' =>$soapstruct));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStruct', array('inputStruct' =>$soapsoapstruct));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoStructArray
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStructArray', array('inputStructArray' => array(
|
||||
$soapstruct,$soapstruct,$soapstruct)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoStructArray', array('inputStructArray' =>
|
||||
soap_value('inputStructArray',array($soapstruct,$soapstruct,$soapstruct),SOAP_ENC_ARRAY)));
|
||||
|
||||
|
||||
//***********************************************************
|
||||
// Base echoVoid
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoVoid', NULL);
|
||||
$test = new SOAP_Test('echoVoid', NULL);
|
||||
$test->type = 'soapval';
|
||||
$soap_tests['base'][] = $test;
|
||||
|
||||
//***********************************************************
|
||||
// Base echoBase64
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBase64', array('inputBase64' => 'TmVicmFza2E='));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBase64', array('inputBase64' =>
|
||||
soap_value('inputBase64','TmVicmFza2E=',XSD_BASE64BINARY)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoHexBinary
|
||||
|
||||
$soap_tests['base'][] = new SOAP_Test('echoHexBinary', array('inputHexBinary' => '736F61707834'));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoHexBinary', array('inputHexBinary' =>
|
||||
soap_value('inputHexBinary','736F61707834',XSD_HEXBINARY)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoDecimal
|
||||
|
||||
# XXX test fails because php-soap incorrectly sets decimal to long rather than float
|
||||
$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' => 12345.67890));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoDecimal', array('inputDecimal' =>
|
||||
soap_value('inputDecimal',12345.67890,XSD_DECIMAL)));
|
||||
|
||||
//***********************************************************
|
||||
// Base echoDate
|
||||
|
||||
# php-soap doesn't handle datetime types properly yet
|
||||
$soap_tests['base'][] = new SOAP_Test('echoDate', array('inputDate' => '2001-05-24T17:31:41Z'));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoDate', array('inputDate' =>
|
||||
soap_value('inputDate','2001-05-24T17:31:41Z',XSD_DATETIME)));#'2001-04-25T13:31:41-0700'
|
||||
|
||||
//***********************************************************
|
||||
// Base echoBoolean
|
||||
|
||||
# php-soap sends boolean as zero or one, which is ok, but to be explicit, send true or false.
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => TRUE));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' =>
|
||||
soap_value('inputBoolean',TRUE,XSD_BOOLEAN)));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' => FALSE));
|
||||
$soap_tests['base'][] = new SOAP_Test('echoBoolean', array('inputBoolean' =>
|
||||
soap_value('inputBoolean',FALSE,XSD_BOOLEAN)));
|
||||
|
||||
#
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GROUP B
|
||||
#
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GroupB echoStructAsSimpleTypes
|
||||
#
|
||||
#$expect = array(
|
||||
# 'outputString'=>'arg',
|
||||
# 'outputInteger'=>34,
|
||||
# 'outputFloat'=>325.325
|
||||
# );
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes',
|
||||
# array('inputStruct' => array(
|
||||
# 'varString'=>'arg',
|
||||
# 'varInt'=>34,
|
||||
# 'varFloat'=>325.325
|
||||
# )), $expect);
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoStructAsSimpleTypes',
|
||||
# array('inputStruct' =>
|
||||
# new SOAP_Value('inputStruct','SOAPStruct',
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# ))), $expect);
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GroupB echoSimpleTypesAsStruct
|
||||
#
|
||||
#$expect =
|
||||
# array(
|
||||
# 'varString'=>'arg',
|
||||
# 'varInt'=>34,
|
||||
# 'varFloat'=>325.325
|
||||
# );
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct',
|
||||
# array(
|
||||
# 'inputString'=>'arg',
|
||||
# 'inputInteger'=>34,
|
||||
# 'inputFloat'=>325.325
|
||||
# ), $expect);
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoSimpleTypesAsStruct',
|
||||
# array(
|
||||
# new SOAP_Value('inputString','string','arg'),
|
||||
# new SOAP_Value('inputInteger','int',34),
|
||||
# new SOAP_Value('inputFloat','float',325.325)
|
||||
# ), $expect);
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GroupB echo2DStringArray
|
||||
#
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray',
|
||||
# array('input2DStringArray' => make_2d(3,3)));
|
||||
#
|
||||
#$multidimarray =
|
||||
# new SOAP_Value('input2DStringArray','Array',
|
||||
# array(
|
||||
# array(
|
||||
# new SOAP_Value('item','string','row0col0'),
|
||||
# new SOAP_Value('item','string','row0col1'),
|
||||
# new SOAP_Value('item','string','row0col2')
|
||||
# ),
|
||||
# array(
|
||||
# new SOAP_Value('item','string','row1col0'),
|
||||
# new SOAP_Value('item','string','row1col1'),
|
||||
# new SOAP_Value('item','string','row1col2')
|
||||
# )
|
||||
# )
|
||||
# );
|
||||
#$multidimarray->options['flatten'] = TRUE;
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echo2DStringArray',
|
||||
# array('input2DStringArray' => $multidimarray));
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GroupB echoNestedStruct
|
||||
#
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct',
|
||||
# array('inputStruct' => array(
|
||||
# 'varString'=>'arg',
|
||||
# 'varInt'=>34,
|
||||
# 'varFloat'=>325.325,
|
||||
# 'varStruct' => array(
|
||||
# 'varString'=>'arg',
|
||||
# 'varInt'=>34,
|
||||
# 'varFloat'=>325.325
|
||||
# )
|
||||
# )));
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct',
|
||||
# array('inputStruct' =>
|
||||
# new SOAP_Value('inputStruct','struct',
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325),
|
||||
# new SOAP_Value('varStruct','SOAPStruct',
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# )
|
||||
# /*,NULL,'http://soapinterop.org/xsd'*/)
|
||||
# )
|
||||
# )));
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GroupB echoNestedArray
|
||||
#
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray',
|
||||
# array('inputStruct' => array(
|
||||
# 'varString'=>'arg',
|
||||
# 'varInt'=>34,
|
||||
# 'varFloat'=>325.325,
|
||||
# 'varArray' => array('red','blue','green')
|
||||
# )));
|
||||
#$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray',
|
||||
# array('inputStruct' =>
|
||||
# new SOAP_Value('inputStruct','struct',
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325),
|
||||
# new SOAP_Value('varArray','Array',
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('item','string','red'),
|
||||
# new SOAP_Value('item','string','blue'),
|
||||
# new SOAP_Value('item','string','green')
|
||||
# )
|
||||
# )
|
||||
# )
|
||||
# )));
|
||||
#
|
||||
#
|
||||
#//***********************************************************
|
||||
#// GROUP C header tests
|
||||
#
|
||||
#//***********************************************************
|
||||
#// echoMeStringRequest php val tests
|
||||
#
|
||||
#// echoMeStringRequest with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'hello world', 0,SOAP_TEST_ACTOR_NEXT);
|
||||
#$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>'hello world');
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'hello world', 1,SOAP_TEST_ACTOR_NEXT);
|
||||
#$this->type = 'soapval'; // force a soapval version of this test
|
||||
#$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>'hello world');
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'hello world', 0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStringRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'hello world', 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStringRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#//***********************************************************
|
||||
#// echoMeStringRequest soapval tests
|
||||
#
|
||||
#// echoMeStringRequest with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', 'hello world');
|
||||
#$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>'hello world');
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', 'hello world', 1);
|
||||
#$this->type = 'soapval'; // force a soapval version of this test
|
||||
#$test->headers_expect['echoMeStringRequest'] = array('echoMeStringResponse'=>'hello world');
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', 'hello world', 0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStringRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStringRequest', 'string', 'hello world', 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStringRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStringRequest with endpoint header destination, must understand,
|
||||
#// invalid namespace, should recieve a fault
|
||||
##$test = new SOAP_Test('echoVoid', NULL);
|
||||
##$test->type = 'soapval';
|
||||
##$test->headers[] = new SOAP_Header('{http://unknown.org/echoheader/}echoMeStringRequest', 'string', 'hello world', 1);
|
||||
##$test->headers_expect['echoMeStringRequest'] = array();
|
||||
##$test->expect_fault = TRUE;
|
||||
##$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#//***********************************************************
|
||||
#// php val tests
|
||||
#// echoMeStructRequest with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStructRequest',
|
||||
# array('varString'=>'arg', 'varInt'=>34, 'varFloat'=>325.325),
|
||||
# 0,SOAP_TEST_ACTOR_NEXT);
|
||||
#$test->headers_expect['echoMeStructRequest'] =
|
||||
# array('echoMeStructResponse'=> array('varString'=>'arg','varInt'=>34,'varFloat'=>325.325));
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStructRequest',
|
||||
# array('varString'=>'arg', 'varInt'=>34, 'varFloat'=>325.325),
|
||||
# 1,SOAP_TEST_ACTOR_NEXT);
|
||||
#$test->headers_expect['echoMeStructRequest'] =
|
||||
# array('echoMeStructResponse'=> array('varString'=>'arg','varInt'=>34,'varFloat'=>325.325));
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStructRequest',
|
||||
# array('varString'=>'arg', 'varInt'=>34, 'varFloat'=>325.325),
|
||||
# 0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStructRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeStructRequest',
|
||||
# array('varString'=>'arg', 'varInt'=>34, 'varFloat'=>325.325),
|
||||
# 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStructRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#//***********************************************************
|
||||
#// soapval tests
|
||||
#// echoMeStructRequest with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStructRequest',NULL,
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# ));
|
||||
#$test->headers_expect['echoMeStructRequest'] =
|
||||
# array('echoMeStructResponse'=> array('varString'=>'arg','varInt'=>34,'varFloat'=>325.325));
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStructRequest',NULL,
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# ), 1);
|
||||
#$test->headers_expect['echoMeStructRequest'] =
|
||||
# array('echoMeStructResponse'=> array('varString'=>'arg','varInt'=>34,'varFloat'=>325.325));
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStructRequest',NULL,
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# ), 0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStructRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeStructRequest with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeStructRequest',NULL,
|
||||
# array( #push struct elements into one soap value
|
||||
# new SOAP_Value('varString','string','arg'),
|
||||
# new SOAP_Value('varInt','int',34),
|
||||
# new SOAP_Value('varFloat','float',325.325)
|
||||
# ), 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeStructRequest'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#//***********************************************************
|
||||
#// echoMeUnknown php val tests
|
||||
#// echoMeUnknown with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', 'nobody understands me!',0,SOAP_TEST_ACTOR_NEXT);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', 'nobody understands me!',1,SOAP_TEST_ACTOR_NEXT);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$test->expect_fault = TRUE;
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', 'nobody understands me!',0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->headers[] = array('{http://soapinterop.org/echoheader/}echoMeUnknown', 'nobody understands me!', 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#//***********************************************************
|
||||
#// echoMeUnknown soapval tests
|
||||
#// echoMeUnknown with endpoint as header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string','nobody understands me!');
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint as header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string','nobody understands me!',1);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$test->expect_fault = TRUE;
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint NOT header destination, doesn't have to understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string','nobody understands me!', 0, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
#
|
||||
#// echoMeUnknown with endpoint NOT header destination, must understand
|
||||
#$test = new SOAP_Test('echoVoid', NULL);
|
||||
#$test->type = 'soapval';
|
||||
#$test->headers[] = new SOAP_Header('{http://soapinterop.org/echoheader/}echoMeUnknown','string','nobody understands me!', 1, SOAP_TEST_ACTOR_OTHER);
|
||||
#$test->headers_expect['echoMeUnknown'] = array();
|
||||
#$soap_tests['GroupC'][] = $test;
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
// NOTE: do not run this directly under a web server, as it will take a very long
|
||||
// time to execute. Run from a command line or something, and redirect output
|
||||
// to an html file.
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
require_once 'client_round2_interop.php';
|
||||
?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
TD { background-color: Red; }
|
||||
TD.BLANK { background-color: White; }
|
||||
TD.OK { background-color: Lime; }
|
||||
TD.RESULT { background-color: Green; }
|
||||
TD.untested { background-color: White; }
|
||||
TD.CONNECT { background-color: Yellow; }
|
||||
TD.TRANSPORT { background-color: Yellow; }
|
||||
TD.WSDL { background-color: Yellow; }
|
||||
TD.WSDLCACHE { background-color: Yellow; }
|
||||
TD.WSDLPARSER { background-color: Yellow; }
|
||||
TD.HTTP { background-color: Yellow; }
|
||||
TD.SMTP { background-color: Yellow; }
|
||||
</style>
|
||||
<title>PEAR-PHP SOAP Interop Tests</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="White" text="Black">
|
||||
<h2 align="center">SOAP Client Interop Test Results: Round2</h2>
|
||||
|
||||
<a href="index.php">Back to Interop Index</a><br>
|
||||
<p> </p>
|
||||
|
||||
<?php
|
||||
$iop = new Interop_Client();
|
||||
|
||||
if ($_GET['detail'] == 1) $iop->showFaults = 1;
|
||||
|
||||
if ($_GET['wire']) {
|
||||
$iop->showWire($_GET['wire']);
|
||||
} else {
|
||||
$iop->getEndpoints();
|
||||
$iop->getResults();
|
||||
|
||||
if ($_GET['test']) {
|
||||
$iop->currentTest = $_GET['test'];
|
||||
$iop->useWSDL = $_GET['wsdl']?$_GET['wsdl']:0;
|
||||
$iop->paramType = $_GET['type']?$_GET['type']:'php';
|
||||
$iop->outputTable();
|
||||
} else {
|
||||
$iop->outputTables();
|
||||
}
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
// this script is usefull for quickly testing stuff, use the 'pretty' file for html output
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
set_time_limit(0);
|
||||
require_once 'client_round2_interop.php';
|
||||
|
||||
$iop = new Interop_Client();
|
||||
// force a fetch of endpoints, this happens irregardless if no endpoints in database
|
||||
#$iop->fetchEndpoints();
|
||||
|
||||
// set some options
|
||||
$iop->currentTest = 'base'; // see $tests above
|
||||
$iop->paramType = 'php'; // 'php' or 'soapval'
|
||||
$iop->useWSDL = 1; // 1= do wsdl tests
|
||||
$iop->numServers = 0; // 0 = all
|
||||
$iop->specificEndpoint = '4s4c'; // test only this endpoint
|
||||
$iop->testMethod = 'echoString'; // test only this method
|
||||
|
||||
#XXX MS SOAP ToolKit 2.0/3.0 crashes php-soap in __getfault!
|
||||
|
||||
// endpoints to skip
|
||||
$iop->skipEndpointList = array('Apache Axis','IONA XMLBus','IONA XMLBus (CORBA)','MS SOAP ToolKit 2.0','MS SOAP ToolKit 3.0','Spheon JSOAP','SQLData SOAP Server','WASP Advanced 3.0');
|
||||
$iop->startAt='';
|
||||
$this->nosave = 0; // 1= disable saving results to database
|
||||
// debug output
|
||||
$iop->show = 1;
|
||||
$iop->debug = 0;
|
||||
$iop->showFaults = 0; // used in result table output
|
||||
|
||||
$iop->doTest(); // run a single set of tests using above options
|
||||
#$iop->doGroupTests(); // run a group of tests set in $currentTest
|
||||
#$iop->doTests(); // run all tests, ignore above options
|
||||
#$iop->outputTables();
|
||||
echo "done";
|
||||
|
||||
?>
|
||||
@@ -1,45 +0,0 @@
|
||||
# phpMyAdmin MySQL-Dump
|
||||
# version 2.2.5
|
||||
# http://phpwizard.net/phpMyAdmin/
|
||||
# http://phpmyadmin.sourceforge.net/ (download page)
|
||||
#
|
||||
# Host: localhost
|
||||
# Generation Time: Apr 08, 2002 at 08:32 PM
|
||||
# Server version: 3.23.49
|
||||
# PHP Version: 4.1.1
|
||||
# Database : `interop`
|
||||
# --------------------------------------------------------
|
||||
|
||||
#
|
||||
# Table structure for table `endpoints`
|
||||
#
|
||||
|
||||
CREATE TABLE endpoints (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
endpointName varchar(50) NOT NULL default '',
|
||||
endpointURL varchar(255) NOT NULL default '',
|
||||
wsdlURL varchar(255) NOT NULL default '',
|
||||
class varchar(20) NOT NULL default '',
|
||||
status int(11) NOT NULL default '1',
|
||||
PRIMARY KEY (id)
|
||||
) TYPE=MyISAM;
|
||||
# --------------------------------------------------------
|
||||
|
||||
#
|
||||
# Table structure for table `results`
|
||||
#
|
||||
|
||||
CREATE TABLE results (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
endpoint int(11) NOT NULL default '0',
|
||||
stamp int(11) NOT NULL default '0',
|
||||
class varchar(10) NOT NULL default '',
|
||||
type varchar(10) default NULL,
|
||||
wsdl int(11) NOT NULL default '0',
|
||||
function varchar(255) NOT NULL default '',
|
||||
result varchar(25) NOT NULL default '',
|
||||
error text,
|
||||
wire text NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) TYPE=MyISAM;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<definitions name="InteropTest" targetNamespace="http://soapinterop.org/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/" xmlns:s="http://soapinterop.org/xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
|
||||
|
||||
<import location="http://www.whitemesa.com/interop/InteropTest.wsdl" namespace="http://soapinterop.org/"/>
|
||||
<import location="http://www.whitemesa.com/interop/InteropTest.wsdl" namespace="http://soapinterop.org/xsd"/>
|
||||
<import location="http://www.whitemesa.com/interop/InteropTestC.wsdl" namespace="http://soapinterop.org/"/>
|
||||
|
||||
<service name="interopLabEchoHeader">
|
||||
|
||||
<port name="interopPortEchoHdr" binding="tns:InteropEchoHeaderBinding">
|
||||
<soap:address location="http://localhost/soap_interop/server_round2.php"/>
|
||||
</port>
|
||||
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
@@ -1,85 +0,0 @@
|
||||
# phpMyAdmin MySQL-Dump
|
||||
# version 2.2.5
|
||||
# http://phpwizard.net/phpMyAdmin/
|
||||
# http://phpmyadmin.sourceforge.net/ (download page)
|
||||
#
|
||||
# Host: localhost
|
||||
# Generation Time: Jul 14, 2002 at 03:13 PM
|
||||
# Server version: 3.23.49
|
||||
# PHP Version: 4.2.1
|
||||
# Database : `interop2`
|
||||
|
||||
#
|
||||
# Dumping data for table `endpoints`
|
||||
#
|
||||
|
||||
INSERT INTO endpoints VALUES (1, '4s4c', 'http://soap.4s4c.com/ilab/soap.asp', 'http://www.pocketsoap.com/services/ilab.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (2, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (3, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (4, 'Apache SOAP 2.2', 'http://nagoya.apache.org:5049/soap/servlet/rpcrouter', 'http://www.apache.org/~rubys/ApacheSoap.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (5, 'ASP.NET Web Services', 'http://www.mssoapinterop.org/asmx/simple.asmx', 'http://www.mssoapinterop.org/asmx/simple.asmx?wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (6, 'CapeConnect', 'http://interop.capeclear.com/ccx/soapbuilders-round2', 'http://interop.capeclear.com/wsdl/soapbuilders-round2.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (7, 'Delphi SOAP', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropService.exe/soap/InteropTestPortType', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropService.exe/wsdl/InteropTestPortType', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (8, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopA.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (9, 'eSOAP', 'http://www.quakersoft.net/cgi-bin/interop2_server.cgi', 'http://www.quakersoft.net/wsdl/interop2.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (10, 'gSOAP', 'http://websrv.cs.fsu.edu/~engelen/interop2.cgi', 'http://www.cs.fsu.edu/~engelen/interop2.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (11, 'Frontier', 'http://www.soapware.org/xmethodsInterop', '', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (12, 'GLUE', 'http://www.themindelectric.net:8005/glue/round2', 'http://www.themindelectric.net:8005/glue/round2.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (13, 'HP SOAP', 'http://soap.bluestone.com/hpws/soap/EchoService', 'http://soap.bluestone.com/hpws/soap/EchoService.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (14, 'IONA XMLBus', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/BaseService/BasePort', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/BaseService/BasePort', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (15, 'IONA XMLBus (CORBA)', 'http://interop.xmlbus.com:7002/xmlbus/container/CORBAInterop/BaseService/BasePort', 'http://interop.xmlbus.com:7002/xmlbus/container/CORBAInterop/BaseService/BasePort', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (16, 'kSOAP', 'http://kissen.cs.uni-dortmund.de:8080/ksoapinterop', 'http://www.whitemesa.com/interop/kSOAP.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (17, 'MS .NET Remoting', 'http://www.mssoapinterop.org/remoting/ServiceA.soap', 'http://www.mssoapinterop.org/remoting/ServiceA.soap?wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (18, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/Interop.wsdl', 'http://mssoapinterop.org/stk/Interop.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (19, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/Interop.wsdl', 'http://mssoapinterop.org/stkV3/Interop.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (20, 'NuSOAP', 'http://dietrich.ganx4.com/nusoap/testbed/round2_base_server.php', 'http://dietrich.ganx4.com/nusoap/testbed/round2_base.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (21, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (24, 'SIM', 'http://soapinterop.simdb.com/round2', 'http://soapinterop.simdb.com/round2?WSDL', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (25, 'SOAP4R', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/SOAP4R_SOAPBuildersInteropTest_R2base.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (26, 'SOAP:Lite', 'http://services.soaplite.com/interop.cgi', 'http://services.soaplite.com/interop2.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (27, 'Spheon JSOAP', 'http://213.23.125.181:8081/RPC', 'http://213.23.125.181:8081/interop.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (28, 'Spray 2001', 'http://www.dolphinharbor.org/services/interop2001', 'http://www.dolphinharbor.org/services/interop2001/service.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (29, 'SQLData SOAP Server', 'http://soapclient.com/interop/sqldatainterop.wsdl', 'http://soapclient.com/interop/sqldatainterop.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (30, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropService/', 'http://soap.systinet.net:6060/InteropService/', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (32, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std', 'http://www.whitemesa.net/wsdl/std/interop.wsdl', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (33, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/interop.wsdl.php', 'base', 1);
|
||||
INSERT INTO endpoints VALUES (34, '4s4c', 'http://soap.4s4c.com/ilab/soap.asp', 'http://www.pocketsoap.com/services/ilab_b.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (35, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab_b.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (36, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (37, 'ASP.NET Web Services', 'http://www.mssoapinterop.org/asmx/simpleB.asmx', 'http://www.mssoapinterop.org/asmx/simpleb.asmx?wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (38, 'Delphi SOAP', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropGroupB.exe/soap/InteropTestPortTypeB', 'http://soap-server.borland.com/WebServices/Interop/cgi-bin/InteropGroupB.exe/wsdl/InteropTestPortTypeB', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (39, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (40, 'GLUE', 'http://www.themindelectric.net:8005/glue/round2B', 'http://www.themindelectric.net:8005/glue/round2B.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (41, 'gSOAP', 'http://websrv.cs.fsu.edu/~engelen/interop2B.cgi', 'http://www.cs.fsu.edu/~engelen/interop2B.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (42, 'HP SOAP', 'http://soap.bluestone.com/hpws/soap/EchoService', 'http://soap.bluestone.com/hpws/soap/EchoService.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (43, 'IONA XMLBus', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/GroupBService/GroupBPort', 'http://interop.xmlbus.com:7002/xmlbus/container/InteropTest/GroupBService/GroupBPort', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (44, 'MS .NET Remoting', 'http://www.mssoapinterop.org/remoting/ServiceB.soap', 'http://www.mssoapinterop.org/remoting/ServiceB.soap?wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (45, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/InteropBtyped.wsdl', 'http://mssoapinterop.org/stk/InteropBtyped.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (46, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/InteropB.wsdl', 'http://mssoapinterop.org/stkV3/InteropB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (47, 'NuSOAP', 'http://dietrich.ganx4.com/nusoap/testbed/round2_groupb_server.php', 'http://dietrich.ganx4.com/nusoap/testbed/round2_groupb.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (48, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (50, 'SIM', 'http://soapinterop.simdb.com/round2B', 'http://soapinterop.simdb.com/round2B?WSDL', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (51, 'SOAP4R', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/', 'http://www.jin.gr.jp/~nahi/Ruby/SOAP4R/SOAPBuildersInterop/SOAP4R_SOAPBuildersInteropTest_R2GroupB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (52, 'SOAP:Lite', 'http://services.soaplite.com/interop.cgi', 'http://services.soaplite.com/InteropTestB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (53, 'Spheon JSOAP', 'http://213.23.125.181:8081/RPC', 'http://213.23.125.181:8081/interopb.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (54, 'Spray 2001', 'http://www.dolphinharbor.org/services/interopB2001', 'http://www.dolphinharbor.org/services/interopB2001/service.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (55, 'SQLData SOAP Server', 'http://soapclient.com/interop/InteropB.wsdl', 'http://soapclient.com/interop/InteropB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (56, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropBService/', 'http://soap.systinet.net:6060/InteropBService/', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (58, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std/groupB', 'http://www.whitemesa.net/wsdl/std/interopB.wsdl', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (59, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/interopB.wsdl.php', 'GroupB', 1);
|
||||
INSERT INTO endpoints VALUES (60, '4s4c v2.0', 'http://soap.4s4c.com/ilab2/soap.asp', 'http://soap.4s4c.com/ilab2/ilab_c.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (61, 'Apache Axis', 'http://nagoya.apache.org:5049/axis/services/echo', 'http://nagoya.apache.org:5049/axis/services/echo?wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (62, 'ASP.NET Web Services', 'http://mssoapinterop.org/asmx/header.asmx', 'http://mssoapinterop.org/asmx/header.asmx?wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (63, 'EasySoap++', 'http://easysoap.sourceforge.net/cgi-bin/interopserver', 'http://easysoap.sourceforge.net/interopC.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (64, 'MS SOAP ToolKit 2.0', 'http://mssoapinterop.org/stk/InteropC.wsdl', 'http://mssoapinterop.org/stk/InteropC.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (65, 'MS SOAP ToolKit 3.0', 'http://mssoapinterop.org/stkV3/InteropC.wsdl', 'http://mssoapinterop.org/stkV3/InteropC.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (66, 'OpenLink', 'http://demo.openlinksw.com:8890/Interop', 'http://demo.openlinksw.com:8890/Interop/services.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (67, 'SOAP:Lite', 'http://services.soaplite.com/interopC.cgi', 'http://services.soaplite.com/InteropTestC.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (68, 'Spray 2001', 'http://www.dolphinharbor.org/services/interopC', 'http://www.dolphinharbor.org/services/interopC/service.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (69, 'SQLData SOAP Server', 'http://soapclient.com/interop/interopC.wsdl', 'http://soapclient.com/interop/interopC.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (70, 'WASP Advanced 3.0', 'http://soap.systinet.net:6060/InteropCService/', 'http://soap.systinet.net:6060/InteropCService/', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (71, 'White Mesa SOAP Server', 'http://www.whitemesa.net/interop/std/echohdr', 'http://www.whitemesa.net/wsdl/std/echoheadersvc.wsdl', 'GroupC', 1);
|
||||
INSERT INTO endpoints VALUES (72, 'PEAR SOAP', 'http://localhost/soap_interop/server_round2.php', 'http://localhost/soap_interop/echoheadersvc.wsdl.php', 'GroupC', 1);
|
||||
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>PEAR SOAP Interop</title>
|
||||
</head>
|
||||
<?php
|
||||
// get our endpoint
|
||||
$server = $_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'];
|
||||
$endpoint = 'http://'.$server."/soap_interop/server_round2.php";
|
||||
$base = 'http://'.$server."/soap_interop/interop.wsdl";
|
||||
$groupb = 'http://'.$server."/soap_interop/interopB.wsdl";
|
||||
$groupc = 'http://'.$server."/soap_interop/echoheadersvc.wsdl";
|
||||
?>
|
||||
<body>
|
||||
|
||||
<h2 align='center'>PEAR SOAP Interop</h2>
|
||||
<p>Welcome to the PEAR SOAP Interop pages. These pages are set up for
|
||||
SOAP Builder interop tests. You can find out more about the interop tests
|
||||
at <a href="http://www.whitemesa.com/interop.htm">White Mesa</a>.</p>
|
||||
<p>Currently Round 2 base, Group B and Group C interop tests are enabled.</p>
|
||||
|
||||
<h3>Round 2 Interop Server</h3>
|
||||
Endpoint: <?php echo $endpoint; ?><br>
|
||||
Base WSDL: <a href="<?php echo $base ?>"><?php echo $base ?></a><br>
|
||||
Group B WSDL: <a href="<?php echo $groupb ?>"><?php echo $groupb ?></a><br>
|
||||
Group C WSDL: <a href="<?php echo $groupc ?>"><?php echo $groupc ?></a><br>
|
||||
|
||||
<h3>Interop Client</h3>
|
||||
|
||||
<p>
|
||||
Notes:
|
||||
Tests are done both "Direct" and with "WSDL". WSDL tests use the supplied interop WSDL
|
||||
to run the tests against. The Direct method uses an internal prebuilt list of methods and parameters
|
||||
for the test.</p>
|
||||
<p>
|
||||
Tests are also run against two methods of generating method parameters. The first, 'php', attempts
|
||||
to directly serialize PHP variables into soap values. The second method, 'soapval', uses a SOAP_Value
|
||||
class to define what the type of the value is. The second method is more interopable than the first
|
||||
by nature.
|
||||
</p>
|
||||
|
||||
<h3>Client Test Interface</h3>
|
||||
<p>The <a href="client_round2.php">client interface</a> allows you to run the PEAR SOAP
|
||||
Client against a choosen interop server. Each run updates the results database below.</p>
|
||||
|
||||
<h3>Interop Client Test Results</h3>
|
||||
<p>This is a database of the current test results using PEAR SOAP Clients against interop servers.</p>
|
||||
<p>
|
||||
More detail (wire) about errors (marked yellow or red) can be obtained by clicking on the
|
||||
link in the result box. If we have an HTTP error
|
||||
attempting to connect to the endpoint, we will mark all consecutive attempts as errors, and skip
|
||||
testing that endpoint. This reduces the time it takes to run the tests if a server is unavailable.
|
||||
WSDLCACHE errors mean we cannot retreive the WSDL file specified for the endpoint.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="client_round2_results.php?test=base&type=php&wsdl=0">Base results using PHP native types</a></li>
|
||||
<li><a href="client_round2_results.php?test=base&type=soapval&wsdl=0">Base results using SOAP types</a></li>
|
||||
<li><a href="client_round2_results.php?test=base&type=php&wsdl=1">Base results using PHP native types with WSDL</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupB&type=php&wsdl=0">Group B results using PHP native types</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupB&type=soapval&wsdl=0">Group B results using SOAP types</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupB&type=php&wsdl=1">Group B results using PHP native types with WSDL</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupC&type=php&wsdl=0">Group C results using PHP native types</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupC&type=soapval&wsdl=0">Group C results using SOAP types</a></li>
|
||||
<li><a href="client_round2_results.php?test=GroupC&type=php&wsdl=1">Group C results using PHP native types with WSDL</a></li>
|
||||
<li><a href="client_round2_results.php">Show All Results</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
<?php phpinfo(); ?>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<definitions name="InteropTest" targetNamespace="http://soapinterop.org/"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:tns="http://soapinterop.org/">
|
||||
|
||||
<import location="http://www.whitemesa.com/wsdl/wmmsgrouter.xsd" namespace="http://whitemesa.com/headers/soapmsgrouter.xsd"/>
|
||||
<import location="http://www.whitemesa.com/interop/InteropTest.wsdl" namespace="http://soapinterop.org/"/>
|
||||
<import location="http://www.whitemesa.com/interop/InteropTest.wsdl" namespace="http://soapinterop.org/xsd"/>
|
||||
|
||||
<service name="interopLab">
|
||||
<port name="interopTestPort" binding="tns:InteropTestSoapBinding">
|
||||
<soap:address location="http://localhost/soap_interop/server_round2.php"/>
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<definitions name="InteropTest" targetNamespace="http://soapinterop.org/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/" xmlns:s="http://soapinterop.org/xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
|
||||
|
||||
<import location="http://www.whitemesa.com/interop/InteropTestB.wsdl" namespace="http://soapinterop.org/"/>
|
||||
<import location="http://www.whitemesa.com/interop/InteropTestB.wsdl" namespace="http://soapinterop.org/xsd"/>
|
||||
|
||||
<service name="interopLabB">
|
||||
<port name="interopTestPortB" binding="tns:InteropTestSoapBindingB">
|
||||
<soap:address location="http://localhost/soap_interop/server_round2.php"/>
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'SOAP/Server.php';
|
||||
|
||||
$server = new SOAP_Server;
|
||||
|
||||
require_once 'server_round2_base.php';
|
||||
require_once 'server_round2_groupB.php';
|
||||
require_once 'server_round2_groupC.php';
|
||||
|
||||
$server->service(isset($HTTP_RAW_POST_DATA)?$HTTP_RAW_POST_DATA:NULL);
|
||||
#echo "Content-Length is {$_SERVER['CONTENT_LENGTH']}\n\n";
|
||||
#echo "<!---\n\nlen:".strlen($HTTP_RAW_POST_DATA)."\n\n";
|
||||
#echo "[$HTTP_RAW_POST_DATA";
|
||||
#print "]\n\nend of input data-->";
|
||||
?>
|
||||
@@ -1,184 +0,0 @@
|
||||
<?
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more |
|
||||
// | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
require_once 'SOAP/Server.php';
|
||||
|
||||
function generateFault($short, $long)
|
||||
{
|
||||
$params = array(
|
||||
"faultcode" => "Server",
|
||||
"faultstring" => $short,
|
||||
"detail" => $long
|
||||
);
|
||||
|
||||
$faultmsg = new SOAP_Message("Fault",$params,"http://schemas.xmlsoap.org/soap/envelope/");
|
||||
return $faultmsg;
|
||||
}
|
||||
|
||||
function hex2bin($data)
|
||||
{
|
||||
$len = strlen($data);
|
||||
return pack("H" . $len, $data);
|
||||
}
|
||||
|
||||
|
||||
class SOAP_Interop_Base {
|
||||
var $method_namespace = 'http://soapinterop.org/';
|
||||
|
||||
function SOAP_Interop_Base() {
|
||||
#if ($server) {
|
||||
# $server->addToMap("echoString",array("string"),array("string"));
|
||||
# $server->addToMap("echoStringArray",array(),array());
|
||||
# $server->addToMap("echoInteger",array("int"),array("int"));
|
||||
# $server->addToMap("echoIntegerArray",array(),array());
|
||||
# $server->addToMap("echoFloat",array("float"),array("float"));
|
||||
# $server->addToMap("echoFloatArray",array(),array());
|
||||
# $server->addToMap("echoStruct",array(),array());
|
||||
# $server->addToMap("echoStructArray",array(),array());
|
||||
# $server->addToMap("echoVoid",array(),array());
|
||||
# $server->addToMap("echoBase64",array("base64Binary"),array("base64Binary"));
|
||||
# $server->addToMap("echoDate",array("dateTime"),array("dateTime"));
|
||||
# $server->addToMap("echoHexBinary",array("hexBinary"),array("hexBinary"));
|
||||
# $server->addToMap("echoDecimal",array("decimal"),array("decimal"));
|
||||
# $server->addToMap("echoBoolean",array("boolean"),array("boolean"));
|
||||
#}
|
||||
}
|
||||
|
||||
function echoString($inputString)
|
||||
{
|
||||
return new SOAP_Value('outputString','string',$inputString);
|
||||
}
|
||||
|
||||
function echoStringArray($inputStringArray)
|
||||
{
|
||||
$ra = array();
|
||||
if ($inputStringArray) {
|
||||
foreach($inputStringArray as $s) {
|
||||
$ra[] = new SOAP_Value('item','string',$s);
|
||||
}
|
||||
}
|
||||
return new SOAP_Value('outputStringArray',NULL,$ra);
|
||||
}
|
||||
|
||||
|
||||
function echoInteger($inputInteger)
|
||||
{
|
||||
return new SOAP_Value('outputInteger','int',(integer)$inputInteger);
|
||||
}
|
||||
|
||||
function echoIntegerArray($inputIntegerArray)
|
||||
{
|
||||
$ra = array();
|
||||
if ($inputIntegerArray) {
|
||||
foreach ($inputIntegerArray as $i) {
|
||||
$ra[] = new SOAP_Value('item','int',$i);
|
||||
}
|
||||
}
|
||||
return new SOAP_Value('outputIntArray',NULL,$ra);
|
||||
}
|
||||
|
||||
function echoFloat($inputFloat)
|
||||
{
|
||||
return new SOAP_Value('outputFloat','float',(FLOAT)$inputFloat);
|
||||
}
|
||||
|
||||
function echoFloatArray($inputFloatArray)
|
||||
{
|
||||
$ra = array();
|
||||
if ($inputFloatArray) {
|
||||
foreach($inputFloatArray as $float) {
|
||||
$ra[] = new SOAP_Value('item','float',(FLOAT)$float);
|
||||
}
|
||||
}
|
||||
return new SOAP_Value('outputFloatArray',NULL,$ra);
|
||||
}
|
||||
|
||||
function echoStruct($inputStruct)
|
||||
{
|
||||
return new SOAP_Value('return','{http://soapinterop.org/xsd}SOAPStruct',
|
||||
array(
|
||||
new SOAP_Value('varInt','int',$inputStruct['varInt']),
|
||||
new SOAP_Value('varFloat','float',$inputStruct['varFloat']),
|
||||
new SOAP_Value('varString','string',$inputStruct['varString'])
|
||||
));
|
||||
}
|
||||
|
||||
function echoStructArray($inputStructArray)
|
||||
{
|
||||
$ra = array();
|
||||
if ($inputStructArray) {
|
||||
foreach($inputStructArray as $struct) {
|
||||
$ra[] = new SOAP_Value('item','{http://soapinterop.org/xsd}SOAPStruct',
|
||||
array(
|
||||
new SOAP_Value('varInt','int',$struct['varInt']),
|
||||
new SOAP_Value('varFloat','float',$struct['varFloat']),
|
||||
new SOAP_Value('varString','string',$struct['varString'])
|
||||
));
|
||||
}
|
||||
}
|
||||
return $ra;
|
||||
}
|
||||
|
||||
function echoVoid()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function echoBase64($b_encoded)
|
||||
{
|
||||
return new SOAP_Value('return','base64Binary',base64_encode(base64_decode($b_encoded)));
|
||||
}
|
||||
|
||||
function echoDate($timeInstant)
|
||||
{
|
||||
$dt = new SOAP_Type_dateTime($timeInstant);
|
||||
if ($dt->toUnixtime() != -1) {
|
||||
$value = $dt->toSOAP();
|
||||
return new SOAP_Value('return','dateTime',$value);
|
||||
} else {
|
||||
return new SOAP_Fault("Value $timeInstant is not a dateTime value");
|
||||
}
|
||||
}
|
||||
|
||||
function echoHexBinary($hb)
|
||||
{
|
||||
return new SOAP_Value('return','hexBinary',bin2hex(hex2bin($hb)));
|
||||
}
|
||||
|
||||
function echoDecimal($dec)
|
||||
{
|
||||
return new SOAP_Value('return','decimal',(FLOAT)$dec);
|
||||
}
|
||||
|
||||
function echoBoolean($boolean)
|
||||
{
|
||||
return new SOAP_Value('return','boolean',$boolean);
|
||||
}
|
||||
|
||||
function echoMimeAttachment($stuff)
|
||||
{
|
||||
return new SOAP_Attachment('return','application/octet-stream',NULL,$stuff);
|
||||
}
|
||||
}
|
||||
|
||||
$base = new SOAP_Interop_Base();
|
||||
$server->addObjectMap($base);
|
||||
?>
|
||||
@@ -1,87 +0,0 @@
|
||||
<?
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more |
|
||||
// | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
require_once 'SOAP/Server.php';
|
||||
|
||||
class SOAP_Interop_GroupB {
|
||||
var $method_namespace = 'http://soapinterop.org/';
|
||||
var $dispatch_map = array();
|
||||
|
||||
function SOAP_Interop_GroupB() {
|
||||
$this->dispatch_map['echoStructAsSimpleTypes'] =
|
||||
array('in' => array('inputStruct' => 'SOAPStruct'),
|
||||
'out' => array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float')
|
||||
);
|
||||
|
||||
# $server->addToMap('echoSimpleTypesAsStruct',
|
||||
# array('outputString' => 'string', 'outputInteger' => 'int', 'outputFloat' => 'float'),
|
||||
# array('return' => 'struct'));
|
||||
# $server->addToMap('echoNestedStruct', array(), array());
|
||||
# $server->addToMap('echo2DStringArray', array(), array());
|
||||
# $server->addToMap('echoNestedArray', array(), array());
|
||||
}
|
||||
function echoStructAsSimpleTypes ($struct)
|
||||
{
|
||||
# convert a SOAPStruct to an array
|
||||
$vals = array_values($struct);
|
||||
return array(
|
||||
new SOAP_Value('outputString','string',$struct['varString']),
|
||||
new SOAP_Value('outputInteger','int',$struct['varInt']),
|
||||
new SOAP_Value('outputFloat','float',$struct['varFloat'])
|
||||
);
|
||||
return array_values($struct);
|
||||
}
|
||||
|
||||
function echoSimpleTypesAsStruct($string, $int, $float)
|
||||
{
|
||||
# convert a input into struct
|
||||
$ret = new SOAP_Value('return','{http://soapinterop.org/xsd}SOAPStruct',
|
||||
array( #push struct elements into one soap value
|
||||
new SOAP_Value('varString','string',$string),
|
||||
new SOAP_Value('varInt','int',(int)$int),
|
||||
new SOAP_Value('varFloat','float',(FLOAT)$float)
|
||||
)
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function echoNestedStruct($struct)
|
||||
{
|
||||
return $struct;
|
||||
}
|
||||
|
||||
function echo2DStringArray($ary)
|
||||
{
|
||||
$ret = new SOAP_Value('return','Array',$ary);
|
||||
$ret->options['flatten'] = TRUE;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function echoNestedArray($ary)
|
||||
{
|
||||
return $ary;
|
||||
}
|
||||
}
|
||||
|
||||
$groupb = new SOAP_Interop_GroupB();
|
||||
$server->addObjectMap($groupb);
|
||||
|
||||
?>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
require_once 'SOAP/Server.php';
|
||||
require_once 'SOAP/Value.php';
|
||||
|
||||
class SOAP_Interop_GroupC {
|
||||
var $method_namespace = 'http://soapinterop.org/echoheader/';
|
||||
|
||||
function echoMeStringRequest($string)
|
||||
{
|
||||
return new SOAP_Value('{'.$this->method_namespace.'}echoMeStringResponse','string',$string);
|
||||
}
|
||||
|
||||
function echoMeStructRequest($struct)
|
||||
{
|
||||
return new SOAP_Value('{'.$this->method_namespace.'}echoMeStructResponse','SOAPStruct',$struct);
|
||||
}
|
||||
}
|
||||
|
||||
$groupc = new SOAP_Interop_GroupC();
|
||||
$server->addObjectMap($groupc);
|
||||
|
||||
?>
|
||||
@@ -1,258 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.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: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'SOAP/Server.php';
|
||||
|
||||
$server = new SOAP_Server;
|
||||
|
||||
require_once 'server_round2_base.php';
|
||||
require_once 'server_round2_groupB.php';
|
||||
require_once 'server_round2_groupC.php';
|
||||
|
||||
$test = '<?xml version="1.0"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:ns6="http://soapinterop.org/echoheader/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Header>
|
||||
|
||||
<ns6:echoMeStringRequest xsi:type="xsd:string" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:mustUnderstand="0">hello world</ns6:echoMeStringRequest>
|
||||
</SOAP-ENV:Header>
|
||||
<SOAP-ENV:Body>
|
||||
|
||||
<echoVoid></echoVoid>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>';
|
||||
|
||||
$test = '<?xml version="1.0"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:ns6="http://soapinterop.org/echoheader/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Header>
|
||||
|
||||
<ns6:echoMeStructRequest xsi:type="si:SOAPStruct"
|
||||
SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next"
|
||||
SOAP-ENV:mustUnderstand="1">
|
||||
<varString xsi:type="xsd:string">arg</varString>
|
||||
|
||||
<varInt xsi:type="xsd:int">34</varInt>
|
||||
|
||||
<varFloat xsi:type="xsd:float">325.325</varFloat>
|
||||
</ns6:echoMeStructRequest>
|
||||
</SOAP-ENV:Header>
|
||||
<SOAP-ENV:Body>
|
||||
|
||||
<echoVoid></echoVoid>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
';
|
||||
|
||||
$test = '<?xml version="1.0"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:ns6="http://soapinterop.org/echoheader/"
|
||||
xmlns:ns7="http://soapinterop.org/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Body>
|
||||
|
||||
<ns7:echoString>
|
||||
<inputString xsi:type="xsd:string"></inputString>
|
||||
</ns7:echoString>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
';
|
||||
$test = '<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:ns6="http://soapinterop.org/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Body>
|
||||
<ns6:echoVoid/>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>';
|
||||
|
||||
$test = '<?xml version="1.0" encoding="US-ASCII"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:ns6="http://soapinterop.org/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Body>
|
||||
<ns6:echoIntegerArray><inputIntegerArray xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:int[3]" SOAP-ENC:offset="[0]"><item xsi:type="xsd:int">1</item>
|
||||
<item xsi:type="xsd:int">234324324</item>
|
||||
<item xsi:type="xsd:int">2</item>
|
||||
</inputIntegerArray>
|
||||
</ns6:echoIntegerArray>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>';
|
||||
|
||||
#$test = "<S:Envelope
|
||||
#S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
|
||||
#xmlns:Enc='http://schemas.xmlsoap.org/soap/encoding/'
|
||||
#xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'
|
||||
#xmlns:a='http://soapinterop.org/'
|
||||
#xmlns:b='http://soapinterop.org/xsd'
|
||||
#xmlns:XS='http://www.w3.org/2001/XMLSchema'
|
||||
#xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'>
|
||||
#<S:Body>
|
||||
#<b:SOAPStruct Enc:root='0' id='21b56c4' XI:type='b:SOAPStruct'>
|
||||
#<varInt XI:type='XS:int'>1</varInt>
|
||||
#<varFloat XI:type='XS:float'>2</varFloat>
|
||||
#<varString XI:type='XS:string'>wilma</varString>
|
||||
#</b:SOAPStruct>
|
||||
#<a:echoStructArray>
|
||||
#<inputStructArray XI:type='Enc:Array' Enc:arrayType='XS:anyType[3]'>
|
||||
#<fred href='#21b56c4'/>
|
||||
#<i href='#21b56c4'/>
|
||||
#<i href='#21b56c4'/>
|
||||
#</inputStructArray>
|
||||
#</a:echoStructArray>
|
||||
#</S:Body></S:Envelope>";
|
||||
|
||||
#$test = "<S:Envelope S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:Enc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:a='http://soapinterop.org/' xmlns:b='http://soapinterop.org/xsd' xmlns:XS='http://www.w3.org/2001/XMLSchema' xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'> <S:Body><a:echoStructArray><inputStructArray XI:type='Enc:Array' Enc:arrayType='b:SOAPStruct[2]'><inputStruct href='#213e654'/> <inputStruct href='#21b8c4c'/> </inputStructArray> </a:echoStructArray> <b:SOAPStruct Enc:root='0' id='21b8c4c' XI:type='b:SOAPStruct'><varInt XI:type='XS:int'>-1</varInt> <varFloat XI:type='XS:float'>-1</varFloat> <varString XI:type='XS:string'>lean on into the groove y'all</varString> </b:SOAPStruct> <b:SOAPStruct Enc:root='0' id='213e654' XI:type='b:SOAPStruct'><varInt XI:type='XS:int'>1073741824</varInt> <varFloat XI:type='XS:float'>-42.24</varFloat> <varString XI:type='XS:string'>pocketSOAP rocks!<g></varString> </b:SOAPStruct> </S:Body></S:Envelope>";
|
||||
|
||||
#$test = "<S:Envelope S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:b='http://soapinterop.org/' xmlns:a='http://soapinterop.org/headers/' xmlns:XS='http://www.w3.org/2001/XMLSchema' xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'> <S:Header> <a:Transaction S:mustUnderstand='1' XI:type='XS:short'>5</a:Transaction> </S:Header> <S:Body><b:echoString><inputString XI:type='XS:string'>Opps, should never see me</inputString> </b:echoString> </S:Body></S:Envelope>";
|
||||
#$test = "<S:Envelope S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:b='http://soapinterop.org/' xmlns:a='http://soapinterop.org/headers/' xmlns:XS='http://www.w3.org/2001/XMLSchema' xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'> <S:Header> <a:Transaction XI:type='XS:short'>5</a:Transaction> </S:Header> <S:Body><b:echoString><inputString XI:type='XS:string'>Opps, should never see me</inputString> </b:echoString> </S:Body></S:Envelope>";
|
||||
#$test = "<S:Envelope S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:Enc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:a='http://soapinterop.org/' xmlns:b='http://soapinterop.org/xsd' xmlns:XS='http://www.w3.org/2001/XMLSchema' xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'> <S:Body><a:echoStructAsSimpleTypes><inputStruct href='#213e59c'/> </a:echoStructAsSimpleTypes> <b:SOAPStruct Enc:root='0' id='213e59c' XI:type='b:SOAPStruct'><varInt XI:type='XS:int'>42</varInt> <varString XI:type='XS:string'>Orbital</varString> <varFloat XI:type='XS:float'>-42.42</varFloat> </b:SOAPStruct> </S:Body></S:Envelope>";
|
||||
|
||||
// white mesa failures
|
||||
/*$test = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><h:echoMeStringRequest SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:mustUnderstand="1" xmlns:h="http://unknown.org/">White Mesa Test Header String.</h:echoMeStringRequest></SOAP-ENV:Header><SOAP-ENV:Body><m:echoVoid SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:m="http://soapinterop.org/" /></SOAP-ENV:Body></SOAP-ENV:Envelope>';
|
||||
*/
|
||||
/*
|
||||
$test = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><h:echoMeStringRequest SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:mustUnderstand="1" xmlns:h="http://unknown.org/">White Mesa Test Header String.</h:echoMeStringRequest></SOAP-ENV:Header><SOAP-ENV:Body><m:echoVoid SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:m="http://soapinterop.org/" /></SOAP-ENV:Body></SOAP-ENV:Envelope>';
|
||||
*/
|
||||
//$test = "<S:Envelope S:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:a='http://soapinterop.org/' xmlns:XI='http://www.w3.org/2001/XMLSchema-instance'> <S:Body><a:echoIntegerArray><inputIntegerArray XI:nil='true'></inputIntegerArray> </a:echoIntegerArray> </S:Body></S:Envelope>";
|
||||
|
||||
$test = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:ns4="http://soapinterop.org/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Body>
|
||||
|
||||
<ns4:echo2DStringArray>
|
||||
<input2DStringArray xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:string[2,3]">
|
||||
<item xsi:type="xsd:string">row0col0</item>
|
||||
<item xsi:type="xsd:string">row0col1</item>
|
||||
<item xsi:type="xsd:string">row0col2</item>
|
||||
<item xsi:type="xsd:string">row1col0</item>
|
||||
<item xsi:type="xsd:string">row1col1</item>
|
||||
<item xsi:type="xsd:string">row1col2</item></input2DStringArray></ns4:echo2DStringArray>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>';
|
||||
|
||||
$_SERVER['REQUEST_METHOD'] = "POST";
|
||||
$_SERVER['CONTENT_TYPE'] = 'multipart/related; type=text/xml; boundary="=_d624611fe466a88d956a205651c74fdb"';
|
||||
|
||||
$test = '--=_d624611fe466a88d956a205651c74fdb
|
||||
Content-Type: text/xml; charset="UTF-8"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCg0KPFNPQVAtRU5WOkVudmVs
|
||||
b3BlICB4bWxuczpTT0FQLUVOVj0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZl
|
||||
bG9wZS8iDQogIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiDQog
|
||||
IHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiDQog
|
||||
IHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5n
|
||||
LyINCiAgU09BUC1FTlY6ZW5jb2RpbmdTdHlsZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcv
|
||||
c29hcC9lbmNvZGluZy8iPg0KPFNPQVAtRU5WOkJvZHk+DQoNCjxlY2hvTWltZUF0dGFjaG1lbnQ+
|
||||
DQo8dGVzdCBocmVmPSJjaWQ6ZTZiOTg0M2JiYzUxY2JiMDAzOTk0MGVmN2VlNzY2MDMiLz48L2Vj
|
||||
aG9NaW1lQXR0YWNobWVudD4NCjwvU09BUC1FTlY6Qm9keT4NCjwvU09BUC1FTlY6RW52ZWxvcGU+
|
||||
DQo=
|
||||
--=_d624611fe466a88d956a205651c74fdb
|
||||
Content-Disposition: attachment.php
|
||||
Content-Type: text/plain
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <e6b9843bbc51cbb0039940ef7ee76603>
|
||||
|
||||
PD9waHANCnJlcXVpcmVfb25jZSgiU09BUC9DbGllbnQucGhwIik7DQpyZXF1aXJlX29uY2UoIlNP
|
||||
QVAvdGVzdC90ZXN0LnV0aWxpdHkucGhwIik7DQpyZXF1aXJlX29uY2UoIlNPQVAvVmFsdWUucGhw
|
||||
Iik7DQokc29hcF9iYXNlID0gbmV3IFNPQVBfQmFzZSgpOw0KDQokdiA9ICBuZXcgU09BUF9BdHRh
|
||||
Y2htZW50KCd0ZXN0JywndGV4dC9wbGFpbicsJ2F0dGFjaG1lbnQucGhwJyk7DQokbWV0aG9kVmFs
|
||||
dWUgPSBuZXcgU09BUF9WYWx1ZSgndGVzdGF0dGFjaCcsICdTdHJ1Y3QnLCBhcnJheSgkdikpOw0K
|
||||
DQovLyBzZWUgdGhlIG1pbWUgYXJyYXkNCi8vJHZhbCA9ICRzb2FwX2Jhc2UtPl9tYWtlRW52ZWxv
|
||||
cGUoJG1ldGhvZFZhbHVlKTsNCi8vcHJpbnRfcigkdmFsKTsNCg0KJGNsaWVudCA9IG5ldyBTT0FQ
|
||||
X0NsaWVudCgnaHR0cDovL2xvY2FsaG9zdC9zb2FwX2ludGVyb3Avc2VydmVyX3JvdW5kMi5waHAn
|
||||
KTsNCiRyZXNwID0gJGNsaWVudC0+Y2FsbCgnZWNob01pbWVBdHRhY2htZW50JyxhcnJheSgkdikp
|
||||
Ow0KcHJpbnRfcigkcmVzcCk7DQpwcmludCAkY2xpZW50LT53aXJlOw0KPz4=
|
||||
--=_d624611fe466a88d956a205651c74fdb--';
|
||||
|
||||
$_SERVER['CONTENT_TYPE'] = 'multipart/related; type=text/xml; boundary="=_a2cbb051424cc43e72d3c8c8d0b8f70e"';
|
||||
$test='--=_a2cbb051424cc43e72d3c8c8d0b8f70e
|
||||
Content-Type: text/xml; charset="UTF-8"
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<SOAP-ENV:Body>
|
||||
|
||||
<echoMimeAttachment>
|
||||
<test href="cid:a223fea3c35b5f0e6dedf8da75efd6b3"/></echoMimeAttachment>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
|
||||
--=_a2cbb051424cc43e72d3c8c8d0b8f70e
|
||||
Content-Disposition: attachment.php
|
||||
Content-Type: text/plain
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <a223fea3c35b5f0e6dedf8da75efd6b3>
|
||||
|
||||
PD9waHANCnJlcXVpcmVfb25jZSgiU09BUC9DbGllbnQucGhwIik7DQpyZXF1aXJlX29uY2UoIlNP
|
||||
QVAvdGVzdC90ZXN0LnV0aWxpdHkucGhwIik7DQpyZXF1aXJlX29uY2UoIlNPQVAvVmFsdWUucGhw
|
||||
Iik7DQokc29hcF9iYXNlID0gbmV3IFNPQVBfQmFzZSgpOw0KDQokdiA9ICBuZXcgU09BUF9BdHRh
|
||||
Y2htZW50KCd0ZXN0JywndGV4dC9wbGFpbicsJ2F0dGFjaG1lbnQucGhwJyk7DQokbWV0aG9kVmFs
|
||||
dWUgPSBuZXcgU09BUF9WYWx1ZSgndGVzdGF0dGFjaCcsICdTdHJ1Y3QnLCBhcnJheSgkdikpOw0K
|
||||
DQovLyBzZWUgdGhlIG1pbWUgYXJyYXkNCi8vJHZhbCA9ICRzb2FwX2Jhc2UtPl9tYWtlRW52ZWxv
|
||||
cGUoJG1ldGhvZFZhbHVlKTsNCi8vcHJpbnRfcigkdmFsKTsNCg0KJGNsaWVudCA9IG5ldyBTT0FQ
|
||||
X0NsaWVudCgnaHR0cDovL2xvY2FsaG9zdC9zb2FwX2ludGVyb3Avc2VydmVyX3JvdW5kMi5waHAn
|
||||
KTsNCiRyZXNwID0gJGNsaWVudC0+Y2FsbCgnZWNob01pbWVBdHRhY2htZW50JyxhcnJheSgkdikp
|
||||
Ow0KI3ByaW50X3IoJHJlc3ApOw0KcHJpbnQgJGNsaWVudC0+d2lyZTsNCj8+
|
||||
--=_a2cbb051424cc43e72d3c8c8d0b8f70e--
|
||||
';
|
||||
$server->service($test, '',TRUE);
|
||||
print $server->response;
|
||||
?>
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
require_once("SOAP/Parser.php");
|
||||
require_once("SOAP/Value.php");
|
||||
|
||||
function number_compare($f1, $f2)
|
||||
{
|
||||
# figure out which has the least fractional digits
|
||||
preg_match('/.*?\.(.*)/',$f1,$m1);
|
||||
preg_match('/.*?\.(.*)/',$f2,$m2);
|
||||
#print_r($m1);
|
||||
# always use at least 2 digits of precision
|
||||
$d = max(min(strlen(count($m1)?$m1[1]:'0'),strlen(count($m2)?$m2[1]:'0')),2);
|
||||
$f1 = round($f1, $d);
|
||||
$f2 = round($f2, $d);
|
||||
return bccomp($f1, $f2, $d) == 0;
|
||||
}
|
||||
|
||||
function boolean_compare($f1, $f2)
|
||||
{
|
||||
if (($f1 == 'true' || $f1 === TRUE || $f1 != 0) &&
|
||||
($f2 == 'true' || $f2 === TRUE || $f2 != 0)) return TRUE;
|
||||
if (($f1 == 'false' || $f1 === FALSE || $f1 == 0) &&
|
||||
($f2 == 'false' || $f2 === FALSE || $f2 == 0)) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function string_compare($e1, $e2)
|
||||
{
|
||||
if (is_numeric($e1) && is_numeric($e2)) {
|
||||
return number_compare($e1, $e2);
|
||||
}
|
||||
# handle dateTime comparison
|
||||
$e1_type = gettype($e1);
|
||||
$e2_type = gettype($e2);
|
||||
$ok = FALSE;
|
||||
if ($e1_type == "string") {
|
||||
$dt = new SOAP_Type_dateTime();
|
||||
$ok = $dt->compare($e1, $e2) == 0;
|
||||
}
|
||||
return $ok || $e1 == $e2 || strcasecmp(trim($e1), trim($e2)) == 0;
|
||||
}
|
||||
|
||||
function array_compare(&$ar1, &$ar2)
|
||||
{
|
||||
if (gettype($ar1) != 'array' || gettype($ar2) != 'array') return FALSE;
|
||||
# first a shallow diff
|
||||
if (count($ar1) != count($ar2)) return FALSE;
|
||||
$diff = array_diff($ar1, $ar2);
|
||||
if (count($diff) == 0) return TRUE;
|
||||
|
||||
# diff failed, do a full check of the array
|
||||
foreach ($ar1 as $k => $v) {
|
||||
#print "comparing $v == $ar2[$k]\n";
|
||||
if (gettype($v) == "array") {
|
||||
if (!array_compare($v, $ar2[$k])) return FALSE;
|
||||
} else {
|
||||
if (!string_compare($v, $ar2[$k])) return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
function parseMessage($msg)
|
||||
{
|
||||
# strip line endings
|
||||
#$msg = preg_replace('/\r|\n/', ' ', $msg);
|
||||
$response = new SOAP_Parser($msg);
|
||||
if ($response->fault) {
|
||||
return $response->fault->getFault();
|
||||
}
|
||||
$return = $response->getResponse();
|
||||
$v = $response->decode($return);
|
||||
if (gettype($v) == 'array' && count($v)==1) {
|
||||
return array_shift($v);
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,17 +0,0 @@
|
||||
<html><body>
|
||||
<?
|
||||
error_reporting(2039);
|
||||
include("SOAP/Client.php");
|
||||
|
||||
$txt = "Bjoern";
|
||||
|
||||
$soapc = new SOAP_Client("http://localhost/soap_interop/testserver.php");
|
||||
$soapc->debug_flag = TRUE;
|
||||
print_r($soapc->call("testMethod",array("txt" => $txt)));
|
||||
print "<br>Debug: ";
|
||||
print $soapc->wire;
|
||||
print "<br><br>";
|
||||
unset($soapc);
|
||||
|
||||
?>
|
||||
</html></body>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
include "SOAP/Server.php";
|
||||
|
||||
function testMethod($arg) {
|
||||
if ($arg != "") {
|
||||
return crypt($arg);
|
||||
} else {
|
||||
return "Please supply a text";
|
||||
}
|
||||
}
|
||||
|
||||
$server = new soap_server();
|
||||
|
||||
$server->addToMap("testMethod",array("string"),array("string"));
|
||||
$server->service($HTTP_RAW_POST_DATA);
|
||||
echo "<!-- this is a test -->";
|
||||
?>
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!-- do not use the "Type" attribute here, that one is only for
|
||||
generated package.xml files -->
|
||||
<package>
|
||||
<name>ext_soap</name>
|
||||
<summary>Provides SOAP Services</summary>
|
||||
<description>
|
||||
Description of package....
|
||||
</description>
|
||||
<status>beta</status>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>rodif_bl</user>
|
||||
<name>Brad Lafountain</name>
|
||||
<email>rodif_bl@yahoo.com</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>shane</user>
|
||||
<name>Shane Caraveo</name>
|
||||
<email>shane@caraveo.com</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<date>2002-07-07</date>
|
||||
<state>alpha</state>
|
||||
<notes>
|
||||
- First offical PEAR/PECL release
|
||||
</notes>
|
||||
</release>
|
||||
<filelist>
|
||||
<dir name="/">
|
||||
<file role="doc">EXPERIMENTAL</file>
|
||||
<file role="doc">TODO</file>
|
||||
<file role="src">config.m4</file>
|
||||
<file role="src">Makefile.in</file>
|
||||
<file role="src">php_encoding.c</file>
|
||||
<file role="src">php_encoding.h</file>
|
||||
<file role="src">php_http.c</file>
|
||||
<file role="src">php_http.h</file>
|
||||
<file role="src">php_packet_soap.c</file>
|
||||
<file role="src">php_packet_soap.h</file>
|
||||
<file role="src">php_schema.c</file>
|
||||
<file role="src">php_schema.h</file>
|
||||
<file role="src">php_sdl.c</file>
|
||||
<file role="src">php_sdl.h</file>
|
||||
<file role="src">php_soap.h</file>
|
||||
<file role="src">php_soap.h</file>
|
||||
<file role="src">php_xml.c</file>
|
||||
<file role="src">php_xml.h</file>
|
||||
<file role="src">soap.c</file>
|
||||
<file role="src">php_soap.dsp</file>
|
||||
</dir>
|
||||
</filelist>
|
||||
</package>
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,256 +0,0 @@
|
||||
#ifndef PHP_ENCODING_H
|
||||
#define PHP_ENCODING_H
|
||||
|
||||
#define XSD_1999_NAMESPACE "http://www.w3.org/1999/XMLSchema"
|
||||
#define XSD_1999_TIMEINSTANT 401
|
||||
#define XSD_1999_TIMEINSTANT_STRING "timeInstant"
|
||||
|
||||
#define XSD_NAMESPACE "http://www.w3.org/2001/XMLSchema"
|
||||
#define XSD_NS_PREFIX "xsd"
|
||||
#define XSD_STRING 101
|
||||
#define XSD_STRING_STRING "string"
|
||||
#define XSD_BOOLEAN 103
|
||||
#define XSD_BOOLEAN_STRING "boolean"
|
||||
#define XSD_DECIMAL 104
|
||||
#define XSD_DECIMAL_STRING "decimal"
|
||||
#define XSD_FLOAT 105
|
||||
#define XSD_FLOAT_STRING "float"
|
||||
#define XSD_DOUBLE 106
|
||||
#define XSD_DOUBLE_STRING "double"
|
||||
#define XSD_DURATION 107
|
||||
#define XSD_DURATION_STRING "duration"
|
||||
#define XSD_DATETIME 108
|
||||
#define XSD_DATETIME_STRING "dateTime"
|
||||
#define XSD_TIME 109
|
||||
#define XSD_TIME_STRING "time"
|
||||
#define XSD_DATE 110
|
||||
#define XSD_DATE_STRING "date"
|
||||
#define XSD_GYEARMONTH 111
|
||||
#define XSD_GYEARMONTH_STRING "gYearMonth"
|
||||
#define XSD_GYEAR 112
|
||||
#define XSD_GYEAR_STRING "gYear"
|
||||
#define XSD_GMONTHDAY 113
|
||||
#define XSD_GMONTHDAY_STRING "gMonthDay"
|
||||
#define XSD_GDAY 114
|
||||
#define XSD_GDAY_STRING "gDay"
|
||||
#define XSD_GMONTH 115
|
||||
#define XSD_GMONTH_STRING "gMonth"
|
||||
#define XSD_HEXBINARY 116
|
||||
#define XSD_HEXBINARY_STRING "hexBinary"
|
||||
#define XSD_BASE64BINARY 117
|
||||
#define XSD_BASE64BINARY_STRING "base64Binary"
|
||||
#define XSD_ANYURI 118
|
||||
#define XSD_ANYURI_STRING "anyURI"
|
||||
#define XSD_QNAME 119
|
||||
#define XSD_QNAME_STRING "QName"
|
||||
#define XSD_NOTATION 120
|
||||
#define XSD_NOTATION_STRING "NOTATION"
|
||||
#define XSD_NORMALIZEDSTRING 121
|
||||
#define XSD_NORMALIZEDSTRING_STRING "normalizedString"
|
||||
#define XSD_TOKEN 122
|
||||
#define XSD_TOKEN_STRING "token"
|
||||
#define XSD_LANGUAGE 123
|
||||
#define XSD_LANGUAGE_STRING "language"
|
||||
#define XSD_NMTOKEN 124
|
||||
#define XSD_NMTOKEN_STRING "NMTOKEN"
|
||||
#define XSD_NAME 124
|
||||
#define XSD_NAME_STRING "Name"
|
||||
#define XSD_NCNAME 125
|
||||
#define XSD_NCNAME_STRING "NCName"
|
||||
#define XSD_ID 126
|
||||
#define XSD_ID_STRING "ID"
|
||||
#define XSD_IDREF 127
|
||||
#define XSD_IDREF_STRING "IDREF"
|
||||
#define XSD_IDREFS 127
|
||||
#define XSD_IDREFS_STRING "IDREFS"
|
||||
#define XSD_ENTITY 128
|
||||
#define XSD_ENTITY_STRING "ENTITY"
|
||||
#define XSD_ENTITYS 129
|
||||
#define XSD_ENTITYS_STRING "ENTITYS"
|
||||
#define XSD_INTEGER 130
|
||||
#define XSD_INTEGER_STRING "integer"
|
||||
#define XSD_NONPOSITIVEINTEGER 131
|
||||
#define XSD_NONPOSITIVEINTEGER_STRING "nonPositiveInteger"
|
||||
#define XSD_NEGATIVEINTEGER 132
|
||||
#define XSD_NEGATIVEINTEGER_STRING "negativeInteger"
|
||||
#define XSD_LONG 133
|
||||
#define XSD_LONG_STRING "long"
|
||||
#define XSD_INT 134
|
||||
#define XSD_INT_STRING "int"
|
||||
#define XSD_SHORT 135
|
||||
#define XSD_SHORT_STRING "short"
|
||||
#define XSD_BYTE 136
|
||||
#define XSD_BYTE_STRING "byte"
|
||||
#define XSD_NONNEGATIVEINTEGER 137
|
||||
#define XSD_NONNEGATIVEINTEGER_STRING "nonNegativeInteger"
|
||||
#define XSD_UNSIGNEDLONG 138
|
||||
#define XSD_UNSIGNEDLONG_STRING "unsignedLong"
|
||||
#define XSD_UNSIGNEDINT 139
|
||||
#define XSD_UNSIGNEDINT_STRING "unsignedInt"
|
||||
#define XSD_UNSIGNEDSHORT 140
|
||||
#define XSD_UNSIGNEDSHORT_STRING "unsignedShort"
|
||||
#define XSD_UNSIGNEDBYTE 141
|
||||
#define XSD_UNSIGNEDBYTE_STRING "unsignedByte"
|
||||
#define XSD_POSITIVEINTEGER 142
|
||||
#define XSD_POSITIVEINTEGER_STRING "positiveInteger"
|
||||
|
||||
#define APACHE_NAMESPACE "http://xml.apache.org/xml-soap"
|
||||
#define APACHE_NS_PREFIX "apache"
|
||||
#define APACHE_MAP 200
|
||||
#define APACHE_MAP_STRING "Map"
|
||||
|
||||
#define SOAP_ENC_NAMESPACE "http://schemas.xmlsoap.org/soap/encoding/"
|
||||
#define SOAP_ENC_NS_PREFIX "SOAP-ENC"
|
||||
#define SOAP_ENC_ARRAY 300
|
||||
#define SOAP_ENC_ARRAY_STRING "Array"
|
||||
#define SOAP_ENC_OBJECT 301
|
||||
#define SOAP_ENC_OBJECT_STRING "Struct"
|
||||
|
||||
#define SCHEMA_NAMESPACE "http://www.w3.org/2001/XMLSchema"
|
||||
#define SCHEMA_NS_PREFIX "s"
|
||||
|
||||
#define WSDL_NAMESPACE "http://schemas.xmlsoap.org/wsdl/"
|
||||
#define WSDL_NS_PREFIX "wsdl"
|
||||
|
||||
#define WSDL_SOAP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
#define WSDL_SOAP_NS_PREFIX "wsdlSoap"
|
||||
|
||||
#define WSDL_HTTP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/http/"
|
||||
#define WSDL_HTTP_NS_PREFIX "http"
|
||||
|
||||
#define WSDL_HTTP_TRANSPORT "http://schemas.xmlsoap.org/soap/http"
|
||||
|
||||
#define UNKNOWN_TYPE 999998
|
||||
#define END_KNOWN_TYPES 999999
|
||||
|
||||
struct _encodeType
|
||||
{
|
||||
int type;
|
||||
char *type_str;
|
||||
char *ns;
|
||||
sdlTypePtr sdl_type;
|
||||
soapMappingPtr map;
|
||||
};
|
||||
|
||||
struct _encode
|
||||
{
|
||||
encodeType details;
|
||||
zval *(*to_zval)(encodeType type, xmlNodePtr data);
|
||||
xmlNodePtr (*to_xml)(encodeType type, zval *data, int style);
|
||||
|
||||
xmlNodePtr (*to_zval_before)(encodeType type, xmlNodePtr data, int style);
|
||||
zval *(*to_zval_after)(encodeType type, zval *data);
|
||||
|
||||
zval *(*to_xml_before)(encodeType type, zval *data);
|
||||
xmlNodePtr (*to_xml_after)(encodeType type, xmlNodePtr data, int style);
|
||||
};
|
||||
|
||||
smart_str *build_soap_action(zval *this_ptr, char *soapaction);
|
||||
|
||||
/* Master functions all encode/decode should be called thur these functions */
|
||||
xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style);
|
||||
zval *master_to_zval(encodePtr encode, xmlNodePtr data);
|
||||
|
||||
#ifdef HAVE_PHP_DOMXML
|
||||
/* user defined mapping */
|
||||
zval *to_xml_before_user(encodeType type, zval *data);
|
||||
xmlNodePtr to_xml_user(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node, int style);
|
||||
xmlNodePtr to_zval_before_user(encodeType type, xmlNodePtr node, int style);
|
||||
zval *to_zval_user(encodeType type, xmlNodePtr node);
|
||||
zval *to_zval_after_user(encodeType type, zval *data);
|
||||
#endif
|
||||
|
||||
/* zval type decode */
|
||||
zval *to_zval_double(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_long(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_bool(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_object(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_string(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_array(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_map(encodeType type, xmlNodePtr data);
|
||||
zval *to_zval_null(encodeType type, xmlNodePtr data);
|
||||
zval *guess_zval_convert(encodeType type, xmlNodePtr data);
|
||||
|
||||
xmlNodePtr to_xml_long(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_bool(encodeType type, zval *data, int style);
|
||||
|
||||
/* String encode */
|
||||
xmlNodePtr to_xml_string(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_stringl(encodeType type, zval *data, int style);
|
||||
|
||||
/* Null encode */
|
||||
xmlNodePtr to_xml_null(encodeType type, zval *data, int style);
|
||||
|
||||
/* Struct encode */
|
||||
xmlNodePtr to_xml_object(encodeType type, zval *data, int style);
|
||||
|
||||
/* Array encode */
|
||||
xmlNodePtr guess_array_map(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_array(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_map(encodeType type, zval *data, int style);
|
||||
|
||||
/* Try and guess for non-wsdl clients and servers */
|
||||
xmlNodePtr guess_xml_convert(encodeType type, zval *data, int style);
|
||||
|
||||
/* Datetime encode/decode */
|
||||
xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format, int style);
|
||||
xmlNodePtr to_xml_datetime(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_time(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_date(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_gyearmonth(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_gyear(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_gmonthday(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_gday(encodeType type, zval *data, int style);
|
||||
xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style);
|
||||
|
||||
#define get_conversion(e) get_conversion_ex(SOAP_GLOBAL(defEncIndex), e)
|
||||
#define get_conversion_from_type(n, t) get_conversion_from_type_ex(SOAP_GLOBAL(defEnc), n, t)
|
||||
#define get_conversion_from_href_type(t) get_conversion_from_href_type_ex(SOAP_GLOBAL(defEnc), t, strlen(t))
|
||||
|
||||
void encode_reset_ns();
|
||||
smart_str *encode_new_ns();
|
||||
|
||||
void set_ns_and_type(xmlNodePtr node, encodeType type);
|
||||
void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type);
|
||||
encodePtr get_conversion_ex(HashTable *encoding, int encode);
|
||||
encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char *type);
|
||||
encodePtr get_conversion_from_href_type_ex(HashTable *encoding, char *type, int len);
|
||||
|
||||
int is_map(zval *array);
|
||||
void get_array_type(zval *array, smart_str *out_type TSRMLS_DC);
|
||||
|
||||
void delete_encoder(void *handle);
|
||||
|
||||
extern encode defaultEncoding[];
|
||||
|
||||
#define FIND_XML_NULL(xml,zval) \
|
||||
{ \
|
||||
xmlAttrPtr null; \
|
||||
if(!xml || !xml->children) \
|
||||
{ \
|
||||
ZVAL_NULL(zval); \
|
||||
return zval; \
|
||||
} \
|
||||
if(xml->properties) \
|
||||
{ \
|
||||
null = get_attribute(xml->properties, "null"); \
|
||||
if(null) \
|
||||
{ \
|
||||
ZVAL_NULL(zval); \
|
||||
return zval; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FIND_ZVAL_NULL(zval, xml) \
|
||||
{ \
|
||||
if(!zval) \
|
||||
{ \
|
||||
xmlSetProp(xml, "xsi:null", "1"); \
|
||||
return xml; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,456 +0,0 @@
|
||||
#include "php_soap.h"
|
||||
|
||||
void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, char *soapaction TSRMLS_DC)
|
||||
{
|
||||
xmlChar *buf;
|
||||
char *soap_headers;
|
||||
int buf_size,err,ret;
|
||||
sdlPtr sdl;
|
||||
php_url *phpurl = NULL;
|
||||
php_stream *stream;
|
||||
zval **trace;
|
||||
|
||||
FETCH_THIS_SOCKET(stream);
|
||||
FETCH_THIS_URL(phpurl);
|
||||
FETCH_THIS_SDL(sdl);
|
||||
|
||||
xmlDocDumpMemory(doc, &buf, &buf_size);
|
||||
|
||||
if(!buf)
|
||||
php_error(E_ERROR, "Error build soap request");
|
||||
|
||||
if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS
|
||||
&& Z_LVAL_PP(trace) > 0)
|
||||
add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
|
||||
|
||||
if(!stream)
|
||||
{
|
||||
char *url;
|
||||
int use_ssl;
|
||||
|
||||
if(!sdl)
|
||||
{
|
||||
zval **location;
|
||||
if(zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE)
|
||||
php_error(E_ERROR, "Error could not find location");
|
||||
url = Z_STRVAL_PP(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
sdlBindingPtr binding;
|
||||
FETCH_THIS_PORT(binding);
|
||||
url = binding->location;
|
||||
}
|
||||
|
||||
phpurl = php_url_parse(url);
|
||||
if (phpurl == NULL) {
|
||||
php_error(E_ERROR, "Unable to parse URL \"%s\"", url);
|
||||
}
|
||||
|
||||
use_ssl = strcmp(phpurl->scheme, "https") == 0;
|
||||
#if !HAVE_OPENSSL_EXT
|
||||
if (use_ssl) {
|
||||
php_error(E_ERROR, "SSL support not available in this build");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (phpurl->port == 0) {
|
||||
phpurl->port = use_ssl ? 443 : 80;
|
||||
}
|
||||
|
||||
stream = php_stream_sock_open_host(phpurl->host, (unsigned short)phpurl->port, SOCK_STREAM, NULL, NULL);
|
||||
|
||||
if(stream)
|
||||
{
|
||||
|
||||
#if HAVE_OPENSSL_EXT
|
||||
/* fire up SSL, if requested */
|
||||
if (use_ssl) {
|
||||
if (FAILURE == php_stream_sock_ssl_activate(stream, 1)) {
|
||||
php_error(E_ERROR, "SSL Connection attempt failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream));
|
||||
|
||||
ret = zend_list_insert(phpurl, le_url);
|
||||
add_property_resource(this_ptr, "httpurl", ret);
|
||||
zend_list_addref(ret);
|
||||
} else {
|
||||
php_error(E_ERROR, "Could not connect to host");
|
||||
}
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
zval **cookies;
|
||||
char *header = "POST %s HTTP/1.1\r\nConnection: close\r\nAccept: text/html; text/xml; text/plain\r\nUser-Agent: PHP SOAP 0.1\r\nHost: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nSOAPAction: \"%s\"\r\n";
|
||||
int size = strlen(header) + strlen(phpurl->host) + strlen(phpurl->path) + 10;
|
||||
|
||||
/* TODO: Add authentication */
|
||||
if(sdl != NULL)
|
||||
{
|
||||
/* TODO: need to grab soap action from wsdl....*/
|
||||
soap_headers = emalloc(size + strlen(soapaction));
|
||||
sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction);
|
||||
}
|
||||
else
|
||||
{
|
||||
soap_headers = emalloc(size + strlen(soapaction));
|
||||
sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction);
|
||||
}
|
||||
|
||||
err = php_stream_write(stream, soap_headers, strlen(soap_headers));
|
||||
|
||||
if(err != (int)strlen(soap_headers))
|
||||
php_error(E_ERROR,"Failed Sending HTTP Headers");
|
||||
|
||||
/* Send cookies along with request */
|
||||
if(zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS)
|
||||
{
|
||||
smart_str cookie_str = {0};
|
||||
zval **data;
|
||||
char *key;
|
||||
int index, i;
|
||||
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
|
||||
for(i = 0;i < (int)Z_ARRVAL_PP(cookies)->nNumOfElements;i++)
|
||||
{
|
||||
zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
|
||||
zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, (long *)&index, FALSE);
|
||||
|
||||
smart_str_appendl(&cookie_str, "Cookie: ", 8);
|
||||
smart_str_appendl(&cookie_str, key, strlen(key));
|
||||
smart_str_appendc(&cookie_str, '=');
|
||||
smart_str_appendl(&cookie_str, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
|
||||
smart_str_appendc(&cookie_str, ';');
|
||||
zend_hash_move_forward(Z_ARRVAL_PP(cookies));
|
||||
}
|
||||
smart_str_appendl(&cookie_str, "\r\n", 2);
|
||||
smart_str_0(&cookie_str);
|
||||
|
||||
err = php_stream_write(stream, cookie_str.c, cookie_str.len);
|
||||
|
||||
if(err != (int)cookie_str.len)
|
||||
php_error(E_ERROR,"Failed Sending HTTP Headers");
|
||||
|
||||
smart_str_free(&cookie_str);
|
||||
}
|
||||
|
||||
err = php_stream_write(stream, "\r\n", 2);
|
||||
|
||||
if(err != 2)
|
||||
php_error(E_ERROR,"Failed Sending HTTP Headers");
|
||||
|
||||
|
||||
err = php_stream_write(stream, buf, buf_size);
|
||||
|
||||
if(err != (int)strlen(buf))
|
||||
php_error(E_ERROR,"Failed Sending HTTP Content");
|
||||
|
||||
efree(soap_headers);
|
||||
}
|
||||
xmlFree(buf);
|
||||
}
|
||||
|
||||
void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC)
|
||||
{
|
||||
char *http_headers, *http_body, *content_type, *http_version, http_status[4], *cookie_itt;
|
||||
int http_header_size, http_body_size, http_close;
|
||||
sdlPtr sdl;
|
||||
zval **socket_ref;
|
||||
php_stream *stream;
|
||||
zval **trace;
|
||||
|
||||
FETCH_THIS_SDL(sdl);
|
||||
|
||||
if(FIND_SOCKET_PROPERTY(this_ptr, socket_ref) != FAILURE)
|
||||
{
|
||||
FETCH_SOCKET_RES(stream, socket_ref);
|
||||
}
|
||||
|
||||
if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC))
|
||||
php_error(E_ERROR, "Error Fetching http headers");
|
||||
|
||||
/* Check to see what HTTP status was sent */
|
||||
http_version = get_http_header_value(http_headers,"HTTP/");
|
||||
if(http_version)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = strstr(http_version," ");
|
||||
|
||||
if(tmp != NULL)
|
||||
{
|
||||
tmp++;
|
||||
strncpy(http_status,tmp,4);
|
||||
http_status[3] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
Try and process any respsone that is xml might contain fault code
|
||||
|
||||
Maybe try and test for some of the 300's 400's specfics but not
|
||||
right now.
|
||||
|
||||
if(strcmp(http_status,"200"))
|
||||
{
|
||||
zval *err;
|
||||
char *http_err;
|
||||
|
||||
MAKE_STD_ZVAL(err);
|
||||
ZVAL_STRING(err, http_body, 1);
|
||||
http_err = emalloc(strlen("HTTP request failed ()") + 4);
|
||||
sprintf(http_err, "HTTP request failed (%s)", http_status);
|
||||
add_soap_fault(thisObj, "SOAP-ENV:Client", http_err, NULL, err TSRMLS_CC);
|
||||
efree(http_err);
|
||||
return;
|
||||
}*/
|
||||
|
||||
/* Try and get headers again */
|
||||
if(!strcmp(http_status, "100"))
|
||||
{
|
||||
if(!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC))
|
||||
php_error(E_ERROR, "Error Fetching http headers");
|
||||
}
|
||||
|
||||
efree(http_version);
|
||||
}
|
||||
|
||||
if(!get_http_body(stream, http_headers, &http_body, &http_body_size TSRMLS_CC))
|
||||
php_error(E_ERROR, "Error Fetching http body");
|
||||
|
||||
if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS
|
||||
&& Z_LVAL_PP(trace) > 0)
|
||||
add_property_stringl(this_ptr, "__last_response", http_body, http_body_size, 1);
|
||||
|
||||
/* Close every time right now till i can spend more time on it
|
||||
it works.. it's just slower??
|
||||
*/
|
||||
/* See if the server requested a close */
|
||||
http_close = TRUE;
|
||||
/*
|
||||
connection = get_http_header_value(http_headers,"Connection: ");
|
||||
if(connection)
|
||||
{
|
||||
if(!strcmp(connection, "Keep-Alive"))
|
||||
http_close = FALSE;
|
||||
efree(connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!strncmp(http_version,"1.1", 3))
|
||||
http_close = FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
if (http_close) {
|
||||
php_stream_close(stream);
|
||||
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
|
||||
}
|
||||
|
||||
/* Check and see if the server even sent a xml document */
|
||||
content_type = get_http_header_value(http_headers,"Content-Type: ");
|
||||
if(content_type)
|
||||
{
|
||||
char *pos = NULL;
|
||||
int cmplen;
|
||||
pos = strstr(content_type,";");
|
||||
if(pos != NULL)
|
||||
cmplen = pos - content_type;
|
||||
else
|
||||
cmplen = strlen(content_type);
|
||||
|
||||
if(strncmp(content_type, "text/xml", cmplen))
|
||||
{
|
||||
if(strncmp(http_body, "<?xml", 5))
|
||||
{
|
||||
zval *err;
|
||||
MAKE_STD_ZVAL(err);
|
||||
ZVAL_STRINGL(err, http_body, http_body_size, 1);
|
||||
add_soap_fault(this_ptr, "SOAP-ENV:Client", "Didn't recieve an xml document", NULL, err TSRMLS_CC);
|
||||
efree(content_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
efree(content_type);
|
||||
}
|
||||
|
||||
/* Grab and send back every cookie */
|
||||
|
||||
/* Not going to worry about Path: because
|
||||
we shouldn't be changing urls so path dont
|
||||
matter too much
|
||||
*/
|
||||
cookie_itt = strstr(http_headers,"Set-Cookie: ");
|
||||
while(cookie_itt)
|
||||
{
|
||||
char *end_pos, *cookie;
|
||||
char *eqpos, *sempos;
|
||||
smart_str name = {0}, value = {0};
|
||||
zval **cookies, *z_cookie;
|
||||
|
||||
if(zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE)
|
||||
{
|
||||
zval *tmp_cookies;
|
||||
MAKE_STD_ZVAL(tmp_cookies);
|
||||
array_init(tmp_cookies);
|
||||
zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
|
||||
}
|
||||
|
||||
end_pos = strstr(cookie_itt,"\r\n");
|
||||
cookie = get_http_header_value(cookie_itt,"Set-Cookie: ");
|
||||
|
||||
eqpos = strstr(cookie, "=");
|
||||
sempos = strstr(cookie, ";");
|
||||
|
||||
smart_str_appendl(&name, cookie, eqpos - cookie);
|
||||
smart_str_0(&name);
|
||||
|
||||
smart_str_appendl(&value, eqpos + 1, sempos - (eqpos + 1));
|
||||
smart_str_0(&value);
|
||||
|
||||
MAKE_STD_ZVAL(z_cookie);
|
||||
ZVAL_STRINGL(z_cookie, value.c, value.len, 1);
|
||||
|
||||
zend_hash_update(Z_ARRVAL_PP(cookies), name.c, name.len + 1, &z_cookie, sizeof(zval *), NULL);
|
||||
|
||||
cookie_itt = strstr(cookie_itt + sizeof("Set-Cookie: "), "Set-Cookie: ");
|
||||
|
||||
smart_str_free(&value);
|
||||
smart_str_free(&name);
|
||||
efree(cookie);
|
||||
cookie_itt = FALSE;
|
||||
}
|
||||
|
||||
*buffer = http_body;
|
||||
*buffer_len = http_body_size;
|
||||
efree(http_headers);
|
||||
}
|
||||
|
||||
char *get_http_header_value(char *headers, char *type)
|
||||
{
|
||||
char *pos, *tmp = NULL;
|
||||
int typelen, headerslen;
|
||||
|
||||
typelen = strlen(type);
|
||||
headerslen = strlen(headers);
|
||||
|
||||
/* header `titles' can be lower case, or any case combination, according
|
||||
* to the various RFC's. */
|
||||
pos = headers;
|
||||
do {
|
||||
/* start of buffer or start of line */
|
||||
if (strncasecmp(pos, type, typelen) == 0) {
|
||||
char *eol;
|
||||
|
||||
/* match */
|
||||
tmp = pos + typelen;
|
||||
eol = strstr(tmp, "\r\n");
|
||||
if (eol == NULL) {
|
||||
eol = headers + headerslen;
|
||||
}
|
||||
return estrndup(tmp, eol - tmp);
|
||||
}
|
||||
|
||||
/* find next line */
|
||||
pos = strstr(pos, "\r\n");
|
||||
if (pos)
|
||||
pos += 2;
|
||||
|
||||
} while (pos);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_http_body(php_stream *stream, char *headers, char **response, int *out_size TSRMLS_DC)
|
||||
{
|
||||
char *trans_enc, *content_length, *http_buf = NULL;
|
||||
int http_buf_size = 0;
|
||||
|
||||
trans_enc = get_http_header_value(headers, "Transfer-Encoding: ");
|
||||
content_length = get_http_header_value(headers, "Content-Length: ");
|
||||
|
||||
if (trans_enc && !strcmp(trans_enc, "chunked")) {
|
||||
int cur = 0, size = 0, buf_size = 0, len_size;
|
||||
char done, chunk_size[10];
|
||||
|
||||
done = FALSE;
|
||||
http_buf = NULL;
|
||||
|
||||
while (!done) {
|
||||
php_stream_gets(stream, chunk_size, sizeof(chunk_size));
|
||||
|
||||
if (sscanf(chunk_size, "%x", &buf_size) != -1) {
|
||||
http_buf = erealloc(http_buf, http_buf_size + buf_size + 1);
|
||||
len_size = 0;
|
||||
|
||||
while (http_buf_size < buf_size) {
|
||||
len_size += php_stream_read(stream, http_buf + http_buf_size, buf_size - len_size);
|
||||
http_buf_size += len_size;
|
||||
}
|
||||
|
||||
/* Eat up '\r' '\n' */
|
||||
php_stream_getc(stream);php_stream_getc(stream);
|
||||
}
|
||||
if (buf_size == 0) {
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
efree(trans_enc);
|
||||
|
||||
if (http_buf == NULL) {
|
||||
http_buf = estrndup("", 1);
|
||||
http_buf_size = 1;
|
||||
} else {
|
||||
http_buf[http_buf_size] = '\0';
|
||||
}
|
||||
|
||||
} else if (content_length) {
|
||||
int size;
|
||||
size = atoi(content_length);
|
||||
http_buf = emalloc(size + 1);
|
||||
|
||||
while(http_buf_size < size) {
|
||||
http_buf_size += php_stream_read(stream, http_buf + http_buf_size, size - http_buf_size);
|
||||
}
|
||||
http_buf[size] = '\0';
|
||||
efree(content_length);
|
||||
} else {
|
||||
php_error(E_ERROR, "Don't know how to read http body, No Content-Length or chunked data");
|
||||
}
|
||||
|
||||
(*response) = http_buf;
|
||||
(*out_size) = http_buf_size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int get_http_headers(php_stream *stream, char **response, int *out_size TSRMLS_DC)
|
||||
{
|
||||
int done = FALSE;
|
||||
char chr;
|
||||
smart_str tmp_response = {0};
|
||||
char headerbuf[8192];
|
||||
|
||||
while(!done)
|
||||
{
|
||||
if (!php_stream_gets(stream, headerbuf, sizeof(headerbuf))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(headerbuf, "\r\n") == 0) {
|
||||
/* empty line marks end of headers */
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* add header to collection */
|
||||
smart_str_appends(&tmp_response, headerbuf);
|
||||
}
|
||||
smart_str_0(&tmp_response);
|
||||
(*response) = tmp_response.c;
|
||||
(*out_size) = tmp_response.len;
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef PHP_HTTP_H
|
||||
#define PHP_HTTP_H
|
||||
|
||||
void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, char *soapaction TSRMLS_DC);
|
||||
void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC);
|
||||
|
||||
char *get_http_header_value(char *headers, char *type);
|
||||
int get_http_body(php_stream *socketd, char *headers, char **response, int *out_size TSRMLS_DC);
|
||||
int get_http_headers(php_stream *socketd,char **response, int *out_size TSRMLS_DC);
|
||||
|
||||
#endif
|
||||
@@ -1,141 +0,0 @@
|
||||
#include "php_soap.h"
|
||||
|
||||
int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval ***ret, int *num_params TSRMLS_DC)
|
||||
{
|
||||
xmlDocPtr response;
|
||||
xmlNodePtr trav, trav2, env, body, resp, cur, fault;
|
||||
zval **tmp_ret;
|
||||
|
||||
response = xmlParseMemory(buffer, buffer_size);
|
||||
xmlCleanupParser();
|
||||
|
||||
if (!response) {
|
||||
php_error(E_ERROR, "looks like we got no XML document");
|
||||
}
|
||||
|
||||
(*num_params) = 0;
|
||||
|
||||
trav = response->children;
|
||||
FOREACHNODE(trav,"Envelope",env)
|
||||
{
|
||||
trav2 = env->children;
|
||||
FOREACHNODE(trav2,"Body",body)
|
||||
{
|
||||
fault = get_node(body->children,"Fault");
|
||||
if(fault != NULL)
|
||||
{
|
||||
char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL;
|
||||
zval *details = NULL;
|
||||
xmlNodePtr tmp;
|
||||
|
||||
tmp = get_node(fault->children,"faultcode");
|
||||
if(tmp != NULL && tmp->children != NULL)
|
||||
faultcode = tmp->children->content;
|
||||
|
||||
tmp = get_node(fault->children,"faultstring");
|
||||
if(tmp != NULL && tmp->children != NULL)
|
||||
faultstring = tmp->children->content;
|
||||
|
||||
tmp = get_node(fault->children,"faultactor");
|
||||
if(tmp != NULL && tmp->children != NULL)
|
||||
faultactor = tmp->children->content;
|
||||
|
||||
tmp = get_node(fault->children,"detail");
|
||||
if(tmp != NULL)
|
||||
{
|
||||
encodePtr enc;
|
||||
enc = get_conversion(UNKNOWN_TYPE);
|
||||
details = enc->to_zval(enc->details, tmp);
|
||||
}
|
||||
|
||||
add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details TSRMLS_CC);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp = body->children;
|
||||
if(fn != NULL)
|
||||
{
|
||||
sdlParamPtr *h_param, param = NULL;
|
||||
xmlNodePtr val = NULL;
|
||||
encodePtr enc;
|
||||
char *name, *ns = NULL;
|
||||
|
||||
if(fn->bindingType == BINDING_SOAP)
|
||||
{
|
||||
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
|
||||
|
||||
zend_hash_internal_pointer_reset(fn->responseParameters);
|
||||
if(zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) != SUCCESS)
|
||||
php_error(E_ERROR, "Can't find response parameter \"%s\"", param->paramName);
|
||||
|
||||
param = (*h_param);
|
||||
if(fnb->style == SOAP_DOCUMENT)
|
||||
{
|
||||
name = (*h_param)->encode->details.type_str;
|
||||
ns = (*h_param)->encode->details.ns;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = fn->responseName;
|
||||
/* ns = ? */
|
||||
}
|
||||
|
||||
cur = get_node_ex(resp, name, ns);
|
||||
/* TODO: produce warning invalid ns */
|
||||
if(!cur)
|
||||
cur = get_node(resp, name);
|
||||
|
||||
if(!cur)
|
||||
php_error(E_ERROR, "Can't find response data");
|
||||
|
||||
|
||||
if(fnb->style == SOAP_DOCUMENT)
|
||||
val = cur;
|
||||
else
|
||||
val = get_node(cur->children, param->paramName);
|
||||
|
||||
if(!val)
|
||||
php_error(E_ERROR, "Can't find response data");
|
||||
|
||||
tmp_ret = emalloc(sizeof(zval **));
|
||||
if(param != NULL)
|
||||
enc = param->encode;
|
||||
else
|
||||
enc = get_conversion(UNKNOWN_TYPE);
|
||||
|
||||
tmp_ret[0] = master_to_zval(enc, val);
|
||||
(*ret) = tmp_ret;
|
||||
(*num_params) = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = resp;
|
||||
while(cur && cur->type != XML_ELEMENT_NODE)
|
||||
cur = cur->next;
|
||||
if(cur != NULL)
|
||||
{
|
||||
xmlNodePtr val;
|
||||
val = cur->children;
|
||||
while(val && val->type != XML_ELEMENT_NODE)
|
||||
val = val->next;
|
||||
|
||||
if(val != NULL)
|
||||
{
|
||||
encodePtr enc;
|
||||
enc = get_conversion(UNKNOWN_TYPE);
|
||||
tmp_ret = emalloc(sizeof(zval **));
|
||||
tmp_ret[0] = master_to_zval(enc, val);
|
||||
(*ret) = tmp_ret;
|
||||
(*num_params) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ENDFOREACH(trav2);
|
||||
}
|
||||
ENDFOREACH(trav);
|
||||
xmlFreeDoc(response);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef PHP_PACKET_SOAP_H
|
||||
#define PHP_PACKET_SOAP_H
|
||||
|
||||
int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval ***ret, int *num_params TSRMLS_DC);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,28 +0,0 @@
|
||||
#ifndef PHP_SCHEMA_H
|
||||
#define PHP_SCHEMA_H
|
||||
|
||||
int load_schema(sdlPtr *sdl,xmlNodePtr schema);
|
||||
int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type);
|
||||
int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type);
|
||||
int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type);
|
||||
int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type);
|
||||
int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type);
|
||||
int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type);
|
||||
int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
|
||||
int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
|
||||
int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
|
||||
int schema_extension(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
|
||||
int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
|
||||
int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type);
|
||||
int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type);
|
||||
int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type);
|
||||
int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type);
|
||||
int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
|
||||
|
||||
int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr);
|
||||
void delete_restriction_var_int(void *rvi);
|
||||
|
||||
int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr);
|
||||
void delete_schema_restriction_var_char(void *srvc);
|
||||
|
||||
#endif
|
||||
-1139
File diff suppressed because it is too large.
Load diff
@@ -1,167 +0,0 @@
|
||||
#ifndef PHP_SDL_H
|
||||
#define PHP_SDL_H
|
||||
|
||||
#define XSD_WHITESPACE_COLLAPSE 1
|
||||
#define XSD_WHITESPACE_PRESERVE 1
|
||||
#define XSD_WHITESPACE_REPLACE 1
|
||||
|
||||
#define BINDING_SOAP 1
|
||||
#define BINDING_HTTP 2
|
||||
|
||||
#define SOAP_RPC 1
|
||||
#define SOAP_DOCUMENT 2
|
||||
|
||||
#define SOAP_ENCODED 1
|
||||
#define SOAP_LITERAL 2
|
||||
|
||||
struct _sdl
|
||||
{
|
||||
xmlDocPtr doc; /* pointer to the parsed xml file */
|
||||
HashTable *types; /* array of sdlTypesPtr */
|
||||
HashTable *encoders; /* array of encodePtr */
|
||||
HashTable *bindings; /* array of sdlBindings (key'd by name) */
|
||||
char *target_ns;
|
||||
char *source;
|
||||
};
|
||||
|
||||
struct _sdlBinding
|
||||
{
|
||||
char *name;
|
||||
HashTable *functions;
|
||||
char *location;
|
||||
int bindingType;
|
||||
void *bindingAttributes;
|
||||
};
|
||||
|
||||
/* Soap Binding Specfic stuff */
|
||||
struct _sdlSoapBinding
|
||||
{
|
||||
char *transport;
|
||||
int style;
|
||||
};
|
||||
|
||||
struct _sdlSoapBindingFunctionBody
|
||||
{
|
||||
char *ns;
|
||||
int use;
|
||||
char *parts; /* not implemented yet */
|
||||
char *encodingStyle; /* not implemented yet */
|
||||
};
|
||||
|
||||
struct _sdlSoapBindingFunction
|
||||
{
|
||||
char *soapAction;
|
||||
int style;
|
||||
|
||||
sdlSoapBindingFunctionBody input;
|
||||
sdlSoapBindingFunctionBody output;
|
||||
sdlSoapBindingFunctionBody falut;
|
||||
};
|
||||
|
||||
/* HTTP Binding Specfic stuff */
|
||||
/*********** not implemented yet ************
|
||||
struct _sdlHttpBinding
|
||||
{
|
||||
int holder;
|
||||
};
|
||||
*********************************************/
|
||||
|
||||
struct _sdlRestrictionInt
|
||||
{
|
||||
int value;
|
||||
char fixed;
|
||||
char *id;
|
||||
};
|
||||
|
||||
struct _sdlRestrictionChar
|
||||
{
|
||||
char *value;
|
||||
char fixed;
|
||||
char *id;
|
||||
};
|
||||
|
||||
struct _sdlRestrictions
|
||||
{
|
||||
HashTable *enumeration; /* array of sdlRestrictionCharPtr */
|
||||
sdlRestrictionIntPtr minExclusive;
|
||||
sdlRestrictionIntPtr minInclusive;
|
||||
sdlRestrictionIntPtr maxExclusive;
|
||||
sdlRestrictionIntPtr maxInclusive;
|
||||
sdlRestrictionIntPtr totalDigits;
|
||||
sdlRestrictionIntPtr fractionDigits;
|
||||
sdlRestrictionIntPtr length;
|
||||
sdlRestrictionIntPtr minLength;
|
||||
sdlRestrictionIntPtr maxLength;
|
||||
sdlRestrictionCharPtr whiteSpace;
|
||||
sdlRestrictionCharPtr pattern;
|
||||
};
|
||||
|
||||
struct _sdlType
|
||||
{
|
||||
char *name;
|
||||
char *namens;
|
||||
int nullable;
|
||||
int min_occurs;
|
||||
int max_occurs;
|
||||
HashTable *elements; /* array of sdlTypePtr */
|
||||
HashTable *attributes; /* array of sdlAttributePtr */
|
||||
sdlRestrictionsPtr restrictions;
|
||||
encodePtr encode;
|
||||
};
|
||||
|
||||
struct _sdlParam
|
||||
{
|
||||
int order;
|
||||
encodePtr encode;
|
||||
char *paramName;
|
||||
};
|
||||
|
||||
struct _sdlFunction
|
||||
{
|
||||
char *functionName;
|
||||
char *requestName;
|
||||
char *responseName;
|
||||
HashTable *requestParameters; /* array of sdlParamPtr */
|
||||
HashTable *responseParameters; /* array of sdlParamPtr (this should only be one) */
|
||||
int bindingType;
|
||||
void *bindingAttributes;
|
||||
};
|
||||
|
||||
struct _sdlAttribute
|
||||
{
|
||||
char *def;
|
||||
char *fixed;
|
||||
char *form;
|
||||
char *id;
|
||||
char *name;
|
||||
char *ref;
|
||||
char *type;
|
||||
char *use;
|
||||
HashTable *extraAttributes; /* array of xmlNodePtr */
|
||||
};
|
||||
|
||||
sdlPtr get_sdl(char *uri);
|
||||
sdlPtr load_wsdl(char *struri, sdlPtr parent);
|
||||
int load_sdl(char *struri, int force_load);
|
||||
int load_ms_sdl(char *struri, int force_load);
|
||||
|
||||
encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, char *type);
|
||||
encodePtr get_encoder(sdlPtr sdl, char *ns, char *type);
|
||||
encodePtr get_encoder_ex(sdlPtr sdl, char *nscat);
|
||||
encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type);
|
||||
encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type);
|
||||
|
||||
sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type);
|
||||
sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns);
|
||||
|
||||
xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval* data, int style);
|
||||
zval *sdl_guess_convert_zval(encodeType enc, xmlNodePtr data);
|
||||
|
||||
xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style);
|
||||
xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style);
|
||||
|
||||
void delete_type(void *type);
|
||||
void delete_attribute(void *attribute);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="php_soap" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=php_soap - Win32 Debug
|
||||
!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 "php_soap.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 "php_soap.mak" CFG="php_soap - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "php_soap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "php_soap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "php_soap - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\bind" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTSWS" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=0 /D "COMPILE_DL_SOAP" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_soap.dll" /libpath:"..\..\\" /libpath:"..\..\..\libxml2-2.4.12\lib" /libpath:"..\..\Release_TS"
|
||||
|
||||
!ELSEIF "$(CFG)" == "php_soap - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\bind" /D "WS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=1 /D "COMPILE_DL_SOAP" /FR"Release_TS/" /Fp"Release_TS/gd.pch" /YX /Fo"Release_TS/" /Fd"Release_TS/" /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_soap.dll" /implib:"Release_TS/php_gd.lib" /pdbtype:sept /libpath:"..\..\\" /libpath:"..\..\..\libxml2-2.4.12\lib" /libpath:"..\..\Debug_TS"
|
||||
# SUBTRACT LINK32 /pdb:none /incremental:no
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "php_soap - Win32 Release"
|
||||
# Name "php_soap - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_encoding.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_http.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_schema.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_sdl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_xml.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\soap.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_encoding.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_http.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_schema.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_sdl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_soap.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\php_xml.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,416 +0,0 @@
|
||||
#ifndef PHP_SOAP_H
|
||||
#define PHP_SOAP_H
|
||||
|
||||
#include "php.h"
|
||||
#include "php_globals.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/php_standard.h"
|
||||
#include "ext/session/php_session.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
#include "php_ini.h"
|
||||
#include "SAPI.h"
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
#ifdef HAVE_PHP_DOMXML
|
||||
# include "ext/domxml/php_domxml.h"
|
||||
#endif
|
||||
|
||||
#ifndef PHP_HAVE_STREAMS
|
||||
# error You lose - must be compiled against PHP 4.3.0 or later
|
||||
#endif
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
# define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
typedef struct _encodeType encodeType, *encodeTypePtr;
|
||||
typedef struct _encode encode, *encodePtr;
|
||||
|
||||
typedef struct _sdl sdl, *sdlPtr;
|
||||
typedef struct _sdlRestrictionInt sdlRestrictionInt, *sdlRestrictionIntPtr;
|
||||
typedef struct _sdlRestrictionChar sdlRestrictionChar, *sdlRestrictionCharPtr;
|
||||
typedef struct _sdlRestrictions sdlRestrictions, *sdlRestrictionsPtr;
|
||||
typedef struct _sdlType sdlType, *sdlTypePtr;
|
||||
typedef struct _sdlParam sdlParam, *sdlParamPtr;
|
||||
typedef struct _sdlFunction sdlFunction, *sdlFunctionPtr;
|
||||
typedef struct _sdlAttribute sdlAttribute, *sdlAttributePtr;
|
||||
typedef struct _sdlBinding sdlBinding, *sdlBindingPtr;
|
||||
typedef struct _sdlSoapBinding sdlSoapBinding, *sdlSoapBindingPtr;
|
||||
typedef struct _sdlSoapBindingFunction sdlSoapBindingFunction, *sdlSoapBindingFunctionPtr;
|
||||
typedef struct _sdlSoapBindingFunctionBody sdlSoapBindingFunctionBody, *sdlSoapBindingFunctionBodyPtr;
|
||||
|
||||
typedef struct _soapMapping soapMapping, *soapMappingPtr;
|
||||
typedef struct _soapService soapService, *soapServicePtr;
|
||||
|
||||
#include "php_xml.h"
|
||||
#include "php_encoding.h"
|
||||
#include "php_sdl.h"
|
||||
#include "php_schema.h"
|
||||
#include "php_http.h"
|
||||
#include "php_packet_soap.h"
|
||||
|
||||
extern int le_sdl;
|
||||
extern int le_http_socket;
|
||||
extern int le_url;
|
||||
extern int le_service;
|
||||
|
||||
|
||||
struct _soapHeaderHandler
|
||||
{
|
||||
char *ns;
|
||||
int type;
|
||||
|
||||
struct _function_handler
|
||||
{
|
||||
char *functionName;
|
||||
char *type;
|
||||
} function_handler;
|
||||
|
||||
struct _class_handler
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
} class_handler;
|
||||
};
|
||||
|
||||
struct _soapMapping
|
||||
{
|
||||
char *ns;
|
||||
char *ctype;
|
||||
int type;
|
||||
|
||||
struct _map_functions
|
||||
{
|
||||
zval *to_xml_before;
|
||||
zval *to_xml;
|
||||
zval *to_xml_after;
|
||||
zval *to_zval_before;
|
||||
zval *to_zval;
|
||||
zval *to_zval_after;
|
||||
} map_functions;
|
||||
|
||||
struct _map_class
|
||||
{
|
||||
int type;
|
||||
zend_class_entry *ce;
|
||||
} map_class;
|
||||
};
|
||||
|
||||
struct _soapService
|
||||
{
|
||||
sdlPtr sdl;
|
||||
|
||||
struct _soap_functions
|
||||
{
|
||||
HashTable *ft;
|
||||
int functions_all;
|
||||
} soap_functions;
|
||||
|
||||
struct _soap_class
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
zval **argv;
|
||||
int argc;
|
||||
int persistance;
|
||||
} soap_class;
|
||||
|
||||
HashTable *mapping;
|
||||
int type;
|
||||
int enabled;
|
||||
char *uri;
|
||||
};
|
||||
|
||||
#define SOAP_CLASS 1
|
||||
#define SOAP_FUNCTIONS 2
|
||||
#define SOAP_FUNCTIONS_ALL 999
|
||||
|
||||
#define SOAP_MAP_FUNCTION 1
|
||||
#define SOAP_MAP_CLASS 2
|
||||
|
||||
#define SOAP_PERSISTENCE_SESSION 1
|
||||
#define SOAP_PERSISTENCE_REQUEST 2
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(soap)
|
||||
HashTable *defEncNs;
|
||||
HashTable *defEncPrefix;
|
||||
HashTable *defEnc;
|
||||
HashTable *defEncIndex;
|
||||
HashTable *sdls;
|
||||
HashTable *services;
|
||||
HashTable *overrides;
|
||||
int cur_uniq_ns;
|
||||
ZEND_END_MODULE_GLOBALS(soap)
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_SOAP_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_SOAP_API
|
||||
#endif
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
ZEND_EXTERN_MODULE_GLOBALS(soap);
|
||||
|
||||
#ifdef ZTS
|
||||
# define SOAP_GLOBAL(v) TSRMG(soap_globals_id, zend_soap_globals *, v)
|
||||
#else
|
||||
# define SOAP_GLOBAL(v) (soap_globals.v)
|
||||
#endif
|
||||
|
||||
#define PHP_SOAP_SERVER_CLASSNAME "soapserver"
|
||||
#define PHP_SOAP_CLASSNAME "soapobject"
|
||||
#define PHP_SOAP_VAR_CLASSNAME "soapvar"
|
||||
#define PHP_SOAP_FAULT_CLASSNAME "soapfault"
|
||||
#define PHP_SOAP_PARAM_CLASSNAME "soapparam"
|
||||
|
||||
|
||||
extern zend_module_entry soap_module_entry;
|
||||
#define soap_module_ptr & soap_module_entry
|
||||
|
||||
PHP_MINIT_FUNCTION(soap);
|
||||
PHP_MSHUTDOWN_FUNCTION(soap);
|
||||
PHP_MINFO_FUNCTION(soap);
|
||||
|
||||
/*
|
||||
Registry Functions
|
||||
TODO: this!
|
||||
*/
|
||||
PHP_FUNCTION(load_sdl);
|
||||
PHP_FUNCTION(unload_sdl);
|
||||
PHP_FUNCTION(unload_all_sdls);
|
||||
PHP_FUNCTION(get_available_sdls);
|
||||
PHP_FUNCTION(get_available_functions);
|
||||
PHP_FUNCTION(get_function_parameters);
|
||||
PHP_FUNCTION(soap_encode_to_xml);
|
||||
PHP_FUNCTION(soap_encode_to_zval);
|
||||
|
||||
|
||||
/* Server Functions */
|
||||
PHP_FUNCTION(soapserver);
|
||||
PHP_FUNCTION(setclass);
|
||||
PHP_FUNCTION(addfunction);
|
||||
PHP_FUNCTION(getfunctions);
|
||||
PHP_FUNCTION(handle);
|
||||
PHP_FUNCTION(setpersistence);
|
||||
PHP_FUNCTION(bind);
|
||||
#ifdef HAVE_PHP_DOMXML
|
||||
PHP_FUNCTION(map);
|
||||
#endif
|
||||
|
||||
/* Client Functions */
|
||||
PHP_FUNCTION(soapobject);
|
||||
PHP_FUNCTION(__use);
|
||||
PHP_FUNCTION(__style);
|
||||
PHP_FUNCTION(__isfault);
|
||||
PHP_FUNCTION(__getfault);
|
||||
PHP_FUNCTION(__call);
|
||||
PHP_FUNCTION(__parse);
|
||||
PHP_FUNCTION(__generate);
|
||||
PHP_FUNCTION(__trace);
|
||||
PHP_FUNCTION(__getfunctions);
|
||||
PHP_FUNCTION(__gettypes);
|
||||
PHP_FUNCTION(__getlastresponse);
|
||||
PHP_FUNCTION(__getlastrequest);
|
||||
PHP_FUNCTION(__headerclass);
|
||||
PHP_FUNCTION(__headerfunction);
|
||||
|
||||
/* SoapVar Functions */
|
||||
PHP_FUNCTION(soapvar);
|
||||
|
||||
/* SoapFault Functions */
|
||||
PHP_FUNCTION(soapfault);
|
||||
|
||||
/* SoapParam Functions */
|
||||
PHP_FUNCTION(soapparam);
|
||||
|
||||
|
||||
#define DECLARE_TRACE(file) \
|
||||
FILE *trace_fp; \
|
||||
char *trace_file = file;
|
||||
|
||||
#define TRACE(place) \
|
||||
trace_fp = fopen(trace_file, "a+"); \
|
||||
fwrite(place, strlen(place), 1, trace_fp); \
|
||||
fclose(trace_fp);
|
||||
|
||||
extern zend_class_entry soap_var_class_entry;
|
||||
|
||||
PS_SERIALIZER_FUNCS(soap);
|
||||
|
||||
void clear_soap_fault(zval *obj);
|
||||
void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC);
|
||||
void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC);
|
||||
|
||||
sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int);
|
||||
sdlFunctionPtr get_function(sdlBindingPtr sdl, char *function_name);
|
||||
|
||||
void delete_sdl(void *handle);
|
||||
void delete_binding(void *binding);
|
||||
void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body);
|
||||
void delete_function(void *function);
|
||||
void delete_paramater(void *paramater);
|
||||
void delete_service(void *service);
|
||||
void delete_http_socket(void *handle);
|
||||
void delete_url(void *handle);
|
||||
void delete_mapping(void *data);
|
||||
|
||||
void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
|
||||
zval soap_get_property_handler(zend_property_reference *property_reference);
|
||||
int soap_set_property_handler(zend_property_reference *property_reference, zval *value);
|
||||
void soap_destructor(void *jobject);
|
||||
|
||||
void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name, int *num_params, zval **parameters[] TSRMLS_DC);
|
||||
xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret TSRMLS_DC);
|
||||
xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count TSRMLS_DC);
|
||||
xmlNodePtr seralize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style TSRMLS_DC);
|
||||
xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int style TSRMLS_DC);
|
||||
zval *desearlize_zval(sdlPtr sdl, xmlNodePtr data, sdlParamPtr param TSRMLS_DC);
|
||||
|
||||
void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
#ifndef ZEND_ENGINE_2
|
||||
int my_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[] TSRMLS_DC);
|
||||
#endif
|
||||
|
||||
#define phpext_soap_ptr soap_module_ptr
|
||||
|
||||
#define HTTP_RAW_POST_DATA "HTTP_RAW_POST_DATA"
|
||||
|
||||
#define SOAP_SERVER_BEGIN_CODE() \
|
||||
zend_error_cb = soap_error_handler
|
||||
|
||||
#define SOAP_SERVER_END_CODE() \
|
||||
zend_error_cb = old_handler
|
||||
|
||||
|
||||
#define FOREACHATTRNODE(n,c,i) \
|
||||
do \
|
||||
{ \
|
||||
if(n == NULL) \
|
||||
break; \
|
||||
if(c) \
|
||||
i = get_attribute(n,c); \
|
||||
else \
|
||||
i = n; \
|
||||
if(i != NULL) \
|
||||
{ \
|
||||
n = i;
|
||||
|
||||
#define FOREACHNODE(n,c,i) \
|
||||
do \
|
||||
{ \
|
||||
if(n == NULL) \
|
||||
break; \
|
||||
if(c) \
|
||||
i = get_node(n,c); \
|
||||
else \
|
||||
i = n; \
|
||||
if(i != NULL) \
|
||||
{ \
|
||||
n = i;
|
||||
|
||||
#define ENDFOREACH(n) \
|
||||
} \
|
||||
} while ((n = n->next));
|
||||
|
||||
#define ZERO_PARAM() \
|
||||
if(ZEND_NUM_ARGS() != 0) \
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
#define ONE_PARAM(p) \
|
||||
if(ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &p) == FAILURE) \
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
#define TWO_PARAM(p,p1) \
|
||||
if(ZEND_NUM_ARGS() != 1 || getParameters(ht, 2, &p, &p1) == FAILURE) \
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
#define THREE_PARAM(p,p1,p2) \
|
||||
if(ZEND_NUM_ARGS() != 1 || getParameters(ht, 3, &p, &p1, &p2) == FAILURE) \
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
#define FETCH_THIS_PORT(ss) \
|
||||
{ \
|
||||
zval *__thisObj; zval *__port; sdlBindingPtr *__tmp; \
|
||||
GET_THIS_OBJECT(__thisObj) \
|
||||
if(FIND_PORT_PROPERTY(__thisObj, __port) == FAILURE) { \
|
||||
ss = NULL; \
|
||||
php_error(E_ERROR, "Error could find current port"); \
|
||||
} \
|
||||
__tmp = (sdlBindingPtr*)Z_LVAL_P(__port); \
|
||||
ss = *__tmp; \
|
||||
}
|
||||
|
||||
#define FIND_PORT_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "port", sizeof("port"), (void **)&tmp)
|
||||
|
||||
#define FETCH_THIS_SDL(ss) \
|
||||
{ \
|
||||
zval *__thisObj,**__tmp; \
|
||||
GET_THIS_OBJECT(__thisObj) \
|
||||
if(FIND_SDL_PROPERTY(__thisObj,__tmp) != FAILURE) \
|
||||
{ \
|
||||
FETCH_SDL_RES(ss,__tmp); \
|
||||
} \
|
||||
else \
|
||||
ss = NULL; \
|
||||
}
|
||||
|
||||
#define FIND_SDL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl"), (void **)&tmp)
|
||||
#define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl)
|
||||
|
||||
#define FETCH_THIS_SERVICE(ss) \
|
||||
{ \
|
||||
zval *__thisObj,**__tmp; \
|
||||
GET_THIS_OBJECT(__thisObj) \
|
||||
if(FIND_SERVICE_PROPERTY(__thisObj,__tmp) != FAILURE) \
|
||||
{ \
|
||||
FETCH_SERVICE_RES(ss,__tmp); \
|
||||
} \
|
||||
else \
|
||||
ss = NULL; \
|
||||
}
|
||||
|
||||
#define FIND_SERVICE_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "service", sizeof("service"), (void **)&tmp)
|
||||
#define FETCH_SERVICE_RES(ss,tmp) ss = (soapServicePtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service)
|
||||
|
||||
#define FETCH_THIS_URL(ss) \
|
||||
{ \
|
||||
zval *__thisObj,**__tmp; \
|
||||
GET_THIS_OBJECT(__thisObj) \
|
||||
if(FIND_URL_PROPERTY(__thisObj,__tmp) != FAILURE) \
|
||||
{ \
|
||||
FETCH_URL_RES(ss,__tmp); \
|
||||
} \
|
||||
else \
|
||||
ss = NULL; \
|
||||
}
|
||||
|
||||
#define FIND_URL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "httpurl", sizeof("httpurl"), (void **)&tmp)
|
||||
#define FETCH_URL_RES(ss,tmp) ss = (php_url *) zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url)
|
||||
|
||||
#define FETCH_THIS_SOCKET(ss) \
|
||||
{ \
|
||||
zval *__thisObj,**__tmp; \
|
||||
GET_THIS_OBJECT(__thisObj) \
|
||||
if(FIND_SOCKET_PROPERTY(__thisObj,__tmp) != FAILURE) \
|
||||
{ \
|
||||
FETCH_SOCKET_RES(ss,__tmp); \
|
||||
} \
|
||||
else \
|
||||
ss = NULL; \
|
||||
}
|
||||
|
||||
#define FIND_SOCKET_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "httpsocket", sizeof("httpsocket"), (void **)&tmp)
|
||||
#define FETCH_SOCKET_RES(ss,tmp) php_stream_from_zval_no_verify(ss,tmp)
|
||||
|
||||
#define GET_THIS_OBJECT(o) \
|
||||
o = getThis(); \
|
||||
if (!o) \
|
||||
{ \
|
||||
php_error(E_WARNING, "Cannot Get Class Info"); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,242 +0,0 @@
|
||||
#include "php_soap.h"
|
||||
|
||||
/* Channel libxml file io layer through the PHP streams subsystem.
|
||||
* This allows use of ftps:// and https:// urls */
|
||||
|
||||
int php_stream_xmlIO_match_wrapper(const char *filename)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
return php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ? 1 : 0;
|
||||
|
||||
}
|
||||
|
||||
void *php_stream_xmlIO_open_wrapper(const char *filename)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
return php_stream_open_wrapper(filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
|
||||
}
|
||||
|
||||
int php_stream_xmlIO_read(void *context, char *buffer, int len)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
return php_stream_read((php_stream*)context, buffer, len);
|
||||
}
|
||||
|
||||
int php_stream_xmlIO_close(void *context)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
return php_stream_close((php_stream*)context);
|
||||
}
|
||||
|
||||
xmlNsPtr attr_find_ns(xmlAttrPtr node)
|
||||
{
|
||||
if(node->ns)
|
||||
return node->ns;
|
||||
else if(node->parent->ns)
|
||||
return node->parent->ns;
|
||||
else
|
||||
return xmlSearchNs(node->doc, node->parent, NULL);
|
||||
}
|
||||
|
||||
xmlNsPtr node_find_ns(xmlNodePtr node)
|
||||
{
|
||||
if(node->ns)
|
||||
return node->ns;
|
||||
else
|
||||
return xmlSearchNs(node->doc, node, NULL);
|
||||
}
|
||||
|
||||
int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
|
||||
{
|
||||
if(!strcmp(node->name, name))
|
||||
{
|
||||
if(ns)
|
||||
{
|
||||
xmlNsPtr nsPtr;
|
||||
if(node->ns)
|
||||
nsPtr = node->ns;
|
||||
else if(node->parent->ns)
|
||||
nsPtr = node->parent->ns;
|
||||
else
|
||||
nsPtr = xmlSearchNs(node->doc, node->parent, NULL);
|
||||
if(!strcmp(nsPtr->href, ns))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
|
||||
{
|
||||
if(!strcmp(node->name, name))
|
||||
{
|
||||
if(ns)
|
||||
{
|
||||
xmlNsPtr nsPtr;
|
||||
if(node->ns)
|
||||
nsPtr = node->ns;
|
||||
else
|
||||
nsPtr = xmlSearchNs(node->doc, node, NULL);
|
||||
if(!strcmp(nsPtr->href, ns))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns)
|
||||
{
|
||||
xmlAttrPtr trav = node;
|
||||
if(node == NULL) return NULL;
|
||||
do {
|
||||
if(attr_is_equal_ex(trav, name, ns))
|
||||
return trav;
|
||||
} while(trav = trav->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns)
|
||||
{
|
||||
xmlNodePtr trav = node;
|
||||
if(node == NULL) return NULL;
|
||||
do {
|
||||
if(node_is_equal_ex(trav, name, ns))
|
||||
return trav;
|
||||
} while(trav = trav->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns)
|
||||
{
|
||||
xmlNodePtr trav = node;
|
||||
if(node == NULL) return NULL;
|
||||
do
|
||||
{
|
||||
if(node_is_equal_ex(trav, name, ns))
|
||||
return trav;
|
||||
else
|
||||
{
|
||||
if(node->children != NULL)
|
||||
{
|
||||
xmlNodePtr tmp;
|
||||
tmp = get_node_recurisve_ex(node->children, name, ns);
|
||||
if(tmp)
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
} while(trav = trav->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
|
||||
{
|
||||
xmlNodePtr trav = node, cur = NULL;
|
||||
xmlAttrPtr attr;
|
||||
|
||||
if(node == NULL) return NULL;
|
||||
do
|
||||
{
|
||||
if(name != NULL)
|
||||
{
|
||||
cur = get_node_ex(trav, name, name_ns);
|
||||
if(!cur)
|
||||
return cur;
|
||||
}
|
||||
else
|
||||
cur = trav;
|
||||
|
||||
attr = get_attribute_ex(cur->properties, attribute, attr_ns);
|
||||
if(attr != NULL && strcmp(attr->children->content, value) == 0)
|
||||
return cur;
|
||||
else
|
||||
{
|
||||
if(cur->children != NULL)
|
||||
{
|
||||
xmlNodePtr tmp;
|
||||
tmp = get_node_with_attribute_ex(cur->children, name, name_ns, attribute, value, attr_ns);
|
||||
if(tmp)
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}while(trav = trav->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
|
||||
{
|
||||
xmlNodePtr trav = node, cur;
|
||||
xmlAttrPtr attr;
|
||||
|
||||
if(node == NULL) return NULL;
|
||||
do
|
||||
{
|
||||
if(name != NULL)
|
||||
{
|
||||
cur = get_node_recurisve_ex(trav, name, name_ns);
|
||||
if(!cur)
|
||||
return cur;
|
||||
}
|
||||
else
|
||||
cur = trav;
|
||||
|
||||
attr = get_attribute_ex(cur->properties, attribute, attr_ns);
|
||||
if(attr != NULL && strcmp(attr->children->content, value) == 0)
|
||||
return cur;
|
||||
else
|
||||
{
|
||||
if(cur->children != NULL)
|
||||
{
|
||||
xmlNodePtr tmp;
|
||||
tmp = get_node_with_attribute_recursive_ex(cur->children, name, name_ns, attribute, value, attr_ns);
|
||||
if(tmp)
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}while(trav = trav->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNodePtr check_and_resolve_href(xmlNodePtr data)
|
||||
{
|
||||
xmlAttrPtr href;
|
||||
xmlNodePtr ret = data;
|
||||
|
||||
if(!data || !data->properties)
|
||||
return ret;
|
||||
|
||||
href = get_attribute(data->properties, "href");
|
||||
if(href)
|
||||
{
|
||||
/* Internal href try and find node */
|
||||
if(href->children->content[0] == '#')
|
||||
{
|
||||
ret = get_node_with_attribute_recursive(data->doc->children, NULL, "id", &href->children->content[1]);
|
||||
}
|
||||
/* External href....? */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parse_namespace(char *inval, char **value, char **namespace)
|
||||
{
|
||||
char *found = strchr(inval, ':');
|
||||
|
||||
if(found != NULL)
|
||||
{
|
||||
(*namespace) = estrndup(inval, found - inval);
|
||||
(*value) = estrdup(++found);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*value) = estrdup(inval);
|
||||
(*namespace) = NULL;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef PHP_SOAP_XML_H
|
||||
#define PHP_SOAP_XML_H
|
||||
|
||||
#define get_attribute(node, name) get_attribute_ex(node, name, NULL)
|
||||
#define get_node(node, name) get_node_ex(node, name, NULL)
|
||||
#define get_node_recursive(node, name) get_node_recursive_ex(node, name, NULL)
|
||||
#define get_node_with_attribute(node, name, attr, val) get_node_with_attribute_ex(node, name, NULL, attr, val, NULL)
|
||||
#define get_node_with_attribute_recursive(node, name, attr, val) get_node_with_attribute_recursive_ex(node, name, NULL, attr, val, NULL)
|
||||
#define attr_is_equal(node, name) attr_is_equal_ex(node, name, NULL)
|
||||
|
||||
xmlNsPtr attr_find_ns(xmlAttrPtr node);
|
||||
xmlNsPtr node_find_ns(xmlNodePtr node);
|
||||
int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns);
|
||||
int node_is_equal_ex(xmlNodePtr node, char *name, char *ns);
|
||||
xmlAttrPtr get_attribute_ex(xmlAttrPtr node,char *name, char *ns);
|
||||
xmlNodePtr get_node_ex(xmlNodePtr node,char *name, char *ns);
|
||||
xmlNodePtr get_node_recurisve_ex(xmlNodePtr node,char *name, char *ns);
|
||||
xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns);
|
||||
xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns);
|
||||
int parse_namespace(char *inval,char **value,char **namespace);
|
||||
xmlNodePtr check_and_resolve_href(xmlNodePtr data);
|
||||
|
||||
int php_stream_xmlIO_match_wrapper(const char *filename);
|
||||
void *php_stream_xmlIO_open_wrapper(const char *filename);
|
||||
int php_stream_xmlIO_read(void *context, char *buffer, int len);
|
||||
int php_stream_xmlIO_close(void *context);
|
||||
|
||||
#endif
|
||||
-2309
File diff suppressed because it is too large.
Load diff
@@ -1,2 +0,0 @@
|
||||
SPL
|
||||
Marcus Boerger
|
||||
Whitespace-only changes.
@@ -1,88 +0,0 @@
|
||||
This is an extension that aims to implement some efficient data access
|
||||
interfaces and classes. You'll find the classes documented using php
|
||||
code in the file spl.php.
|
||||
|
||||
There are special SPL interfaces that provides the ability to hook into
|
||||
foreach and array reading/writng. By inheriting these interfaces, instances
|
||||
of the resulting classes can be iterated using the foreach construct or
|
||||
use array read write notation.
|
||||
|
||||
Look into the examples subdirectory for some basic examples which will
|
||||
demonstracte this.
|
||||
|
||||
Also some classes of extensions like SQLite inherit SPL interfaces so that
|
||||
they take advantage of the foreach or array overloading.
|
||||
|
||||
1) Iterators
|
||||
|
||||
Iterator is design pattern that allows to enumerate and list all elements of
|
||||
a collection whatsoever using an oo protocol. The minimalistic Iterator needs
|
||||
a method that returns the current value, a method that moves to the next value
|
||||
and a method that checks whether or not the Iterator can provide more elements.
|
||||
|
||||
In SPL this basich Iterator is defined by the interface spl_forward:
|
||||
|
||||
interface spl_forward {
|
||||
function current();
|
||||
function next();
|
||||
function has_more();
|
||||
}
|
||||
|
||||
This basic Iterator does not allow to rewind itself nor does it in anyway
|
||||
support to name the values by some kind association as key/value mappings
|
||||
provided by the standard PHP arrays. All these additions to the basic Iterator
|
||||
are done in specialized interfaces as described in detail in the file spl.php.
|
||||
|
||||
SPL allows to hook into the engine opcodes that realize the foreach construct.
|
||||
This construct normally works on arrays the following way. First it rewinds
|
||||
the current array position to the beginning. Then it loops through the whole
|
||||
array by first checking whether or not the end of the array is reached and
|
||||
if not returning the current array value and or key. After that it move the
|
||||
current array pointer forward and does starts the loop process again. As you
|
||||
can see this perfectly maps to the interface spl_forward. So the foreach
|
||||
hooking simply checks whether or not the variable passed to foreach is an
|
||||
object of a class implementing the interface spl_forward. The foreach hook
|
||||
can be activated by --enable-spl-foreach which is on by default.
|
||||
|
||||
class it implements spl_forward...
|
||||
$obj = new it();
|
||||
foreach($obj as $value) ...
|
||||
|
||||
2) Arrays
|
||||
|
||||
Arrays in general, not specifically PHP arrays, provide a collection of pairs
|
||||
normally referred to as key and value. A PHP object consists of properties and
|
||||
a class type specifing the methods available for the object. SPL now allows
|
||||
this to be combined using the spl_array_<xy> interfaces.
|
||||
|
||||
The minimalistic array interface is spl_array_read which only support reading:
|
||||
|
||||
interface spl_array_read {
|
||||
function exists($key);
|
||||
function get($key);
|
||||
}
|
||||
|
||||
Any instance of a class that implements spl_array_read can be used with array
|
||||
read notation when the corresponding hook is activated --enable-spl-array-read.
|
||||
|
||||
class ar implements spl_array_read...
|
||||
$obj = new ar();
|
||||
$value = $obj[$key];
|
||||
|
||||
SPL also supports the write notation by the interface spl_array_access:
|
||||
|
||||
interface spl_array_access extends spl_array_read {
|
||||
function set($value, $index);
|
||||
}
|
||||
|
||||
When the array write hook is activated by --enable-spl-array-write the
|
||||
following can be done:
|
||||
|
||||
class ar implements spl_array_access...
|
||||
$obj = new ar();
|
||||
$value = $obj[$key];
|
||||
$obj[$key] = $value;
|
||||
|
||||
However this hook should only be activated when it is made use of, since it
|
||||
slows down noticeable. That is the case because first there is some not used
|
||||
overhead and second the overhead is in one the most often used opcodes.
|
||||
@@ -1,98 +0,0 @@
|
||||
SQLite is the first extension that makes use of SPL automatically by simply
|
||||
enabling both.
|
||||
|
||||
SQLite offers four access strategies:
|
||||
1) sqlite_query + sqlite_fetch_array
|
||||
2) sqlite_unbuffered_query + sqlite_fetch_array
|
||||
3) sqlite_query + iterators (sqlite_current)
|
||||
4) sqlite_unbuffered_query + iterators (sqlite_current)
|
||||
5) sqlite_array_query
|
||||
|
||||
1) and 3) do "over eager evaluating" since they fetch all rows directly.
|
||||
|
||||
2) does "eager evaluating". It always fetches the next row but doesn't
|
||||
keep the current row, so that it must be stored elsewhere if it must be
|
||||
accessed more then once. For instance this happens when you need to access
|
||||
columns separately.
|
||||
|
||||
4) does "eager evaluating". But in contrast to 2) it keeps the current row
|
||||
hence its name.
|
||||
|
||||
There is no efficient way for "lazy or just in time evaluating" so 4) should
|
||||
be the best case. And 4) also enables the foreach trick.
|
||||
|
||||
5) does a full buffered fetch and returns the complete result into an array.
|
||||
As long as you only have a few rows in your result this is very fast and of
|
||||
course it is very flexible since you can access any column/row as often you
|
||||
like and in any order you like. But it needs to store the full result what
|
||||
is called "eager evaluating".
|
||||
|
||||
Speedwise analysis:
|
||||
|
||||
I compared a database using a table of round about 200 rows with 3 columns.
|
||||
I measured the case where 10 rows are returned, since i guess this is a
|
||||
value often taken as default list size in web applications. However i did
|
||||
that 10 times because the loop initialization is the slowest part of foreach
|
||||
overloading. Since we are only interested in the relative effect foreach
|
||||
overloading has i stiped the setup part and used a query result iteration
|
||||
that does nothing. That means i run 'php -h' in the profiler first and then
|
||||
profiled every single case. For completeness i also computed the values
|
||||
including the setup process.
|
||||
|
||||
Method, without setup, with setup
|
||||
1) 100.00% 100.00%
|
||||
2) 89.32% 97.16%
|
||||
3) 88.35% 96.90%
|
||||
|
||||
Furthermore i did some more checks and found out that the loop process using
|
||||
foreach overloading (2) takes a constant time while it seems that the time
|
||||
needed to add more rows to the array increases with the number of rows being
|
||||
already in the array. As a result (2) is faster than (3) after round about 45
|
||||
rows.
|
||||
|
||||
The loop codes used:
|
||||
|
||||
1) Unbuffered query
|
||||
|
||||
<?php
|
||||
$dbname = dirname(__FILE__).'/profile.sqlite';
|
||||
$db = sqlite_factory($dbname);
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$res = $db->unbuffered_query("SELECT idx, name, size from files LIMIT 10", SQLITE_NUM);
|
||||
while ($res->has_more()) {
|
||||
// var_dump($res->current());
|
||||
$res->current();
|
||||
$res->next();
|
||||
}
|
||||
}
|
||||
echo "DONE!\n";
|
||||
?>
|
||||
|
||||
2) Unbuffered query using foreach overloading
|
||||
|
||||
<?php
|
||||
$dbname = dirname(__FILE__).'/profile.sqlite';
|
||||
$db = sqlite_factory($dbname);
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
foreach($db->unbuffered_query("SELECT idx, name, size from files LIMIT 10", SQLITE_NUM) as $row) {
|
||||
// var_dump($row);
|
||||
}
|
||||
}
|
||||
echo "DONE!\n";
|
||||
?>
|
||||
|
||||
3) Array query method
|
||||
|
||||
<?php
|
||||
$dbname = dirname(__FILE__).'/profile.sqlite';
|
||||
$db = sqlite_factory($dbname);
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
foreach($db->array_query("SELECT idx, name, size from files LIMIT 10", SQLITE_NUM) as $row) {
|
||||
// var_dump($row);
|
||||
}
|
||||
}
|
||||
echo "DONE!\n";
|
||||
?>
|
||||
@@ -1,13 +0,0 @@
|
||||
This is the ToDo of ext/spl:
|
||||
|
||||
- spl::array_access cals set() which is supposed to return a value.
|
||||
Currently you *must* return a value even when it is not used.
|
||||
$obj[$idx] = $val; // doesn't use the return value
|
||||
$x = $obj[$idx] = $val; // here it is used
|
||||
Since array_access.phpt is a test with a return value there
|
||||
should be a test without a return value. Maybe an error message
|
||||
is required in case there is no return value.
|
||||
|
||||
- spl::array_access_ex is not completely done and not tested.
|
||||
|
||||
If you have further questions: mailto:helly@php.net
|
||||
@@ -1,41 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension SPL
|
||||
|
||||
PHP_ARG_ENABLE(spl, enable SPL suppport,
|
||||
[ --enable-spl Enable Standard PHP Library])
|
||||
|
||||
dnl first enable/disable all hooks
|
||||
|
||||
PHP_ARG_ENABLE(spl, enable all hooks,
|
||||
[ --enable-spl-hook-all SPL: Enable all hooks])
|
||||
|
||||
dnl now all single enable/disable for hooks
|
||||
|
||||
PHP_ARG_ENABLE(spl, enable hook on foreach,
|
||||
[ --disable-spl-foreach SPL: Disable hook on forach], yes)
|
||||
|
||||
PHP_ARG_ENABLE(spl, enable hook on array read,
|
||||
[ --enable-spl-array-read SPL: Enable hook on array read])
|
||||
|
||||
PHP_ARG_ENABLE(spl, enable hook on array write,
|
||||
[ --enable-spl-array-write SPL: Enable hook on array write (+read)])
|
||||
|
||||
dnl last do checks on hooks
|
||||
|
||||
if test "$PHP_SPL_HOOK_ALL" != "no" -o "$PHP_SPL_FOREACH" != "no"; then
|
||||
AC_DEFINE(SPL_FOREACH, 1, [Activate opcode hook on foreach])
|
||||
PHP_SPL="yes"
|
||||
fi
|
||||
if test "$PHP_SPL_HOOK_ALL" != "no" -o "$PHP_SPL_ARRAY_READ" != "no" -o "$PHP_SPL_ARRAY_WRITE" != "no"; then
|
||||
AC_DEFINE(SPL_ARRAY_READ, 1, [Activate opcode hook on array read])
|
||||
PHP_SPL="yes"
|
||||
fi
|
||||
if test "$PHP_SPL_HOOK_ALL" != "no" -o "$PHP_SPL_ARRAY_WRITE" != "no"; then
|
||||
AC_DEFINE(SPL_ARRAY_WRITE, 1, [Activate opcode hook on array write])
|
||||
PHP_SPL="yes"
|
||||
fi
|
||||
|
||||
if test "$PHP_SPL" != "no"; then
|
||||
AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard Php Library) support])
|
||||
PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_foreach.c spl_array.c, $ext_shared)
|
||||
fi
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* dba array utility
|
||||
*
|
||||
* Usage php dba_dump <file> <handler> <key> [<value>]
|
||||
*
|
||||
* If <value> is specified then <key> is set to <value> in <file>.
|
||||
* Else the value of <key> is printed only.
|
||||
*
|
||||
* Note: configure with --enable-dba
|
||||
*
|
||||
* (c) Marcus Boerger
|
||||
*/
|
||||
|
||||
class dba_array implements spl_array_access {
|
||||
private $db;
|
||||
|
||||
function __construct($file, $handler)
|
||||
{
|
||||
$this->db = dba_popen($file, "c", $handler);
|
||||
if (!$this->db) {
|
||||
throw new exception("Databse could not be opened");
|
||||
}
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
dba_close($this->db);
|
||||
}
|
||||
|
||||
function get($name)
|
||||
{
|
||||
$data = dba_fetch($name, $this->db);
|
||||
if($data) {
|
||||
if (ini_get('magic_quotes_runtime')) {
|
||||
$data = stripslashes($data);
|
||||
}
|
||||
return unserialize($data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
function set($name, $value)
|
||||
{
|
||||
dba_replace($name, serialize($value), $this->db);
|
||||
return $value;
|
||||
}
|
||||
|
||||
function exists($name)
|
||||
{
|
||||
return dba_exists($name, $this->db);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if ($argc > 2) {
|
||||
$dba = new dba_array($argv[1], $argv[2]);
|
||||
if ($dba && $argc > 3) {
|
||||
if ($argc > 4) {
|
||||
$dba[$argv[3]] = $argv[4];
|
||||
}
|
||||
var_dump(array('Index' => $argv[3], 'Value' => $dba[$argv[3]]));
|
||||
}
|
||||
$dba = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Not enough parameters\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
catch (exception $err) {
|
||||
var_dump($err);
|
||||
exit(1);
|
||||
}
|
||||
?>
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* dba dump utility
|
||||
*
|
||||
* Usage php dba_dump <file> <handler>
|
||||
*
|
||||
* Note: configure with --enable-dba
|
||||
*
|
||||
* (c) Marcus Boerger
|
||||
*/
|
||||
|
||||
class dba_reader implements spl_sequence_assoc
|
||||
{
|
||||
|
||||
private $db = NULL;
|
||||
private $key = false;
|
||||
private $val = false;
|
||||
|
||||
function __construct($file, $handler) {
|
||||
$this->db = dba_open($file, 'r', $handler);
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
if ($this->db) {
|
||||
dba_close($this->db);
|
||||
}
|
||||
}
|
||||
|
||||
function rewind() {
|
||||
if ($this->db) {
|
||||
$this->key = dba_firstkey($this->db);
|
||||
}
|
||||
}
|
||||
|
||||
function current() {
|
||||
return $this->val;
|
||||
}
|
||||
|
||||
function next() {
|
||||
if ($this->db) {
|
||||
$this->key = dba_nextkey($this->db);
|
||||
if ($this->key !== false) {
|
||||
$this->val = dba_fetch($this->key, $this->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function has_more() {
|
||||
if ($this->db && $this->key !== false) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function key() {
|
||||
return $this->key;
|
||||
}
|
||||
}
|
||||
|
||||
$db = new dba_reader($argv[1], $argv[2]);
|
||||
foreach($db as $key => $val) {
|
||||
echo "'$key' => '$val'\n";
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_spl.h"
|
||||
#include "spl_functions.h"
|
||||
#include "spl_engine.h"
|
||||
#include "spl_foreach.h"
|
||||
#include "spl_array.h"
|
||||
|
||||
#ifdef COMPILE_DL_SPL
|
||||
ZEND_GET_MODULE(spl)
|
||||
#endif
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(spl)
|
||||
|
||||
/* {{{ spl_functions
|
||||
*/
|
||||
function_entry spl_functions[] = {
|
||||
PHP_FE(spl_classes, NULL)
|
||||
PHP_FE(class_parents, NULL)
|
||||
PHP_FE(class_implements, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_module_entry
|
||||
*/
|
||||
zend_module_entry spl_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"spl",
|
||||
spl_functions,
|
||||
PHP_MINIT(spl),
|
||||
PHP_MSHUTDOWN(spl),
|
||||
PHP_RINIT(spl),
|
||||
PHP_RSHUTDOWN(spl),
|
||||
PHP_MINFO(spl),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
zend_class_entry *spl_ce_iterator;
|
||||
zend_class_entry *spl_ce_forward;
|
||||
zend_class_entry *spl_ce_assoc;
|
||||
zend_class_entry *spl_ce_sequence;
|
||||
zend_class_entry *spl_ce_forward_assoc;
|
||||
zend_class_entry *spl_ce_sequence_assoc;
|
||||
zend_class_entry *spl_ce_array_read;
|
||||
zend_class_entry *spl_ce_array_access;
|
||||
zend_class_entry *spl_ce_array_access_ex;
|
||||
zend_class_entry *spl_ce_array_writer;
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
zend_class_entry *spl_ce_array_writer_default;
|
||||
#endif /* SPL_ARRAY_WRITE */
|
||||
|
||||
/* {{{ spl_functions_none
|
||||
*/
|
||||
function_entry spl_functions_none[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
static unsigned char first_of_two_force_ref[] = { 2, BYREF_FORCE, BYREF_NONE };
|
||||
|
||||
/* {{{ spl_array_writer_funcs
|
||||
*/
|
||||
function_entry spl_array_writer_funcs[] = {
|
||||
SPL_CLASS_FE(array_writer_default, __construct, first_of_two_force_ref)
|
||||
SPL_CLASS_FE(array_writer_default, set, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_init_globals
|
||||
*/
|
||||
static void spl_init_globals(zend_spl_globals *spl_globals)
|
||||
{
|
||||
#ifdef SPL_FOREACH
|
||||
ZEND_EXECUTE_HOOK(ZEND_FE_RESET);
|
||||
ZEND_EXECUTE_HOOK(ZEND_FE_FETCH);
|
||||
ZEND_EXECUTE_HOOK(ZEND_SWITCH_FREE);
|
||||
#endif
|
||||
|
||||
#if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE)
|
||||
ZEND_EXECUTE_HOOK(ZEND_FETCH_DIM_R);
|
||||
ZEND_EXECUTE_HOOK(ZEND_FETCH_DIM_W);
|
||||
ZEND_EXECUTE_HOOK(ZEND_FETCH_DIM_RW);
|
||||
#endif
|
||||
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
ZEND_EXECUTE_HOOK(ZEND_ASSIGN);
|
||||
#endif /* SPL_ARRAY_WRITE */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION(spl)
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(spl)
|
||||
{
|
||||
ZEND_INIT_MODULE_GLOBALS(spl, spl_init_globals, NULL);
|
||||
|
||||
REGISTER_SPL_INTERFACE(iterator);
|
||||
REGISTER_SPL_INTF_FUNC(iterator, new_iterator);
|
||||
|
||||
REGISTER_SPL_INTERFACE(forward);
|
||||
REGISTER_SPL_INTF_FUNC(forward, current);
|
||||
REGISTER_SPL_INTF_FUNC(forward, next);
|
||||
REGISTER_SPL_INTF_FUNC(forward, has_more);
|
||||
|
||||
REGISTER_SPL_INTERFACE(sequence);
|
||||
REGISTER_SPL_INTF_FUNC(sequence, rewind);
|
||||
REGISTER_SPL_IMPLEMENT(sequence, forward);
|
||||
|
||||
REGISTER_SPL_INTERFACE(assoc);
|
||||
REGISTER_SPL_INTF_FUNC(assoc, key);
|
||||
|
||||
REGISTER_SPL_INTERFACE(forward_assoc);
|
||||
REGISTER_SPL_IMPLEMENT(forward_assoc, assoc);
|
||||
REGISTER_SPL_IMPLEMENT(forward_assoc, forward);
|
||||
|
||||
REGISTER_SPL_INTERFACE(sequence_assoc);
|
||||
REGISTER_SPL_IMPLEMENT(sequence_assoc, forward_assoc);
|
||||
REGISTER_SPL_IMPLEMENT(sequence_assoc, sequence);
|
||||
|
||||
REGISTER_SPL_INTERFACE(array_read);
|
||||
REGISTER_SPL_INTF_FUNC(array_read, get);
|
||||
REGISTER_SPL_INTF_FUNC(array_read, exists);
|
||||
|
||||
REGISTER_SPL_INTERFACE(array_access);
|
||||
REGISTER_SPL_IMPLEMENT(array_access, array_read);
|
||||
REGISTER_SPL_INTF_FUNC(array_access, set);
|
||||
|
||||
REGISTER_SPL_INTERFACE(array_access_ex);
|
||||
REGISTER_SPL_IMPLEMENT(array_access_ex, array_access);
|
||||
REGISTER_SPL_INTF_FUNC(array_access_ex, new_writer);
|
||||
|
||||
REGISTER_SPL_INTERFACE(array_writer);
|
||||
REGISTER_SPL_INTF_FUNC(array_writer, set);
|
||||
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
REGISTER_SPL_STD_CLASS(array_writer_default, spl_array_writer_default_create);
|
||||
REGISTER_SPL_FUNCTIONS(array_writer_default, spl_array_writer_funcs);
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RINIT_FUNCTION(spl)
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(spl)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION(spl)
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(spl)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION(spl)
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(spl)
|
||||
{
|
||||
SPL_DEBUG(fprintf(stderr, "%s\n", "Shutting down SPL");)
|
||||
|
||||
#ifdef SPL_FOREACH
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_FE_RESET);
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_FE_FETCH);
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_SWITCH_FREE);
|
||||
#endif
|
||||
|
||||
#if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE)
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_FETCH_DIM_R);
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_FETCH_DIM_W);
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_FETCH_DIM_RW);
|
||||
#endif
|
||||
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
ZEND_EXECUTE_HOOK_RESTORE(ZEND_ASSIGN);
|
||||
#endif /* SPL_ARRAY_WRITE */
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO(spl)
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(spl)
|
||||
{
|
||||
#ifdef SPL_FOREACH
|
||||
char *foreach = "beta";
|
||||
#else /* SPL_ARRAY_WRITE */
|
||||
char *foreach = "beta, not hooked";
|
||||
#endif
|
||||
#ifdef SPL_ARRAY_READ
|
||||
char *array_read = "beta";
|
||||
#else /* SPL_ARRAY_WRITE */
|
||||
char *array_read = "beta, not hooked";
|
||||
#endif
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
char *array_write = "beta";
|
||||
#else /* SPL_ARRAY_WRITE */
|
||||
char *array_write = "beta, not hooked";
|
||||
#endif /* SPL_ARRAY_WRITE */
|
||||
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "SPL support", "enabled");
|
||||
php_info_print_table_row(2, "iterator", foreach);
|
||||
php_info_print_table_row(2, "forward", foreach);
|
||||
php_info_print_table_row(2, "sequence", foreach);
|
||||
php_info_print_table_row(2, "assoc", foreach);
|
||||
php_info_print_table_row(2, "forward_assoc", foreach);
|
||||
php_info_print_table_row(2, "sequence_assoc", foreach);
|
||||
php_info_print_table_row(2, "array_read", array_read);
|
||||
php_info_print_table_row(2, "array_access", array_write);
|
||||
php_info_print_table_row(2, "array_access_ex", array_write);
|
||||
php_info_print_table_row(2, "array_writer", array_write);
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ class_parents
|
||||
*/
|
||||
PHP_FUNCTION(class_parents)
|
||||
{
|
||||
zval *obj;
|
||||
zend_class_entry *parent_class;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
array_init(return_value);
|
||||
parent_class = Z_OBJCE_P(obj)->parent;
|
||||
while (parent_class) {
|
||||
spl_add_class_name(return_value, parent_class TSRMLS_CC);
|
||||
parent_class = parent_class->parent;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ class_implements
|
||||
*/
|
||||
PHP_FUNCTION(class_implements)
|
||||
{
|
||||
zval *obj;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
array_init(return_value);
|
||||
spl_add_interfaces(return_value, Z_OBJCE_P(obj) TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define SPL_ADD_CLASS(class_name) \
|
||||
spl_add_classes(&spl_ce_ ## class_name, return_value TSRMLS_CC)
|
||||
|
||||
/* {{{ spl_classes */
|
||||
PHP_FUNCTION(spl_classes)
|
||||
{
|
||||
array_init(return_value);
|
||||
|
||||
SPL_ADD_CLASS(iterator);
|
||||
SPL_ADD_CLASS(forward);
|
||||
SPL_ADD_CLASS(sequence);
|
||||
SPL_ADD_CLASS(assoc);
|
||||
SPL_ADD_CLASS(forward_assoc);
|
||||
SPL_ADD_CLASS(sequence_assoc);
|
||||
SPL_ADD_CLASS(array_read);
|
||||
SPL_ADD_CLASS(array_access);
|
||||
SPL_ADD_CLASS(array_access_ex);
|
||||
SPL_ADD_CLASS(array_writer);
|
||||
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
SPL_ADD_CLASS(array_writer_default);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef PHP_SPL_H
|
||||
#define PHP_SPL_H
|
||||
|
||||
#include "php.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#if 0
|
||||
#define SPL_DEBUG(x) x
|
||||
#else
|
||||
#define SPL_DEBUG(x)
|
||||
#endif
|
||||
|
||||
extern zend_module_entry spl_module_entry;
|
||||
#define phpext_spl_ptr &spl_module_entry
|
||||
|
||||
#if defined(PHP_WIN32) && !defined(COMPILE_DL_SPL)
|
||||
#undef phpext_spl
|
||||
#define phpext_spl NULL
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(spl);
|
||||
PHP_MSHUTDOWN_FUNCTION(spl);
|
||||
PHP_RINIT_FUNCTION(spl);
|
||||
PHP_RSHUTDOWN_FUNCTION(spl);
|
||||
PHP_MINFO_FUNCTION(spl);
|
||||
|
||||
#define ZEND_EXECUTE_HOOK_PTR(name) \
|
||||
opcode_handler_t handler_ ## name
|
||||
|
||||
#define ZEND_EXECUTE_HOOK(name) \
|
||||
spl_globals->handler_ ## name = zend_opcode_handlers[name]; \
|
||||
zend_opcode_handlers[name] = spl_handler_ ## name
|
||||
|
||||
#define ZEND_EXECUTE_HOOK_RESTORE(name) \
|
||||
zend_opcode_handlers[name] = SPL_G(handler_ ## name)
|
||||
|
||||
#define ZEND_EXECUTE_HOOK_ORIGINAL(name) \
|
||||
return SPL_G(handler_ ## name)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
|
||||
|
||||
#define ZEND_EXECUTE_HOOK_FUNCTION(name) \
|
||||
int spl_handler_ ## name(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(spl)
|
||||
#ifdef SPL_FOREACH
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_FE_RESET);
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_FE_FETCH);
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_SWITCH_FREE);
|
||||
#endif
|
||||
#if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE)
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_FETCH_DIM_R);
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_FETCH_DIM_W);
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_FETCH_DIM_RW);
|
||||
#endif
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
ZEND_EXECUTE_HOOK_PTR(ZEND_ASSIGN);
|
||||
#endif
|
||||
ZEND_END_MODULE_GLOBALS(spl)
|
||||
|
||||
#ifdef ZTS
|
||||
# define SPL_G(v) TSRMG(spl_globals_id, zend_spl_globals *, v)
|
||||
extern int spl_globals_id;
|
||||
#else
|
||||
# define SPL_G(v) (spl_globals.v)
|
||||
extern zend_spl_globals spl_globals;
|
||||
#endif
|
||||
|
||||
extern zend_class_entry *spl_ce_iterator;
|
||||
extern zend_class_entry *spl_ce_forward;
|
||||
extern zend_class_entry *spl_ce_sequence;
|
||||
extern zend_class_entry *spl_ce_assoc;
|
||||
extern zend_class_entry *spl_ce_forward_assoc;
|
||||
extern zend_class_entry *spl_ce_sequence_assoc;
|
||||
extern zend_class_entry *spl_ce_array_read;
|
||||
extern zend_class_entry *spl_ce_array_access;
|
||||
extern zend_class_entry *spl_ce_array_access_ex;
|
||||
extern zend_class_entry *spl_ce_array_writer;
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
extern zend_class_entry *spl_ce_array_writer_default;
|
||||
#endif /* SPL_ARRAY_WRITE */
|
||||
|
||||
PHP_FUNCTION(spl_classes);
|
||||
PHP_FUNCTION(class_parents);
|
||||
PHP_FUNCTION(class_implements);
|
||||
|
||||
#endif /* PHP_SPL_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
-304
@@ -1,304 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* Standard PHP Library
|
||||
*
|
||||
* (c) M.Boerger 2003
|
||||
*/
|
||||
|
||||
/*! \brief Interface to foreach() construct
|
||||
*
|
||||
* Any class that implements this interface can for example be used as
|
||||
* the input parameter to foreach() calls which would normally be an
|
||||
* array.
|
||||
*
|
||||
* The only thing a class has to do is
|
||||
*/
|
||||
interface spl_iterator {
|
||||
|
||||
/*! \brief Create a new iterator
|
||||
*
|
||||
* used for example in foreach() operator.
|
||||
*/
|
||||
function new_iterator();
|
||||
}
|
||||
|
||||
/*! \brief Simple forward iterator
|
||||
*
|
||||
* Any class that implements this interface can be used as the
|
||||
* return of a foreach interface. And hence the class itself
|
||||
* can be used as a parameter to be iterated (normally an array).
|
||||
*
|
||||
* \code
|
||||
class c implements spl_iterator, spl_forward {
|
||||
private $num = 0;
|
||||
function new_iterator() {
|
||||
$this->num = 0;
|
||||
return $this;
|
||||
}
|
||||
function current() {
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
return $this->num < 5;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
|
||||
foreach($t as $num) {
|
||||
echo "$num\n";
|
||||
}
|
||||
\endcode
|
||||
*
|
||||
* A very interesting usage scenario are for example database queries.
|
||||
* Without this interface you need to do it without foreach or fetch the
|
||||
* whole rowset into an array.
|
||||
*
|
||||
* In the above code the class implements both the foreach and the
|
||||
* forward interface. Doing this you cannot have nested foreach calls.
|
||||
* If you need this you must split the two parts.
|
||||
*
|
||||
* \code
|
||||
class c implements spl_iterator {
|
||||
public $max = 3;
|
||||
function new_iterator() {
|
||||
return new c_iter($this);
|
||||
}
|
||||
}
|
||||
class c_iter implements spl_forward {
|
||||
private $obj;
|
||||
private $num = 0;
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function current() {
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
return $this->num < $this->obj->max;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
|
||||
foreach($t as $outer) {
|
||||
foreach($t as $inner) {
|
||||
echo "$outer,$inner\n";
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*
|
||||
* You can also use this interface with the for() construct.
|
||||
*
|
||||
* \code
|
||||
class c implements spl_iterator {
|
||||
public $max = 3;
|
||||
function new_iterator() {
|
||||
return new c_iter($this);
|
||||
}
|
||||
}
|
||||
class c_iter implements spl_forward {
|
||||
private $obj;
|
||||
private $num = 0;
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function current() {
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
return $this->num < $this->obj->max;
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
|
||||
for ($iter = $t->new_iterator(); $iter->has_more(); $iter->next()) {
|
||||
echo $iter->current() . "\n";
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
interface spl_forward {
|
||||
|
||||
/*! \brief Retrieve the current currentent
|
||||
*
|
||||
* \return \c mixed current element or \c false if no more elements
|
||||
*/
|
||||
function current();
|
||||
|
||||
/*! \brief Forward to next element.
|
||||
*/
|
||||
function next();
|
||||
|
||||
/*! \brief Check if more elements are available.
|
||||
*
|
||||
* \return \c bool whether or not more elements are available
|
||||
*/
|
||||
function has_more();
|
||||
}
|
||||
|
||||
/*! \brief A restartable iterator.
|
||||
*
|
||||
* This iterator allows you to implement a restartable iterator. That
|
||||
* means the iterator can be rewind to the first element after accessing
|
||||
* any number of elements.
|
||||
*
|
||||
* \note If you use sequence in foreach then rewind() will be called
|
||||
* first.
|
||||
*/
|
||||
interface spl_sequence extends spl_forward {
|
||||
|
||||
/*! Restart the sequence by positioning it to the first element.
|
||||
*/
|
||||
function rewind();
|
||||
}
|
||||
|
||||
/*! \brief associative interface
|
||||
*
|
||||
* This interface allows to implement associative iterators
|
||||
* and containers.
|
||||
*/
|
||||
interface spl_assoc {
|
||||
|
||||
/*! \brief Retrieve the current elements key
|
||||
*
|
||||
* \return \c mixed current key or \c false if no more elements
|
||||
*/
|
||||
function key();
|
||||
}
|
||||
|
||||
/*! \brief associative foreach() interface
|
||||
*
|
||||
* This interface extends the forward interface to support keys.
|
||||
* With this interface you can do:
|
||||
* \code
|
||||
$t = new c();
|
||||
foreach($t as $key => $elem).
|
||||
\endcode
|
||||
*/
|
||||
interface spl_assoc_forward implements spl_forward, spl_assoc {
|
||||
}
|
||||
|
||||
/*! \brief associative sequence
|
||||
*/
|
||||
interface spl_assoc_sequence implements spl_sequence, spl_assoc {
|
||||
}
|
||||
|
||||
/*! \brief array read only access for objects
|
||||
*/
|
||||
interface spl_array_read {
|
||||
|
||||
/*! Check whether or not the given index exists.
|
||||
* The returned value is interpreted as converted to bool.
|
||||
*/
|
||||
function exists($index);
|
||||
|
||||
/*! Read the value at position $index.
|
||||
* This function is only beeing called if exists() returns true.
|
||||
*/
|
||||
function get($index);
|
||||
}
|
||||
|
||||
/*! \brief array read/write access for objects.
|
||||
*
|
||||
* The following example shows how to use an array_writer:
|
||||
* \code
|
||||
class array_emulation implemets spl_array_access {
|
||||
private $ar = array();
|
||||
function exists($index) {
|
||||
return array_key_exists($index, $this->ar);
|
||||
}
|
||||
function get($index) {
|
||||
return $this->ar[$index];
|
||||
}
|
||||
function set($index, $value) {
|
||||
$this->ar[$index] = $value;
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
interface spl_array_access extends spl_array_read {
|
||||
|
||||
/*! Set the value identified by $index to $value.
|
||||
*/
|
||||
function set($value, $index);
|
||||
}
|
||||
|
||||
/*! \brief array read/write access with customized array_writer
|
||||
*
|
||||
* The internal structure requires that write access via interfaces
|
||||
* is divided into two parts. First the index is used to create an
|
||||
* array_writer which will later receive the new value and calls the
|
||||
* containers set() method with appropriate parameters.
|
||||
*
|
||||
* Sometimes it is helpfull to overwrite this behavior and have your
|
||||
* own implementation for the array_writer.
|
||||
*
|
||||
* The following example shows how to use a customized array_writer:
|
||||
* \code
|
||||
class array_emulation_ex extends array_emulation implemets spl_array_access_ex {
|
||||
private $last_index = NULL;
|
||||
function new_writer($index) {
|
||||
$last_index = $index;
|
||||
return new array_write(&$this, $index);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
interface spl_array_access_ex extends spl_array_access {
|
||||
|
||||
/*! Create an array_writer interface for the specified index.
|
||||
*
|
||||
* If your container uses array_access instead of array_access_ex
|
||||
* the following code would be equal to the internal new_writer()
|
||||
* method:
|
||||
\code
|
||||
function new_writer($index) {
|
||||
return new array_write(&$this, $index);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
function new_writer($index);
|
||||
}
|
||||
|
||||
/*! \brief array writer interface
|
||||
*
|
||||
* for every write access to an array_access instance an array_writer
|
||||
* is created which receives the originating object and the index as
|
||||
* parameters for the constructor call.
|
||||
*
|
||||
* The following shows the equivalent php code for the default
|
||||
* implementation array_write.
|
||||
* \code
|
||||
class array_write implements array_writer {
|
||||
private $obj;
|
||||
private $idx;
|
||||
function __construct(&$obj, $index = null) {
|
||||
$this->obj = $obj;
|
||||
$this->idx = $index;
|
||||
}
|
||||
function set($value) {
|
||||
return $this->obj->set($this->idx, $value);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*
|
||||
* See array_access for more.
|
||||
*/
|
||||
interface spl_array_writer {
|
||||
|
||||
/*! Set the corresponding value to $value.
|
||||
*/
|
||||
function set($value);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute_locks.h"
|
||||
|
||||
#include "php_spl.h"
|
||||
#include "spl_functions.h"
|
||||
#include "spl_engine.h"
|
||||
#include "spl_array.h"
|
||||
|
||||
#define DELETE_ZVAL(z) \
|
||||
if ((z)->refcount < 2) { \
|
||||
zval_dtor(z); \
|
||||
FREE_ZVAL(z); /* maybe safe_free_zval_ptr is needed for the uninitialised things */ \
|
||||
}
|
||||
|
||||
#define DELETE_RET_ZVAL(z) \
|
||||
if ((z)->refcount < 3) { \
|
||||
zval_dtor(z); \
|
||||
FREE_ZVAL(z); /* maybe safe_free_zval_ptr is needed for the uninitialised things */ \
|
||||
}
|
||||
|
||||
#define AI_PTR_2_PTR_PTR(ai) \
|
||||
(ai).ptr_ptr = &((ai).ptr)
|
||||
|
||||
/* {{{ spl_array_writer_default stuff */
|
||||
typedef struct {
|
||||
zval *obj;
|
||||
zval *idx;
|
||||
int locked;
|
||||
} spl_array_writer_object;
|
||||
|
||||
static zend_class_entry *spl_array_writer_default_get_class(zval *object TSRMLS_DC)
|
||||
{
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
return spl_ce_array_writer_default;
|
||||
#else
|
||||
return (zend_class_entry *)1; /* force an error here: this ensures not equal */
|
||||
#endif
|
||||
}
|
||||
|
||||
static zend_object_handlers spl_array_writer_default_handlers = {
|
||||
ZEND_OBJECTS_STORE_HANDLERS,
|
||||
|
||||
NULL, /* read_property */
|
||||
NULL, /* write_property */
|
||||
NULL, /* get_property_ptr */
|
||||
NULL, /* get_property_zval_ptr */
|
||||
NULL, /* get */
|
||||
NULL, /* set */
|
||||
NULL, /* has_property */
|
||||
NULL, /* unset_property */
|
||||
NULL, /* get_properties */
|
||||
NULL, /* get_method */
|
||||
NULL, /* call_method */
|
||||
NULL, /* get_constructor */
|
||||
spl_array_writer_default_get_class, /* get_class_entry */
|
||||
NULL, /* get_class_name */
|
||||
NULL /* compare_objects */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_array_writer_dtor */
|
||||
void spl_array_writer_default_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||
{
|
||||
spl_array_writer_object *writer = (spl_array_writer_object*) object;
|
||||
|
||||
if (writer->obj)
|
||||
{
|
||||
writer->obj->refcount--;
|
||||
/* DELETE_ZVAL(writer->obj); */
|
||||
}
|
||||
if (writer->idx)
|
||||
{
|
||||
if (writer->locked) {
|
||||
PZVAL_UNLOCK(writer->idx);
|
||||
} else {
|
||||
writer->idx->refcount--;
|
||||
DELETE_ZVAL(writer->idx);
|
||||
}
|
||||
}
|
||||
efree(writer);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_array_writer_default_create */
|
||||
zend_object_value spl_array_writer_default_create(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
zend_object_value retval;
|
||||
spl_array_writer_object *intern;
|
||||
|
||||
intern = ecalloc(sizeof(spl_array_writer_object), 1);
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, spl_array_writer_default_dtor, NULL TSRMLS_CC);
|
||||
retval.handlers = &spl_array_writer_default_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_array_writer_default_set */
|
||||
void spl_array_writer_default_set(zval *object, zval *newval, zval **retval TSRMLS_DC)
|
||||
{
|
||||
spl_array_writer_object *writer;
|
||||
|
||||
writer = (spl_array_writer_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
spl_begin_method_call_arg_ex2(&writer->obj, NULL, NULL, "set", sizeof("set")-1, retval, writer->idx, newval TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ SPL_CLASS_FUNCTION(array_writer_default, __construct) */
|
||||
SPL_CLASS_FUNCTION(array_writer_default, __construct)
|
||||
{
|
||||
zval *object = getThis();
|
||||
zval *obj, *idx;
|
||||
spl_array_writer_object *writer;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &obj, &idx) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to parse parameters");
|
||||
return;
|
||||
}
|
||||
writer = (spl_array_writer_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
writer->obj = obj; obj->refcount++;
|
||||
writer->idx = idx; idx->refcount++;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ SPL_CLASS_FUNCTION(array_writer_default, set) */
|
||||
SPL_CLASS_FUNCTION(array_writer_default, set)
|
||||
{
|
||||
zval *object = getThis();
|
||||
zval *newval;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &newval) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to parse parameters");
|
||||
return;
|
||||
}
|
||||
spl_array_writer_default_set(object, newval, &return_value TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_fetch_dimension_address */
|
||||
int spl_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC)
|
||||
{
|
||||
zval **container_ptr = spl_get_zval_ptr_ptr(op1, Ts TSRMLS_CC);
|
||||
|
||||
if (spl_is_instance_of(container_ptr, spl_ce_array_read TSRMLS_CC)) {
|
||||
zval **retval = &(T(result->u.var).var.ptr);
|
||||
zval *dim = spl_get_zval_ptr(op2, Ts, &EG(free_op2) TSRMLS_CC);
|
||||
zval *exists;
|
||||
|
||||
/*ALLOC_ZVAL(exists); not needed */
|
||||
spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "exists", sizeof("exists")-1, &exists, dim TSRMLS_CC);
|
||||
if (!i_zend_is_true(exists)) {
|
||||
if (type == BP_VAR_R || type == BP_VAR_RW) {
|
||||
SEPARATE_ZVAL(&dim);
|
||||
convert_to_string_ex(&dim);
|
||||
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(dim));
|
||||
DELETE_ZVAL(dim);
|
||||
}
|
||||
if (type == BP_VAR_R || type == BP_VAR_IS) {
|
||||
DELETE_RET_ZVAL(exists);
|
||||
*retval = &EG(error_zval);
|
||||
(*retval)->refcount++;
|
||||
FREE_OP(Ts, op2, EG(free_op2));
|
||||
SELECTIVE_PZVAL_LOCK(*retval, result);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DELETE_RET_ZVAL(exists);
|
||||
if (type == BP_VAR_R || type == BP_VAR_IS) {
|
||||
spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "get", sizeof("get")-1, retval, dim TSRMLS_CC);
|
||||
(*retval)->refcount--;
|
||||
} else
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
if (spl_is_instance_of(container_ptr, spl_ce_array_access_ex TSRMLS_CC)) {
|
||||
/* array_access_ex instaces have their own way of creating an access_writer */
|
||||
spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "new_writer", sizeof("new_writer")-1, retval, dim TSRMLS_CC);
|
||||
T(result->u.var).var.ptr = *retval;
|
||||
AI_PTR_2_PTR_PTR(T(result->u.var).var);
|
||||
SELECTIVE_PZVAL_LOCK(*retval, result);
|
||||
} else if (spl_is_instance_of(container_ptr, spl_ce_array_access TSRMLS_CC)) {
|
||||
/* array_access instances create the default array_writer: array_write */
|
||||
spl_array_writer_object *writer;
|
||||
spl_instanciate(spl_ce_array_writer_default, retval TSRMLS_CC);
|
||||
T(result->u.var).var.ptr = *retval;
|
||||
AI_PTR_2_PTR_PTR(T(result->u.var).var);
|
||||
writer = (spl_array_writer_object *) zend_object_store_get_object(*retval TSRMLS_CC);
|
||||
writer->obj = *container_ptr;
|
||||
writer->obj->refcount++;
|
||||
writer->idx = dim;
|
||||
PZVAL_LOCK(writer->idx);
|
||||
writer->locked = 1;
|
||||
SELECTIVE_PZVAL_LOCK(*retval, result);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Object must implement spl_array_access for write access");
|
||||
retval = &EG(error_zval_ptr);
|
||||
}
|
||||
SELECTIVE_PZVAL_LOCK(*retval, result);
|
||||
#else
|
||||
zend_error(E_ERROR, "SPL compiled without array write hook");
|
||||
#endif
|
||||
FREE_OP(Ts, op2, EG(free_op2));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_R) */
|
||||
#ifdef SPL_ARRAY_READ
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_R)
|
||||
{
|
||||
if (!spl_fetch_dimension_address(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_R TSRMLS_CC))
|
||||
{
|
||||
if (EX(opline)->extended_value == ZEND_FETCH_ADD_LOCK) {
|
||||
PZVAL_LOCK(*EX_T(EX(opline)->op1.u.var).var.ptr_ptr);
|
||||
}
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
|
||||
AI_PTR_2_PTR_PTR(EX_T(EX(opline)->result.u.var).var);
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FETCH_DIM_R);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_W) */
|
||||
#ifdef SPL_ARRAY_READ
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_W)
|
||||
{
|
||||
if (!spl_fetch_dimension_address(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_W TSRMLS_CC))
|
||||
{
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FETCH_DIM_W);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW) */
|
||||
#ifdef SPL_ARRAY_READ
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW)
|
||||
{
|
||||
if (!spl_fetch_dimension_address(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_RW TSRMLS_CC))
|
||||
{
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FETCH_DIM_RW);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN) */
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN)
|
||||
{
|
||||
zval **writer = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
zval *newval, *retval, *target;
|
||||
znode *result;
|
||||
|
||||
if (writer && *writer && Z_TYPE_PP(writer) == IS_OBJECT) {
|
||||
/* optimization: do pre checks and only test for handlers in case of
|
||||
* spl_array_writer_default, for spl_array_writer we must use the
|
||||
* long way of calling spl_instance
|
||||
* if (spl_is_instance_of(writer, spl_ce_array_writer_default TSRMLS_CC))
|
||||
*/
|
||||
if ((*writer)->value.obj.handlers == &spl_array_writer_default_handlers) {
|
||||
newval = spl_get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2) TSRMLS_CC);
|
||||
spl_array_writer_default_set(*writer, newval, &retval TSRMLS_CC);
|
||||
} else if (spl_is_instance_of(writer, spl_ce_array_writer TSRMLS_CC)) {
|
||||
newval = spl_get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2) TSRMLS_CC);
|
||||
spl_begin_method_call_arg_ex1(writer, NULL, NULL, "set", sizeof("set")-1, &retval, newval TSRMLS_CC);
|
||||
} else {
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN);
|
||||
}
|
||||
} else {
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN);
|
||||
}
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
|
||||
result = &EX(opline)->result;
|
||||
if (result) {
|
||||
if (retval->refcount<2) {
|
||||
if ((*writer)->value.obj.handlers == &spl_array_writer_default_handlers) {
|
||||
spl_array_writer_object *object = (spl_array_writer_object *) zend_object_store_get_object(*writer TSRMLS_CC);
|
||||
target = object->obj;
|
||||
} else {
|
||||
target = *writer;
|
||||
}
|
||||
zend_error(E_WARNING, "Method %s::set() did not return a value, using NULL", Z_OBJCE_P(target)->name);
|
||||
DELETE_ZVAL(retval);
|
||||
DELETE_ZVAL(newval);
|
||||
/* Unfortunately it doesn't work when trying to return newval.
|
||||
* But anyhow it wouldn't make sense...and confuse reference counting and such.
|
||||
*/
|
||||
retval = &EG(uninitialized_zval);
|
||||
} else {
|
||||
retval->refcount--;
|
||||
}
|
||||
EX_T(EX(opline)->result.u.var).var.ptr = retval;
|
||||
AI_PTR_2_PTR_PTR(EX_T(EX(opline)->result.u.var).var);
|
||||
SELECTIVE_PZVAL_LOCK(retval, result);
|
||||
} else {
|
||||
retval->refcount = 1;
|
||||
DELETE_ZVAL(retval);
|
||||
}
|
||||
|
||||
(*writer)->refcount = 1;
|
||||
DELETE_ZVAL(*writer);
|
||||
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
|
||||
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute_locks.h"
|
||||
|
||||
#include "php_spl.h"
|
||||
#include "spl_functions.h"
|
||||
#include "spl_engine.h"
|
||||
|
||||
/* {{{ spl_instanciate */
|
||||
void spl_instanciate(zend_class_entry *pce, zval **object TSRMLS_DC)
|
||||
{
|
||||
ALLOC_ZVAL(*object);
|
||||
object_init_ex(*object, pce);
|
||||
(*object)->refcount = 1;
|
||||
(*object)->is_ref = 1; /* check if this can be hold always */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_instanciate_arg_ex2 */
|
||||
int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC)
|
||||
{
|
||||
zval *object;
|
||||
|
||||
spl_instanciate(pce, &object TSRMLS_CC);
|
||||
|
||||
retval = &EG(uninitialized_zval_ptr);
|
||||
|
||||
spl_call_method(&object, pce, &pce->constructor, pce->constructor->common.function_name, strlen(pce->constructor->common.function_name), retval, NULL TSRMLS_CC, 2, arg1, arg2);
|
||||
*retval = object;
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_get_zval_ptr_ptr
|
||||
Remember to call spl_unlock_ptr_ptr when needed */
|
||||
zval ** spl_get_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC)
|
||||
{
|
||||
if (node->op_type==IS_VAR) {
|
||||
return T(node->u.var).var.ptr_ptr;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_unlock_zval_ptr_ptr */
|
||||
void spl_unlock_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC)
|
||||
{
|
||||
if (node->op_type==IS_VAR) {
|
||||
if (T(node->u.var).var.ptr_ptr) {
|
||||
PZVAL_UNLOCK(*T(node->u.var).var.ptr_ptr);
|
||||
} else if (T(node->u.var).EA.type==IS_STRING_OFFSET) {
|
||||
PZVAL_UNLOCK(T(node->u.var).EA.data.str_offset.str);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_get_zval_ptr */
|
||||
zval * spl_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRMLS_DC)
|
||||
{
|
||||
switch (node->op_type) {
|
||||
case IS_CONST:
|
||||
*should_free = 0;
|
||||
return &node->u.constant;
|
||||
break;
|
||||
case IS_TMP_VAR:
|
||||
return *should_free = &T(node->u.var).tmp_var;
|
||||
break;
|
||||
case IS_VAR:
|
||||
if (T(node->u.var).var.ptr) {
|
||||
PZVAL_UNLOCK(T(node->u.var).var.ptr);
|
||||
*should_free = 0;
|
||||
return T(node->u.var).var.ptr;
|
||||
} else {
|
||||
*should_free = &T(node->u.var).tmp_var;
|
||||
|
||||
switch (T(node->u.var).EA.type) {
|
||||
case IS_STRING_OFFSET: {
|
||||
temp_variable *T = &T(node->u.var);
|
||||
zval *str = T->EA.data.str_offset.str;
|
||||
|
||||
if (T->EA.data.str_offset.str->type != IS_STRING
|
||||
|| (T->EA.data.str_offset.offset<0)
|
||||
|| (T->EA.data.str_offset.str->value.str.len <= T->EA.data.str_offset.offset)) {
|
||||
zend_error(E_NOTICE, "Uninitialized string offset: %d", T->EA.data.str_offset.offset);
|
||||
T->tmp_var.value.str.val = empty_string;
|
||||
T->tmp_var.value.str.len = 0;
|
||||
} else {
|
||||
char c = str->value.str.val[T->EA.data.str_offset.offset];
|
||||
|
||||
T->tmp_var.value.str.val = estrndup(&c, 1);
|
||||
T->tmp_var.value.str.len = 1;
|
||||
}
|
||||
PZVAL_UNLOCK(str);
|
||||
T->tmp_var.refcount=1;
|
||||
T->tmp_var.is_ref=1;
|
||||
T->tmp_var.type = IS_STRING;
|
||||
return &T->tmp_var;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_UNUSED:
|
||||
*should_free = 0;
|
||||
return NULL;
|
||||
break;
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_is_instance_of */
|
||||
int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC)
|
||||
{
|
||||
/* Ensure everything needed is available before checking for the type.
|
||||
*/
|
||||
zend_class_entry *instance_ce;
|
||||
|
||||
if (obj && (instance_ce = spl_get_class_entry(*obj TSRMLS_CC)) != NULL) {
|
||||
return instanceof_function(instance_ce, ce TSRMLS_CC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_implements */
|
||||
spl_is_a spl_implements(zend_class_entry *ce)
|
||||
{
|
||||
register spl_is_a is_a = 0;
|
||||
register int i = ce->num_interfaces;
|
||||
register zend_class_entry **pce = ce->interfaces;
|
||||
|
||||
while (i--) {
|
||||
if (*pce == spl_ce_iterator) is_a |= SPL_IS_A_ITERATOR;
|
||||
else if (*pce == spl_ce_forward) is_a |= SPL_IS_A_FORWARD;
|
||||
else if (*pce == spl_ce_assoc) is_a |= SPL_IS_A_ASSOC;
|
||||
else if (*pce == spl_ce_sequence) is_a |= SPL_IS_A_SEQUENCE;
|
||||
pce++;
|
||||
}
|
||||
return is_a;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#undef EX
|
||||
#define EX(element) execute_data.element
|
||||
|
||||
/* {{{ spl_call_method */
|
||||
int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval, HashTable *symbol_table TSRMLS_DC, int param_count, ...)
|
||||
{
|
||||
int i, l;
|
||||
zval *arg;
|
||||
zval *param;
|
||||
unsigned char *arg_types;
|
||||
zval **original_return_value;
|
||||
HashTable *calling_symbol_table;
|
||||
zend_function_state *original_function_state_ptr;
|
||||
zend_op_array *original_op_array;
|
||||
zend_op **original_opline_ptr;
|
||||
zval *orig_free_op1, *orig_free_op2;
|
||||
int (*orig_unary_op)(zval *result, zval *op1);
|
||||
int (*orig_binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
|
||||
zend_class_entry *current_scope;
|
||||
zval *current_this;
|
||||
zend_execute_data execute_data;
|
||||
va_list args;
|
||||
|
||||
if (!object_pp || (!obj_ce && (obj_ce = spl_get_class_entry(*object_pp TSRMLS_CC)) == NULL)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize execute_data */
|
||||
EX(fbc) = NULL;
|
||||
EX(Ts) = NULL;
|
||||
EX(op_array) = NULL;
|
||||
EX(opline) = NULL;
|
||||
|
||||
EX(object) = *object_pp;
|
||||
|
||||
original_function_state_ptr = EG(function_state_ptr);
|
||||
if (fn_proxy && *fn_proxy) {
|
||||
EX(function_state).function = *fn_proxy;
|
||||
} else {
|
||||
if (zend_hash_find(&obj_ce->function_table, function_name, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (fn_proxy) {
|
||||
*fn_proxy = EX(function_state).function;
|
||||
}
|
||||
}
|
||||
|
||||
va_start(args, param_count);
|
||||
if (param_count) {
|
||||
if ((arg_types = EX(function_state).function->common.arg_types) != NULL) {
|
||||
l = arg_types[0];
|
||||
} else {
|
||||
l = 0;
|
||||
}
|
||||
for (i=1; i<=param_count; i++) {
|
||||
arg = va_arg(args, zval*);
|
||||
|
||||
if (i<=l && arg_types[i]==BYREF_FORCE && !PZVAL_IS_REF(arg)) {
|
||||
if (arg->refcount > 1) {
|
||||
zval *new_zval;
|
||||
|
||||
ALLOC_ZVAL(new_zval);
|
||||
*new_zval = *arg;
|
||||
zval_copy_ctor(new_zval);
|
||||
new_zval->refcount = 2;
|
||||
new_zval->is_ref = 1;
|
||||
arg->refcount--;
|
||||
param = new_zval;
|
||||
} else {
|
||||
arg->refcount++;
|
||||
arg->is_ref = 1;
|
||||
param = arg;
|
||||
}
|
||||
} else if (arg != &EG(uninitialized_zval)) {
|
||||
arg->refcount++;
|
||||
param = arg;
|
||||
} else {
|
||||
ALLOC_ZVAL(param);
|
||||
*param = *arg;
|
||||
INIT_PZVAL(param);
|
||||
}
|
||||
zend_ptr_stack_push(&EG(argument_stack), param);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
zend_ptr_stack_push(&EG(argument_stack), (void *) (long) param_count);
|
||||
zend_ptr_stack_push(&EG(argument_stack), NULL);
|
||||
|
||||
EG(function_state_ptr) = &EX(function_state);
|
||||
|
||||
current_scope = EG(scope);
|
||||
EG(scope) = obj_ce;
|
||||
|
||||
current_this = EG(This);
|
||||
EG(This) = *object_pp;
|
||||
|
||||
if (!PZVAL_IS_REF(EG(This))) {
|
||||
EG(This)->refcount++; /* For $this pointer */
|
||||
} else {
|
||||
zval *this_ptr;
|
||||
|
||||
ALLOC_ZVAL(this_ptr);
|
||||
*this_ptr = *EG(This);
|
||||
INIT_PZVAL(this_ptr);
|
||||
zval_copy_ctor(this_ptr);
|
||||
EG(This) = this_ptr;
|
||||
}
|
||||
|
||||
EX(prev_execute_data) = EG(current_execute_data);
|
||||
EG(current_execute_data) = &execute_data;
|
||||
|
||||
if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
|
||||
calling_symbol_table = EG(active_symbol_table);
|
||||
if (symbol_table) {
|
||||
EG(active_symbol_table) = symbol_table;
|
||||
} else {
|
||||
ALLOC_HASHTABLE(EG(active_symbol_table));
|
||||
zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
|
||||
original_return_value = EG(return_value_ptr_ptr);
|
||||
original_op_array = EG(active_op_array);
|
||||
EG(return_value_ptr_ptr) = retval;
|
||||
EG(active_op_array) = (zend_op_array *) EX(function_state).function;
|
||||
original_opline_ptr = EG(opline_ptr);
|
||||
orig_free_op1 = EG(free_op1);
|
||||
orig_free_op2 = EG(free_op2);
|
||||
orig_unary_op = EG(unary_op);
|
||||
orig_binary_op = EG(binary_op);
|
||||
zend_execute(EG(active_op_array) TSRMLS_CC);
|
||||
if (!symbol_table) {
|
||||
zend_hash_destroy(EG(active_symbol_table));
|
||||
FREE_HASHTABLE(EG(active_symbol_table));
|
||||
}
|
||||
EG(active_symbol_table) = calling_symbol_table;
|
||||
EG(active_op_array) = original_op_array;
|
||||
EG(return_value_ptr_ptr)=original_return_value;
|
||||
EG(opline_ptr) = original_opline_ptr;
|
||||
EG(free_op1) = orig_free_op1;
|
||||
EG(free_op2) = orig_free_op2;
|
||||
EG(unary_op) = orig_unary_op;
|
||||
EG(binary_op) = orig_binary_op;
|
||||
} else {
|
||||
ALLOC_INIT_ZVAL(*retval);
|
||||
((zend_internal_function *) EX(function_state).function)->handler(param_count, *retval, *object_pp, 1 TSRMLS_CC);
|
||||
INIT_PZVAL(*retval);
|
||||
}
|
||||
zend_ptr_stack_clear_multiple(TSRMLS_C);
|
||||
EG(function_state_ptr) = original_function_state_ptr;
|
||||
|
||||
if (EG(This)) {
|
||||
zval_ptr_dtor(&EG(This));
|
||||
}
|
||||
EG(scope) = current_scope;
|
||||
EG(This) = current_this;
|
||||
EG(current_execute_data) = EX(prev_execute_data); \
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef SPL_ENGINE_H
|
||||
#define SPL_ENGINE_H
|
||||
|
||||
#include "php.h"
|
||||
#include "php_spl.h"
|
||||
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute_locks.h"
|
||||
|
||||
#undef EX
|
||||
#define EX(element) execute_data->element
|
||||
#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
|
||||
#define T(offset) (*(temp_variable *)((char *) Ts + offset))
|
||||
|
||||
#define NEXT_OPCODE() \
|
||||
EX(opline)++; \
|
||||
return 0;
|
||||
|
||||
int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS);
|
||||
|
||||
int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr, HashTable *symbol_table TSRMLS_DC, int param_count, ...);
|
||||
|
||||
/* {{{ zend_class_entry */
|
||||
static inline zend_class_entry *spl_get_class_entry(zval *obj TSRMLS_DC)
|
||||
{
|
||||
if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_class_entry) {
|
||||
return Z_OBJ_HT_P(obj)->get_class_entry(obj TSRMLS_CC);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_begin_method_call_arg */
|
||||
static inline int spl_begin_method_call_arg(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval *retval, zval *arg1 TSRMLS_DC)
|
||||
{
|
||||
zval *local_retval;
|
||||
int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &local_retval, NULL TSRMLS_CC, 1, arg1);
|
||||
if (local_retval) {
|
||||
COPY_PZVAL_TO_ZVAL(*retval, local_retval);
|
||||
} else {
|
||||
INIT_ZVAL(*retval);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_begin_method_call_no_retval */
|
||||
static inline int spl_begin_method_call_no_retval(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len TSRMLS_DC)
|
||||
{
|
||||
zval *retval;
|
||||
int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &retval, NULL TSRMLS_CC, 0);
|
||||
if (retval) {
|
||||
zval_dtor(retval);
|
||||
FREE_ZVAL(retval);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define spl_begin_method_call_ex(ce, obj_ce, fn_proxy, function_name, fname_len, retval) \
|
||||
spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0)
|
||||
|
||||
#define spl_begin_method_call_arg_ex1(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1) \
|
||||
spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1)
|
||||
|
||||
#define spl_begin_method_call_arg_ex2(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1, arg2) \
|
||||
spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2)
|
||||
|
||||
void spl_instanciate(zend_class_entry *pce, zval **object TSRMLS_DC);
|
||||
int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC);
|
||||
|
||||
zval ** spl_get_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC);
|
||||
void spl_unlock_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC);
|
||||
zval * spl_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRMLS_DC);
|
||||
|
||||
int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC);
|
||||
|
||||
typedef enum {
|
||||
SPL_IS_A_ITERATOR = 1,
|
||||
SPL_IS_A_FORWARD = 2,
|
||||
SPL_IS_A_ASSOC = 4,
|
||||
SPL_IS_A_SEQUENCE = 8
|
||||
} spl_is_a;
|
||||
|
||||
spl_is_a spl_implements(zend_class_entry *ce);
|
||||
|
||||
#endif /* SPL_ENGINE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute_locks.h"
|
||||
|
||||
#include "php_spl.h"
|
||||
#include "spl_functions.h"
|
||||
#include "spl_engine.h"
|
||||
#include "spl_foreach.h"
|
||||
|
||||
#define OPTIMIZED_ARRAY_CONSTRUCT
|
||||
|
||||
typedef struct {
|
||||
zend_function *next;
|
||||
zend_function *rewind;
|
||||
zend_function *more;
|
||||
zend_function *current;
|
||||
zend_function *key;
|
||||
} spl_foreach_funcs;
|
||||
|
||||
typedef struct {
|
||||
zval *obj;
|
||||
zend_class_entry *obj_ce;
|
||||
zend_uint index;
|
||||
spl_is_a is_a;
|
||||
spl_foreach_funcs funcs;
|
||||
char dummy; /* needed for '\0' but we can't set it due to compiler optimizations */
|
||||
} spl_foreach_proxy;
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET) */
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET)
|
||||
{
|
||||
zval **obj, *retval;
|
||||
spl_foreach_proxy *proxy;
|
||||
zend_class_entry *instance_ce, *obj_ce;
|
||||
spl_is_a is_a;
|
||||
temp_variable *tmp;
|
||||
|
||||
obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
|
||||
if (!obj || (instance_ce = spl_get_class_entry(*obj TSRMLS_CC)) == NULL) {
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET);
|
||||
}
|
||||
|
||||
is_a = spl_implements(instance_ce);
|
||||
|
||||
if (is_a & SPL_IS_A_ITERATOR) {
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval);
|
||||
obj_ce = instance_ce;
|
||||
instance_ce = spl_get_class_entry(retval TSRMLS_CC);
|
||||
is_a = spl_implements(instance_ce);
|
||||
if (!(is_a & SPL_IS_A_FORWARD)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Objects created by %s::new_iterator() must implement spl_forward", obj_ce->name);
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET);
|
||||
}
|
||||
PZVAL_LOCK(retval);
|
||||
} else if (is_a & SPL_IS_A_FORWARD) {
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
retval = *obj;
|
||||
retval->refcount += 2; /* lock two times */
|
||||
} else {
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET);
|
||||
}
|
||||
|
||||
/* create the proxy */
|
||||
proxy = emalloc(sizeof(spl_foreach_proxy));
|
||||
proxy->obj = retval;
|
||||
proxy->obj_ce = instance_ce;
|
||||
proxy->index = 0;
|
||||
proxy->is_a = is_a;
|
||||
memset(&proxy->funcs, 0, sizeof(spl_foreach_funcs));
|
||||
((char*)proxy)[sizeof(spl_foreach_proxy)-1] = '\0';
|
||||
/* And pack it into a zval. Since it is nowhere accessible using a
|
||||
* zval of type STRING is the fastest approach of storing the proxy.
|
||||
*/
|
||||
ALLOC_ZVAL(retval);
|
||||
ZVAL_STRINGL(retval, (char*)proxy, sizeof(spl_foreach_proxy)-1, 0);
|
||||
retval->is_ref = 0;
|
||||
retval->refcount = 2; /* lock two times */
|
||||
/* return the created proxy container */
|
||||
tmp = &EX_T(EX(opline)->result.u.var);
|
||||
tmp->var.ptr = retval;
|
||||
tmp->var.ptr_ptr = &tmp->var.ptr;
|
||||
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ OPTIMIZED_ARRAY_CONSTRUCT macros */
|
||||
#ifdef OPTIMIZED_ARRAY_CONSTRUCT
|
||||
#define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
|
||||
(element)->pNext = (list_head); \
|
||||
(element)->pLast = NULL;
|
||||
|
||||
#define CONNECT_TO_GLOBAL_DLLIST(element, ht) \
|
||||
(element)->pListLast = (ht)->pListTail; \
|
||||
(ht)->pListTail = (element); \
|
||||
(element)->pListNext = NULL; \
|
||||
if ((element)->pListLast != NULL) { \
|
||||
(element)->pListLast->pListNext = (element); \
|
||||
} \
|
||||
if (!(ht)->pListHead) { \
|
||||
(ht)->pListHead = (element); \
|
||||
} \
|
||||
if ((ht)->pInternalPointer == NULL) { \
|
||||
(ht)->pInternalPointer = (element); \
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH) */
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH)
|
||||
{
|
||||
znode *op1 = &EX(opline)->op1;
|
||||
zval **obj = spl_get_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC);
|
||||
zval *more, *value, *key, *result;
|
||||
spl_foreach_proxy *proxy;
|
||||
|
||||
if (Z_TYPE_PP(obj) == IS_STRING) {
|
||||
|
||||
proxy = (spl_foreach_proxy*)Z_STRVAL_PP(obj);
|
||||
obj = &proxy->obj; /* will be optimized out */
|
||||
|
||||
if (proxy->index++) {
|
||||
spl_begin_method_call_no_retval(obj, proxy->obj_ce, &proxy->funcs.next, "next", sizeof("next")-1 TSRMLS_CC);
|
||||
} else {
|
||||
if (proxy->is_a & SPL_IS_A_SEQUENCE) {
|
||||
spl_begin_method_call_no_retval(obj, proxy->obj_ce, &proxy->funcs.rewind, "rewind", sizeof("rewind")-1 TSRMLS_CC);
|
||||
}
|
||||
op_array->opcodes[EX(opline)->op2.u.opline_num].op2 = *op1;
|
||||
}
|
||||
|
||||
spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.more, "has_more", sizeof("has_more")-1, &more);
|
||||
if (!more->type == IS_BOOL && !more->type == IS_LONG) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Method %s::has_more implements spl_forward::has_more and should return a value of type boolean or int");
|
||||
convert_to_boolean(more);
|
||||
}
|
||||
if (more->value.lval) {
|
||||
zval_dtor(more);
|
||||
FREE_ZVAL(more);
|
||||
result = &EX_T(EX(opline)->result.u.var).tmp_var;
|
||||
|
||||
spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.current, "current", sizeof("current")-1, &value);
|
||||
|
||||
if (proxy->is_a & SPL_IS_A_ASSOC) {
|
||||
spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.key, "key", sizeof("key")-1, &key);
|
||||
} else {
|
||||
MAKE_STD_ZVAL(key);
|
||||
key->value.lval = proxy->index;
|
||||
key->type = IS_LONG;
|
||||
}
|
||||
#ifndef OPTIMIZED_ARRAY_CONSTRUCT
|
||||
array_init(result);
|
||||
add_next_index_zval(result, value);
|
||||
add_next_index_zval(result, key);
|
||||
#else
|
||||
{
|
||||
Bucket *p;
|
||||
HashTable *ht;
|
||||
|
||||
ht = emalloc(sizeof(HashTable));
|
||||
result->value.ht = ht;
|
||||
ht->nTableSize = 1 << 1;
|
||||
ht->nTableMask = ht->nTableSize - 1;
|
||||
#if ZEND_DEBUG
|
||||
ht->inconsistent = 0; /*HT_OK;*/
|
||||
#endif
|
||||
|
||||
ht->arBuckets = (Bucket **)emalloc(ht->nTableSize * sizeof(Bucket *));
|
||||
|
||||
ht->pDestructor = ZVAL_PTR_DTOR;
|
||||
ht->pListHead = NULL;
|
||||
ht->pListTail = NULL;
|
||||
ht->nNumOfElements = 0;
|
||||
ht->nNextFreeElement = 0;
|
||||
ht->pInternalPointer = NULL;
|
||||
ht->persistent = 0;
|
||||
ht->nApplyCount = 0;
|
||||
ht->bApplyProtection = 1;
|
||||
result->type = IS_ARRAY;
|
||||
|
||||
p = (Bucket*)emalloc(sizeof(Bucket)-1);
|
||||
p->pDataPtr = value;
|
||||
p->pData = &p->pDataPtr;
|
||||
p->nKeyLength = 0;
|
||||
p->h = 0;
|
||||
result->value.ht->arBuckets[0] = p;
|
||||
CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[0]);
|
||||
CONNECT_TO_GLOBAL_DLLIST(p, ht);
|
||||
|
||||
p = (Bucket*)emalloc(sizeof(Bucket)-1);
|
||||
p->pDataPtr = key;
|
||||
p->pData = &p->pDataPtr;
|
||||
p->nKeyLength = 0;
|
||||
p->h = 1;
|
||||
result->value.ht->arBuckets[1] = p;
|
||||
CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[1]);
|
||||
CONNECT_TO_GLOBAL_DLLIST(p, ht);
|
||||
|
||||
ht->nNumOfElements = 2;
|
||||
}
|
||||
#endif
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
zval_dtor(more);
|
||||
FREE_ZVAL(more);
|
||||
EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
|
||||
return 0;
|
||||
}
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_FETCH);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE) */
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE)
|
||||
{
|
||||
znode *op2 = &EX(opline)->op2;
|
||||
zval *tmp, **obj = spl_get_zval_ptr_ptr(op2, EX(Ts) TSRMLS_CC);
|
||||
spl_foreach_proxy *proxy;
|
||||
|
||||
if (obj) {
|
||||
proxy = (spl_foreach_proxy*)Z_STRVAL_PP(obj);
|
||||
tmp = *obj;
|
||||
*obj = proxy->obj; /* restore */
|
||||
|
||||
efree(tmp->value.str.val);
|
||||
FREE_ZVAL(tmp);
|
||||
|
||||
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
|
||||
PZVAL_LOCK(*obj);
|
||||
|
||||
SET_UNUSED(*op2);
|
||||
}
|
||||
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_SWITCH_FREE);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef SPL_FOREACH_H
|
||||
#define SPL_FOREACH_H
|
||||
|
||||
#include "php.h"
|
||||
#include "php_spl.h"
|
||||
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET);
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH);
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE);
|
||||
|
||||
#endif /* SPL_FOREACH_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_spl.h"
|
||||
#include "spl_foreach.h"
|
||||
|
||||
/* {{{ spl_destroy_class */
|
||||
void spl_destroy_class(zend_class_entry ** ppce)
|
||||
{
|
||||
SPL_DEBUG(fprintf(stderr, "Destroy(%s): %s\n", (*ppce)->type == ZEND_USER_CLASS ? "user" : "other", (*ppce)->name);)
|
||||
destroy_zend_class(ppce);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_interface */
|
||||
void spl_register_interface(zend_class_entry ** ppce, char * class_name TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, class_name, NULL);
|
||||
ce.name_length = strlen(class_name);
|
||||
*ppce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
/* entries changed by initialize */
|
||||
(*ppce)->ce_flags = ZEND_ACC_ABSTRACT | ZEND_ACC_INTERFACE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_std_class */
|
||||
void spl_register_std_class(zend_class_entry ** ppce, char * class_name, void * obj_ctor TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, class_name, NULL);
|
||||
ce.name_length = strlen(class_name);
|
||||
*ppce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
/* entries changed by initialize */
|
||||
(*ppce)->create_object = obj_ctor;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_interface_function */
|
||||
void spl_register_interface_function(zend_class_entry * class_entry, char * fn_name TSRMLS_DC)
|
||||
{
|
||||
zend_function function, *reg_function;
|
||||
zend_internal_function *pfunction = (zend_internal_function *)&function;
|
||||
|
||||
pfunction->type = ZEND_INTERNAL_FUNCTION;
|
||||
pfunction->handler = NULL;
|
||||
pfunction->arg_types = NULL;
|
||||
pfunction->function_name = fn_name;
|
||||
pfunction->scope = class_entry;
|
||||
pfunction->fn_flags = ZEND_ACC_ABSTRACT | ZEND_ACC_PUBLIC;
|
||||
pfunction->prototype = NULL;
|
||||
zend_hash_add(&class_entry->function_table, fn_name, strlen(fn_name)+1, &function, sizeof(zend_function), (void**)®_function);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_parent_ce */
|
||||
void spl_register_parent_ce(zend_class_entry * class_entry, zend_class_entry * parent_class TSRMLS_DC)
|
||||
{
|
||||
class_entry->parent = parent_class;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_implement */
|
||||
void spl_register_implement(zend_class_entry * class_entry, zend_class_entry * interface_entry TSRMLS_DC)
|
||||
{
|
||||
class_entry->interfaces = realloc(class_entry->interfaces, sizeof(zend_class_entry*) * (class_entry->num_interfaces+1));
|
||||
class_entry->interfaces[class_entry->num_interfaces++] = interface_entry;
|
||||
zend_do_implement_interface(class_entry, interface_entry);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_register_functions */
|
||||
void spl_register_functions(zend_class_entry * class_entry, function_entry * function_list TSRMLS_DC)
|
||||
{
|
||||
zend_register_functions(class_entry, function_list, &class_entry->function_table, MODULE_PERSISTENT TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_add_class_name */
|
||||
void spl_add_class_name(zval * list, zend_class_entry * pce TSRMLS_DC)
|
||||
{
|
||||
size_t len = strlen(pce->name);
|
||||
zval *tmp;
|
||||
|
||||
if (zend_hash_find(Z_ARRVAL_P(list), pce->name, len+1, (void*)&tmp) == FAILURE) {
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
ZVAL_STRING(tmp, pce->name, 1);
|
||||
zend_hash_add(Z_ARRVAL_P(list), pce->name, len+1, &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_add_interfaces */
|
||||
void spl_add_interfaces(zval *list, zend_class_entry * pce TSRMLS_DC)
|
||||
{
|
||||
zend_uint num_interfaces;
|
||||
|
||||
for (num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) {
|
||||
spl_add_class_name(list, pce->interfaces[num_interfaces] TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_add_classes */
|
||||
int spl_add_classes(zend_class_entry ** ppce, zval *list TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry *pce = *ppce;
|
||||
spl_add_class_name(list, pce TSRMLS_CC);
|
||||
spl_add_interfaces(list, pce TSRMLS_CC);
|
||||
while (pce->parent) {
|
||||
pce = pce->parent;
|
||||
spl_add_classes(&pce, list TSRMLS_CC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef PHP_FUNCTIONS_H
|
||||
#define PHP_FUNCTIONS_H
|
||||
|
||||
#include "php.h"
|
||||
|
||||
typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type TSRMLS_DC);
|
||||
|
||||
#define REGISTER_SPL_STD_CLASS(class_name, obj_ctor) \
|
||||
spl_register_std_class(&spl_ce_ ## class_name, "spl_" # class_name, obj_ctor TSRMLS_CC);
|
||||
|
||||
#define REGISTER_SPL_INTERFACE(class_name) \
|
||||
spl_register_interface(&spl_ce_ ## class_name, "spl_" # class_name TSRMLS_CC);
|
||||
|
||||
#define REGISTER_SPL_INTF_FUNC(class_name, function_name) \
|
||||
spl_register_interface_function(spl_ce_ ## class_name, # function_name TSRMLS_CC);
|
||||
|
||||
#define REGISTER_SPL_PARENT_CE(class_name, parent_class) \
|
||||
spl_register_parent_ce(spl_ce_ ## class_name, spl_ce_ ## parent_class TSRMLS_CC);
|
||||
|
||||
#define REGISTER_SPL_IMPLEMENT(class_name, interface_name) \
|
||||
spl_register_implement(spl_ce_ ## class_name, spl_ce_ ## interface_name TSRMLS_CC);
|
||||
|
||||
#define REGISTER_SPL_FUNCTIONS(class_name, function_list) \
|
||||
spl_register_functions(spl_ce_ ## class_name, function_list TSRMLS_CC);
|
||||
|
||||
void spl_destroy_class(zend_class_entry ** ppce);
|
||||
|
||||
void spl_register_std_class(zend_class_entry ** ppce, char * class_name, create_object_func_t ctor TSRMLS_DC);
|
||||
|
||||
void spl_register_interface(zend_class_entry ** ppce, char * class_name TSRMLS_DC);
|
||||
|
||||
void spl_register_interface_function(zend_class_entry * class_entry, char * fn_name TSRMLS_DC);
|
||||
void spl_register_parent_ce(zend_class_entry * class_entry, zend_class_entry * parent_class TSRMLS_DC);
|
||||
void spl_register_implement(zend_class_entry * class_entry, zend_class_entry * interface_entry TSRMLS_DC);
|
||||
void spl_register_functions(zend_class_entry * class_entry, function_entry * function_list TSRMLS_DC);
|
||||
|
||||
void spl_add_class_name(zval * list, zend_class_entry * pce TSRMLS_DC);
|
||||
void spl_add_interfaces(zval * list, zend_class_entry * pce TSRMLS_DC);
|
||||
int spl_add_classes(zend_class_entry ** ppce, zval *list TSRMLS_DC);
|
||||
|
||||
#define SPL_CLASS_FE(class_name, function_name, arg_types) \
|
||||
PHP_NAMED_FE( function_name, spl_ ## class_name ## function_name, arg_types)
|
||||
|
||||
#define SPL_CLASS_FUNCTION(class_name, function_name) \
|
||||
PHP_NAMED_FUNCTION(spl_ ## class_name ## function_name)
|
||||
|
||||
#endif /* PHP_FUNCTIONS_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,3 +0,0 @@
|
||||
<IfModule mod_autoindex.c>
|
||||
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t *.php
|
||||
</IfModule>
|
||||
@@ -1,127 +0,0 @@
|
||||
--TEST--
|
||||
SPL: array_access
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("spl")) die("skip");
|
||||
if (!in_array("spl_array_access", spl_classes())) die("skip spl_array_access not present");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c implements spl_array_access {
|
||||
|
||||
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
|
||||
function exists($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return array_key_exists($index, $this->a);
|
||||
}
|
||||
function get($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return $this->a[$index];
|
||||
}
|
||||
function set($index, $newval) {
|
||||
echo __METHOD__ . "($index,$newval)\n";
|
||||
return $this->a[$index] = $newval;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new c();
|
||||
|
||||
var_dump($obj->a);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[1]);
|
||||
var_dump($obj[2]);
|
||||
var_dump($obj['4th']);
|
||||
var_dump($obj['5th']);
|
||||
var_dump($obj[6]);
|
||||
|
||||
echo "WRITE 1\n";
|
||||
$obj[1] = 'Changed 1';
|
||||
var_dump($obj[1]);
|
||||
echo "WRITE 2\n";
|
||||
$obj['4th'] = 'Changed 4th';
|
||||
var_dump($obj['4th']);
|
||||
echo "WRITE 3\n";
|
||||
$obj['5th'] = 'Added 5th';
|
||||
var_dump($obj['5th']);
|
||||
echo "WRITE 4\n";
|
||||
$obj[6] = 'Added 6';
|
||||
var_dump($obj[6]);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[2]);
|
||||
|
||||
$x = $obj[6] = 'changed 6';
|
||||
var_dump($obj[6]);
|
||||
var_dump($x);
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "1st"
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(3) "3rd"
|
||||
["4th"]=>
|
||||
int(4)
|
||||
}
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
int(1)
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
int(4)
|
||||
c::exists(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
c::exists(6)
|
||||
|
||||
Notice: Undefined index: 6 in %s on line %d
|
||||
NULL
|
||||
WRITE 1
|
||||
c::exists(1)
|
||||
c::set(1,Changed 1)
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
string(9) "Changed 1"
|
||||
WRITE 2
|
||||
c::exists(4th)
|
||||
c::set(4th,Changed 4th)
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
string(11) "Changed 4th"
|
||||
WRITE 3
|
||||
c::exists(5th)
|
||||
c::set(5th,Added 5th)
|
||||
c::exists(5th)
|
||||
c::get(5th)
|
||||
string(9) "Added 5th"
|
||||
WRITE 4
|
||||
c::exists(6)
|
||||
c::set(6,Added 6)
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(7) "Added 6"
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(6)
|
||||
c::set(6,changed 6)
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(9) "changed 6"
|
||||
string(9) "changed 6"
|
||||
Done
|
||||
@@ -1,137 +0,0 @@
|
||||
--TEST--
|
||||
SPL: array_access without return in set()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("spl")) die("skip");
|
||||
if (!in_array("spl_array_access", spl_classes())) die("skip spl_array_access not present");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c implements spl_array_access {
|
||||
|
||||
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
|
||||
function exists($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return array_key_exists($index, $this->a);
|
||||
}
|
||||
function get($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return $this->a[$index];
|
||||
}
|
||||
function set($index, $newval) {
|
||||
echo __METHOD__ . "($index,$newval)\n";
|
||||
/* return */ $this->a[$index] = $newval;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new c();
|
||||
|
||||
var_dump($obj->a);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[1]);
|
||||
var_dump($obj[2]);
|
||||
var_dump($obj['4th']);
|
||||
var_dump($obj['5th']);
|
||||
var_dump($obj[6]);
|
||||
|
||||
echo "WRITE 1\n";
|
||||
$obj[1] = 'Changed 1';
|
||||
var_dump($obj[1]);
|
||||
echo "WRITE 2\n";
|
||||
$obj['4th'] = 'Changed 4th';
|
||||
var_dump($obj['4th']);
|
||||
echo "WRITE 3\n";
|
||||
$obj['5th'] = 'Added 5th';
|
||||
var_dump($obj['5th']);
|
||||
echo "WRITE 4\n";
|
||||
$obj[6] = 'Added 6';
|
||||
var_dump($obj[6]);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[2]);
|
||||
|
||||
$x = $obj[6] = 'changed 6';
|
||||
var_dump($obj[6]);
|
||||
var_dump($x);
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "1st"
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(3) "3rd"
|
||||
["4th"]=>
|
||||
int(4)
|
||||
}
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
int(1)
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
int(4)
|
||||
c::exists(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
c::exists(6)
|
||||
|
||||
Notice: Undefined index: 6 in %s on line %d
|
||||
NULL
|
||||
WRITE 1
|
||||
c::exists(1)
|
||||
c::set(1,Changed 1)
|
||||
|
||||
Warning: Method c::set() did not return a value, using NULL in %s on line %d
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
string(9) "Changed 1"
|
||||
WRITE 2
|
||||
c::exists(4th)
|
||||
c::set(4th,Changed 4th)
|
||||
|
||||
Warning: Method c::set() did not return a value, using NULL in %s on line %d
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
string(11) "Changed 4th"
|
||||
WRITE 3
|
||||
c::exists(5th)
|
||||
c::set(5th,Added 5th)
|
||||
|
||||
Warning: Method c::set() did not return a value, using NULL in %s on line %d
|
||||
c::exists(5th)
|
||||
c::get(5th)
|
||||
string(9) "Added 5th"
|
||||
WRITE 4
|
||||
c::exists(6)
|
||||
c::set(6,Added 6)
|
||||
|
||||
Warning: Method c::set() did not return a value, using NULL in %s on line %d
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(7) "Added 6"
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(6)
|
||||
c::set(6,changed 6)
|
||||
|
||||
Warning: Method c::set() did not return a value, using NULL in %s on line %d
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(9) "changed 6"
|
||||
NULL
|
||||
Done
|
||||
@@ -1,154 +0,0 @@
|
||||
--TEST--
|
||||
SPL: array_access
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("spl")) die("skip");
|
||||
if (!in_array("spl_array_access", spl_classes())) die("skip spl_array_access not present");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class array_write implements spl_array_writer {
|
||||
private $obj;
|
||||
private $idx;
|
||||
|
||||
function __construct(&$obj, $index = null) {
|
||||
$this->obj = &$obj;
|
||||
$this->idx = $index;
|
||||
}
|
||||
|
||||
function set($value) {
|
||||
echo __METHOD__ . "($value,".$this->idx.")\n";
|
||||
return $this->obj->set($this->idx, $value);
|
||||
}
|
||||
}
|
||||
|
||||
class c implements spl_array_access_ex {
|
||||
|
||||
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
|
||||
|
||||
function new_writer($index) {
|
||||
return new array_write(&$this, $index);
|
||||
}
|
||||
|
||||
function exists($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return array_key_exists($index, $this->a);
|
||||
}
|
||||
|
||||
function get($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return $this->a[$index];
|
||||
}
|
||||
|
||||
function set($index, $newval) {
|
||||
echo __METHOD__ . "($index,$newval)\n";
|
||||
return $this->a[$index] = $newval;
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new c();
|
||||
|
||||
var_dump($obj->a);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[1]);
|
||||
var_dump($obj[2]);
|
||||
var_dump($obj['4th']);
|
||||
var_dump($obj['5th']);
|
||||
var_dump($obj[6]);
|
||||
|
||||
echo "WRITE 1\n";
|
||||
$obj[1] = 'Changed 1';
|
||||
var_dump($obj[1]);
|
||||
echo "WRITE 2\n";
|
||||
$obj['4th'] = 'Changed 4th';
|
||||
var_dump($obj['4th']);
|
||||
echo "WRITE 3\n";
|
||||
$obj['5th'] = 'Added 5th';
|
||||
var_dump($obj['5th']);
|
||||
echo "WRITE 4\n";
|
||||
$obj[6] = 'Added 6';
|
||||
var_dump($obj[6]);
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[2]);
|
||||
|
||||
$x = $obj[6] = 'changed 6';
|
||||
var_dump($obj[6]);
|
||||
var_dump($x);
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "1st"
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(3) "3rd"
|
||||
["4th"]=>
|
||||
int(4)
|
||||
}
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
int(1)
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
int(4)
|
||||
c::exists(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %sarray_access_ex.php on line %d
|
||||
NULL
|
||||
c::exists(6)
|
||||
|
||||
Notice: Undefined index: 6 in %sarray_access_ex.php on line %d
|
||||
NULL
|
||||
WRITE 1
|
||||
c::exists(1)
|
||||
array_write::set(Changed 1,1)
|
||||
c::set(1,Changed 1)
|
||||
c::exists(1)
|
||||
c::get(1)
|
||||
string(9) "Changed 1"
|
||||
WRITE 2
|
||||
c::exists(4th)
|
||||
array_write::set(Changed 4th,4th)
|
||||
c::set(4th,Changed 4th)
|
||||
c::exists(4th)
|
||||
c::get(4th)
|
||||
string(11) "Changed 4th"
|
||||
WRITE 3
|
||||
c::exists(5th)
|
||||
array_write::set(Added 5th,5th)
|
||||
c::set(5th,Added 5th)
|
||||
c::exists(5th)
|
||||
c::get(5th)
|
||||
string(9) "Added 5th"
|
||||
WRITE 4
|
||||
c::exists(6)
|
||||
array_write::set(Added 6,6)
|
||||
c::set(6,Added 6)
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(7) "Added 6"
|
||||
c::exists(0)
|
||||
c::get(0)
|
||||
string(3) "1st"
|
||||
c::exists(2)
|
||||
c::get(2)
|
||||
string(3) "3rd"
|
||||
c::exists(6)
|
||||
array_write::set(changed 6,6)
|
||||
c::set(6,changed 6)
|
||||
c::exists(6)
|
||||
c::get(6)
|
||||
string(9) "changed 6"
|
||||
string(9) "changed 6"
|
||||
Done
|
||||
@@ -1,208 +0,0 @@
|
||||
--TEST--
|
||||
SPL: array_read
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "EXTERNAL\n";
|
||||
|
||||
$a = array('1st', 1, 2=>'3rd', '4th'=>4);
|
||||
var_dump($a);
|
||||
|
||||
class external implements spl_array_read {
|
||||
|
||||
function exists($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return array_key_exists($index, $GLOBALS['a']);
|
||||
}
|
||||
|
||||
function get($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return $GLOBALS['a'][$index];
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new external();
|
||||
|
||||
var_dump($obj->get(0));
|
||||
var_dump($obj->get(1));
|
||||
var_dump($obj->get(2));
|
||||
var_dump($obj->get('4th'));
|
||||
var_dump($obj->get('5th'));
|
||||
var_dump($obj->get(6));
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[1]);
|
||||
var_dump($obj[2]);
|
||||
var_dump($obj['4th']);
|
||||
var_dump($obj['5th']);
|
||||
var_dump($obj[6]);
|
||||
|
||||
$out = $obj[0]; echo "$out\n";
|
||||
$out = $obj[1]; echo "$out\n";
|
||||
$out = $obj[2]; echo "$out\n";
|
||||
$out = $obj['4th']; echo "$out\n";
|
||||
|
||||
echo "INTERNAL\n";
|
||||
|
||||
class internal implements spl_array_read {
|
||||
|
||||
public $a = array('1st', 1, 2=>'3rd', '4th'=>4);
|
||||
|
||||
function exists($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return array_key_exists($index, $GLOBALS['a']);
|
||||
}
|
||||
|
||||
function get($index) {
|
||||
echo __METHOD__ . "($index)\n";
|
||||
return $GLOBALS['a'][$index];
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new internal();
|
||||
|
||||
var_dump($obj->a);
|
||||
|
||||
var_dump($obj->get(0));
|
||||
var_dump($obj->get(1));
|
||||
var_dump($obj->get(2));
|
||||
var_dump($obj->get('4th'));
|
||||
var_dump($obj->get('5th'));
|
||||
var_dump($obj->get(6));
|
||||
|
||||
var_dump($obj[0]);
|
||||
var_dump($obj[1]);
|
||||
var_dump($obj[2]);
|
||||
var_dump($obj['4th']);
|
||||
var_dump($obj['5th']);
|
||||
var_dump($obj[6]);
|
||||
|
||||
$out = $obj[0]; echo "$out\n";
|
||||
$out = $obj[1]; echo "$out\n";
|
||||
$out = $obj[2]; echo "$out\n";
|
||||
$out = $obj['4th']; echo "$out\n";
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
EXTERNAL
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "1st"
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(3) "3rd"
|
||||
["4th"]=>
|
||||
int(4)
|
||||
}
|
||||
external::get(0)
|
||||
string(3) "1st"
|
||||
external::get(1)
|
||||
int(1)
|
||||
external::get(2)
|
||||
string(3) "3rd"
|
||||
external::get(4th)
|
||||
int(4)
|
||||
external::get(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
external::get(6)
|
||||
|
||||
Notice: Undefined offset: 6 in %s on line %d
|
||||
NULL
|
||||
external::exists(0)
|
||||
external::get(0)
|
||||
string(3) "1st"
|
||||
external::exists(1)
|
||||
external::get(1)
|
||||
int(1)
|
||||
external::exists(2)
|
||||
external::get(2)
|
||||
string(3) "3rd"
|
||||
external::exists(4th)
|
||||
external::get(4th)
|
||||
int(4)
|
||||
external::exists(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
external::exists(6)
|
||||
|
||||
Notice: Undefined index: 6 in %s on line %d
|
||||
NULL
|
||||
external::exists(0)
|
||||
external::get(0)
|
||||
1st
|
||||
external::exists(1)
|
||||
external::get(1)
|
||||
1
|
||||
external::exists(2)
|
||||
external::get(2)
|
||||
3rd
|
||||
external::exists(4th)
|
||||
external::get(4th)
|
||||
4
|
||||
INTERNAL
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "1st"
|
||||
[1]=>
|
||||
int(1)
|
||||
[2]=>
|
||||
string(3) "3rd"
|
||||
["4th"]=>
|
||||
int(4)
|
||||
}
|
||||
internal::get(0)
|
||||
string(3) "1st"
|
||||
internal::get(1)
|
||||
int(1)
|
||||
internal::get(2)
|
||||
string(3) "3rd"
|
||||
internal::get(4th)
|
||||
int(4)
|
||||
internal::get(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
internal::get(6)
|
||||
|
||||
Notice: Undefined offset: 6 in %s on line %d
|
||||
NULL
|
||||
internal::exists(0)
|
||||
internal::get(0)
|
||||
string(3) "1st"
|
||||
internal::exists(1)
|
||||
internal::get(1)
|
||||
int(1)
|
||||
internal::exists(2)
|
||||
internal::get(2)
|
||||
string(3) "3rd"
|
||||
internal::exists(4th)
|
||||
internal::get(4th)
|
||||
int(4)
|
||||
internal::exists(5th)
|
||||
|
||||
Notice: Undefined index: 5th in %s on line %d
|
||||
NULL
|
||||
internal::exists(6)
|
||||
|
||||
Notice: Undefined index: 6 in %s on line %d
|
||||
NULL
|
||||
internal::exists(0)
|
||||
internal::get(0)
|
||||
1st
|
||||
internal::exists(1)
|
||||
internal::get(1)
|
||||
1
|
||||
internal::exists(2)
|
||||
internal::get(2)
|
||||
3rd
|
||||
internal::exists(4th)
|
||||
internal::get(4th)
|
||||
4
|
||||
Done
|
||||
@@ -1,193 +0,0 @@
|
||||
--TEST--
|
||||
SPL: foreach and iterator
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c_iter implements spl_forward_assoc {
|
||||
|
||||
private $obj;
|
||||
private $num = 0;
|
||||
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function current() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
echo __METHOD__ . "\n";
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
$more = $this->num < $this->obj->max;
|
||||
echo __METHOD__ . ' = ' .($more ? 'true' : 'false') . "\n";
|
||||
return $more;
|
||||
}
|
||||
function key() {
|
||||
echo __METHOD__ . "\n";
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class c implements spl_iterator {
|
||||
|
||||
public $max = 3;
|
||||
|
||||
function new_iterator() {
|
||||
echo __METHOD__ . "\n";
|
||||
return new c_iter($this);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
|
||||
for ($iter = $t->new_iterator(); $iter->has_more(); $iter->next()) {
|
||||
echo $iter->current() . "\n";
|
||||
}
|
||||
|
||||
$a = array(0,1,2);
|
||||
foreach($a as $v) {
|
||||
echo "array:$v\n";
|
||||
}
|
||||
|
||||
foreach($t as $v) {
|
||||
echo "object:$v\n";
|
||||
}
|
||||
|
||||
foreach($t as $v) {
|
||||
foreach($t as $w) {
|
||||
echo "double:$v:$w\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach($t as $i => $v) {
|
||||
echo "object:$i=>$v\n";
|
||||
}
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
array:0
|
||||
array:1
|
||||
array:2
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:0:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:0:1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:0:2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:1:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:1:1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:1:2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:2:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:2:1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:2:2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:1st=>0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:2nd=>1
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:3rd=>2
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
Done
|
||||
@@ -1,90 +0,0 @@
|
||||
--TEST--
|
||||
SPL: foreach and break
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c_iter implements spl_forward_assoc {
|
||||
|
||||
private $obj;
|
||||
private $num = 0;
|
||||
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function current() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
echo __METHOD__ . "\n";
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
$more = $this->num < $this->obj->max;
|
||||
echo __METHOD__ . ' = ' .($more ? 'true' : 'false') . "\n";
|
||||
return $more;
|
||||
}
|
||||
function key() {
|
||||
echo __METHOD__ . "\n";
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class c implements spl_iterator {
|
||||
|
||||
public $max = 3;
|
||||
|
||||
function new_iterator() {
|
||||
echo __METHOD__ . "\n";
|
||||
return new c_iter($this);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
|
||||
foreach($t as $v) {
|
||||
foreach($t as $w) {
|
||||
echo "double:$v:$w\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:0:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:1:0
|
||||
c_iter::next
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
c::new_iterator
|
||||
c_iter::has_more = true
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
double:2:0
|
||||
c_iter::next
|
||||
c_iter::has_more = false
|
||||
Done
|
||||
@@ -1,136 +0,0 @@
|
||||
--TEST--
|
||||
SPL: forward
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c implements spl_forward_assoc {
|
||||
|
||||
public $max = 3;
|
||||
public $num = 0;
|
||||
|
||||
function current() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
echo __METHOD__ . "\n";
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num < $this->max;
|
||||
}
|
||||
function key() {
|
||||
echo __METHOD__ . "\n";
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$i = new c();
|
||||
|
||||
$c_info = array(get_class($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
|
||||
print_r($c_info);
|
||||
$methods = get_class_methods("spl_forward_assoc");
|
||||
sort($methods);
|
||||
print_r($methods);
|
||||
$methods = get_class_methods($i);
|
||||
sort($methods);
|
||||
print_r($methods);
|
||||
|
||||
|
||||
echo "1st try\n";
|
||||
foreach($i as $w) {
|
||||
echo "object:$w\n";
|
||||
}
|
||||
|
||||
echo "2nd try\n";
|
||||
|
||||
foreach($i as $v => $w) {
|
||||
echo "object:$v=>$w\n";
|
||||
}
|
||||
|
||||
echo "3rd try\n";
|
||||
$i->num = 0;
|
||||
|
||||
foreach($i as $v => $w) {
|
||||
echo "object:$v=>$w\n";
|
||||
}
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[c] => Array
|
||||
(
|
||||
[inheits] => Array
|
||||
(
|
||||
)
|
||||
|
||||
[implements] => Array
|
||||
(
|
||||
[spl_forward_assoc] => spl_forward_assoc
|
||||
[spl_assoc] => spl_assoc
|
||||
[spl_forward] => spl_forward
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
Array
|
||||
(
|
||||
[0] => current
|
||||
[1] => has_more
|
||||
[2] => key
|
||||
[3] => next
|
||||
)
|
||||
Array
|
||||
(
|
||||
[0] => current
|
||||
[1] => has_more
|
||||
[2] => key
|
||||
[3] => next
|
||||
)
|
||||
1st try
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:0
|
||||
c::next
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:1
|
||||
c::next
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:2
|
||||
c::next
|
||||
c::has_more
|
||||
2nd try
|
||||
c::has_more
|
||||
3rd try
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:1st=>0
|
||||
c::next
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:2nd=>1
|
||||
c::next
|
||||
c::has_more
|
||||
c::current
|
||||
c::key
|
||||
object:3rd=>2
|
||||
c::next
|
||||
c::has_more
|
||||
Done
|
||||
@@ -1,138 +0,0 @@
|
||||
--TEST--
|
||||
SPL: sequence
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class c implements spl_iterator {
|
||||
|
||||
public $max = 3;
|
||||
|
||||
function new_iterator() {
|
||||
echo __METHOD__ . "\n";
|
||||
return new c_iter($this);
|
||||
}
|
||||
}
|
||||
|
||||
class c_iter implements spl_sequence_assoc {
|
||||
|
||||
private $obj;
|
||||
private $num = 0;
|
||||
|
||||
function __construct($obj) {
|
||||
$this->obj = $obj;
|
||||
}
|
||||
function rewind() {
|
||||
echo __METHOD__ . "\n";
|
||||
$this->num = 0;
|
||||
}
|
||||
function current() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num;
|
||||
}
|
||||
function next() {
|
||||
echo __METHOD__ . "\n";
|
||||
$this->num++;
|
||||
}
|
||||
function has_more() {
|
||||
echo __METHOD__ . "\n";
|
||||
return $this->num < $this->obj->max;
|
||||
}
|
||||
function key() {
|
||||
echo __METHOD__ . "\n";
|
||||
switch($this->num) {
|
||||
case 0: return "1st";
|
||||
case 1: return "2nd";
|
||||
case 2: return "3rd";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$t = new c();
|
||||
$i = $t->new_iterator();
|
||||
|
||||
$c_info = array(get_class($t) => array('inheits' => class_parents($t), 'implements' => class_implements($t)),
|
||||
get_class($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
|
||||
print_r($c_info);
|
||||
|
||||
foreach($i as $w) {
|
||||
echo "object:$w\n";
|
||||
}
|
||||
|
||||
foreach($i as $v => $w) {
|
||||
echo "object:$v=>$w\n";
|
||||
}
|
||||
|
||||
print "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
c::new_iterator
|
||||
Array
|
||||
(
|
||||
[c] => Array
|
||||
(
|
||||
[inheits] => Array
|
||||
(
|
||||
)
|
||||
|
||||
[implements] => Array
|
||||
(
|
||||
[spl_iterator] => spl_iterator
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[c_iter] => Array
|
||||
(
|
||||
[inheits] => Array
|
||||
(
|
||||
)
|
||||
|
||||
[implements] => Array
|
||||
(
|
||||
[spl_sequence_assoc] => spl_sequence_assoc
|
||||
[spl_forward_assoc] => spl_forward_assoc
|
||||
[spl_assoc] => spl_assoc
|
||||
[spl_forward] => spl_forward
|
||||
[spl_sequence] => spl_sequence
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
c_iter::rewind
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:0
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:1
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:2
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
c_iter::rewind
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:1st=>0
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:2nd=>1
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
c_iter::current
|
||||
c_iter::key
|
||||
object:3rd=>2
|
||||
c_iter::next
|
||||
c_iter::has_more
|
||||
Done
|
||||
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Andrei Zmievski <andrei@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
#include "basic_functions.h"
|
||||
#include "aggregation.h"
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
#include "ext/pcre/php_pcre.h"
|
||||
#endif
|
||||
|
||||
static void aggregation_info_dtor(aggregation_info *info)
|
||||
{
|
||||
/* FIXME: This is here to make it compile with Engine 2 but part of this module will need rewriting */
|
||||
|
||||
#ifndef ZEND_ENGINE_2
|
||||
destroy_zend_class(info->new_ce);
|
||||
efree(info->new_ce);
|
||||
#else
|
||||
/* FIXME: In ZE2, there seems to be an issue with refcounts or something between
|
||||
* this class entry and the original; there are problems when destroying the
|
||||
* function table.
|
||||
* Skipping deleting here will prevent a segfault but will leak
|
||||
* the class name, the static_members hash and the ce itself.
|
||||
* */
|
||||
|
||||
/* destroy_zend_class(&info->new_ce); */
|
||||
#endif
|
||||
zval_ptr_dtor(&info->aggr_members);
|
||||
|
||||
}
|
||||
|
||||
/* {{{ static zval* array_to_hash */
|
||||
static zval *array_to_hash(zval *array)
|
||||
{
|
||||
zval *hash, **entry;
|
||||
char *name_lc;
|
||||
|
||||
/*
|
||||
* Well, this just transposes the array, popularly known as flipping it, or
|
||||
* giving it the finger.
|
||||
*/
|
||||
MAKE_STD_ZVAL(hash);
|
||||
array_init(hash);
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(array), (void**)&entry) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(array))) {
|
||||
if (Z_TYPE_PP(entry) == IS_STRING) {
|
||||
/*
|
||||
* I hate case-insensitivity. Die, die, die.
|
||||
*/
|
||||
name_lc = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
|
||||
zend_str_tolower(name_lc, Z_STRLEN_PP(entry));
|
||||
add_assoc_bool_ex(hash, name_lc, Z_STRLEN_PP(entry)+1, 1);
|
||||
efree(name_lc);
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ static void aggregate_methods() */
|
||||
static void aggregate_methods(zend_class_entry *ce, zend_class_entry *from_ce, int aggr_type, zval *aggr_filter, zend_bool exclude, zval *aggr_methods TSRMLS_DC)
|
||||
{
|
||||
HashPosition pos;
|
||||
zend_function *function;
|
||||
char *func_name;
|
||||
uint func_name_len;
|
||||
ulong num_key;
|
||||
zval *list_hash = NULL;
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
pcre *re = NULL;
|
||||
pcre_extra *re_extra = NULL;
|
||||
int re_options = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flip the array for easy lookup, or compile the regexp.
|
||||
*/
|
||||
if (aggr_type == AGGREGATE_BY_LIST) {
|
||||
list_hash = array_to_hash(aggr_filter);
|
||||
}
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
else if (aggr_type == AGGREGATE_BY_REGEXP) {
|
||||
if ((re = pcre_get_compiled_regex(Z_STRVAL_P(aggr_filter), &re_extra, &re_options TSRMLS_CC)) == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "Just because it's not nice doesn't mean it's not miraculous."
|
||||
* -- _Interesting Times_, Terry Pratchett
|
||||
*/
|
||||
|
||||
/*
|
||||
* Aggregating by list without exclusion can be done more efficiently if we
|
||||
* iterate through the list and check against function table instead of the
|
||||
* other way around.
|
||||
*/
|
||||
if (aggr_type != AGGREGATE_BY_LIST || exclude) {
|
||||
zend_hash_internal_pointer_reset_ex(&from_ce->function_table, &pos);
|
||||
while (zend_hash_get_current_data_ex(&from_ce->function_table, (void**)&function, &pos) == SUCCESS) {
|
||||
zend_hash_get_current_key_ex(&from_ce->function_table, &func_name, &func_name_len, &num_key, 0, &pos);
|
||||
|
||||
/* We do not aggregate:
|
||||
* 1. constructors */
|
||||
if (!strncmp(func_name, from_ce->name, MIN(func_name_len-1, from_ce->name_length)) ||
|
||||
/* 2. private methods (heh, like we really have them) */
|
||||
func_name[0] == '_' ||
|
||||
/* 3. explicitly excluded methods */
|
||||
(aggr_type == AGGREGATE_BY_LIST && zend_hash_exists(Z_ARRVAL_P(list_hash), func_name, func_name_len))
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
||
|
||||
/* 4. methods matching regexp as modified by the exclusion flag */
|
||||
(aggr_type == AGGREGATE_BY_REGEXP && (pcre_exec(re, re_extra, func_name, func_name_len-1, 0, 0, NULL, 0) < 0) ^ exclude) == 1
|
||||
#endif
|
||||
) {
|
||||
zend_hash_move_forward_ex(&from_ce->function_table, &pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where the magic happens.
|
||||
*/
|
||||
if (zend_hash_add(&ce->function_table, func_name, func_name_len,
|
||||
(void*)function, sizeof(zend_function), NULL) == SUCCESS) {
|
||||
|
||||
add_next_index_stringl(aggr_methods, func_name, func_name_len-1, 1);
|
||||
}
|
||||
|
||||
zend_hash_move_forward_ex(&from_ce->function_table, &pos);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is just like above except the other way around.
|
||||
*/
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(list_hash));
|
||||
while (zend_hash_get_current_key_ex(Z_ARRVAL_P(list_hash), &func_name, &func_name_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) {
|
||||
if (!strncmp(func_name, from_ce->name, MIN(func_name_len-1, from_ce->name_length)) ||
|
||||
func_name[0] == '_' ||
|
||||
zend_hash_find(&from_ce->function_table, func_name, func_name_len, (void**)&function) == FAILURE) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(list_hash));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zend_hash_add(&ce->function_table, func_name, func_name_len,
|
||||
(void*)function, sizeof(zend_function), NULL) == SUCCESS) {
|
||||
add_next_index_stringl(aggr_methods, func_name, func_name_len-1, 1);
|
||||
}
|
||||
|
||||
zend_hash_move_forward(Z_ARRVAL_P(list_hash));
|
||||
}
|
||||
}
|
||||
|
||||
if (list_hash) {
|
||||
zval_ptr_dtor(&list_hash);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ static void aggregate_properties() */
|
||||
static void aggregate_properties(zval *obj, zend_class_entry *from_ce, int aggr_type, zval *aggr_filter, zend_bool exclude, zval *aggr_props TSRMLS_DC)
|
||||
{
|
||||
HashPosition pos;
|
||||
zval **prop;
|
||||
char *prop_name;
|
||||
uint prop_name_len;
|
||||
ulong num_key;
|
||||
zval *list_hash = NULL;
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
pcre *re = NULL;
|
||||
pcre_extra *re_extra = NULL;
|
||||
int re_options = 0;
|
||||
#endif
|
||||
|
||||
if (!from_ce->constants_updated) {
|
||||
zend_hash_apply_with_argument(&from_ce->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
|
||||
from_ce->constants_updated = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flip the array for easy lookup, or compile the regexp.
|
||||
*/
|
||||
if (aggr_type == AGGREGATE_BY_LIST) {
|
||||
list_hash = array_to_hash(aggr_filter);
|
||||
}
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
else if (aggr_type == AGGREGATE_BY_REGEXP) {
|
||||
if ((re = pcre_get_compiled_regex(Z_STRVAL_P(aggr_filter), &re_extra, &re_options TSRMLS_CC)) == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "Just because it's not nice doesn't mean it's not miraculous."
|
||||
* -- _Interesting Times_, Terry Pratchett
|
||||
*/
|
||||
|
||||
/*
|
||||
* Aggregating by list without exclusion can be done more efficiently if we
|
||||
* iterate through the list and check against default properties table
|
||||
* instead of the other way around.
|
||||
*/
|
||||
if (aggr_type != AGGREGATE_BY_LIST || exclude) {
|
||||
zend_hash_internal_pointer_reset_ex(&from_ce->default_properties, &pos);
|
||||
while (zend_hash_get_current_data_ex(&from_ce->default_properties, (void**)&prop, &pos) == SUCCESS) {
|
||||
zend_hash_get_current_key_ex(&from_ce->default_properties, &prop_name, &prop_name_len, &num_key, 0, &pos);
|
||||
|
||||
/* We do not aggregate:
|
||||
* 1. private properties (heh, like we really have them) */
|
||||
if (prop_name[0] == '_' ||
|
||||
/* 2. explicitly excluded properties */
|
||||
(aggr_type == AGGREGATE_BY_LIST && zend_hash_exists(Z_ARRVAL_P(list_hash), prop_name, prop_name_len))
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
||
|
||||
/* 3. properties matching regexp as modified by the exclusion flag */
|
||||
(aggr_type == AGGREGATE_BY_REGEXP && (pcre_exec(re, re_extra, prop_name, prop_name_len-1, 0, 0, NULL, 0) < 0) ^ exclude) == 1
|
||||
#endif
|
||||
) {
|
||||
zend_hash_move_forward_ex(&from_ce->default_properties, &pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where the magic happens.
|
||||
*/
|
||||
if (zend_hash_add(Z_OBJPROP_P(obj), prop_name, prop_name_len,
|
||||
(void*)prop, sizeof(zval *), NULL) == SUCCESS) {
|
||||
zval_add_ref(prop);
|
||||
add_next_index_stringl(aggr_props, prop_name, prop_name_len-1, 1);
|
||||
}
|
||||
|
||||
zend_hash_move_forward_ex(&from_ce->default_properties, &pos);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is just like above except the other way around.
|
||||
*/
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(list_hash));
|
||||
while (zend_hash_get_current_key_ex(Z_ARRVAL_P(list_hash), &prop_name, &prop_name_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) {
|
||||
if (prop_name[0] == '_' ||
|
||||
zend_hash_find(&from_ce->default_properties, prop_name, prop_name_len, (void**)&prop) == FAILURE) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(list_hash));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zend_hash_add(Z_OBJPROP_P(obj), prop_name, prop_name_len,
|
||||
(void*)prop, sizeof(zval *), NULL) == SUCCESS) {
|
||||
zval_add_ref(prop);
|
||||
add_next_index_stringl(aggr_props, prop_name, prop_name_len-1, 1);
|
||||
}
|
||||
|
||||
zend_hash_move_forward(Z_ARRVAL_P(list_hash));
|
||||
}
|
||||
}
|
||||
|
||||
if (list_hash) {
|
||||
zval_ptr_dtor(&list_hash);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ static void aggregate() */
|
||||
static void aggregate(INTERNAL_FUNCTION_PARAMETERS, int aggr_what, int aggr_type)
|
||||
{
|
||||
/* Incoming parameters. */
|
||||
zval *obj, *aggr_list = NULL;
|
||||
char *class_name, *class_name_lc, *aggr_regexp;
|
||||
int class_name_len, aggr_regexp_len;
|
||||
zend_bool exclude = 0;
|
||||
|
||||
/* Other variables. */
|
||||
zval **aggr_members, z_aggr_regexp;
|
||||
zend_class_entry *ce, *new_ce;
|
||||
zend_function tmp_zend_function;
|
||||
aggregation_info aggr_info_new, *aggr_info = &aggr_info_new;
|
||||
zval *aggr_methods_new, **aggr_methods = &aggr_methods_new;
|
||||
zval *aggr_props_new, **aggr_props = &aggr_props_new;
|
||||
zval *aggr_filter = NULL;
|
||||
int zpp_result = FAILURE;
|
||||
|
||||
/*
|
||||
* Ah, the beauty of the new parameter parsing API. Almost as good as Heidi Klum.
|
||||
*/
|
||||
switch (aggr_type) {
|
||||
case AGGREGATE_ALL:
|
||||
zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &obj,
|
||||
&class_name, &class_name_len);
|
||||
break;
|
||||
|
||||
case AGGREGATE_BY_LIST:
|
||||
zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "osa|b", &obj,
|
||||
&class_name, &class_name_len,
|
||||
&aggr_list, &exclude);
|
||||
break;
|
||||
|
||||
case AGGREGATE_BY_REGEXP:
|
||||
zpp_result = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oss|b", &obj,
|
||||
&class_name, &class_name_len,
|
||||
&aggr_regexp, &aggr_regexp_len, &exclude);
|
||||
ZVAL_STRINGL(&z_aggr_regexp, aggr_regexp, aggr_regexp_len, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (zpp_result == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case-insensitivity is like that last freaking mutant from horror movies:
|
||||
* irradiated, blown in half, its eyes melting in their sockets, yet still
|
||||
* dragging itself closer and closer to you until it's pulverized into
|
||||
* microscopic pieces via some last-minute contrivance. And even then you
|
||||
* are not sure that it's finally dead. But that's just how I feel.
|
||||
*/
|
||||
class_name_lc = estrndup(class_name, class_name_len);
|
||||
zend_str_tolower(class_name_lc, class_name_len);
|
||||
if (zend_hash_find(EG(class_table), class_name_lc,
|
||||
class_name_len+1, (void **)&ce) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects the second parameter to be a valid class name, '%s' given", class_name);
|
||||
efree(class_name_lc);
|
||||
return;
|
||||
}
|
||||
#ifdef ZEND_ENGINE_2
|
||||
ce = *(zend_class_entry**)ce;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* And God said, Let there be light; and there was light. But only once.
|
||||
*/
|
||||
if (!BG(aggregation_table)) {
|
||||
BG(aggregation_table) = (HashTable *) emalloc(sizeof(HashTable));
|
||||
zend_hash_init(BG(aggregation_table), 5, NULL, (dtor_func_t) aggregation_info_dtor, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Digging deep in the rabbit hole with a long object.. and coming up
|
||||
* more empty than the imagination of whoever made "Battlefield Earth".
|
||||
*/
|
||||
if (zend_hash_index_find(BG(aggregation_table), (long)obj, (void**)&aggr_info) == FAILURE) {
|
||||
zval *tmp;
|
||||
|
||||
/*
|
||||
* You are not expected to understand this.
|
||||
*/
|
||||
new_ce = emalloc(sizeof(zend_class_entry));
|
||||
new_ce->type = ZEND_USER_CLASS;
|
||||
new_ce->name = estrndup(Z_OBJCE_P(obj)->name, Z_OBJCE_P(obj)->name_length);
|
||||
new_ce->name_length = Z_OBJCE_P(obj)->name_length;
|
||||
new_ce->parent = Z_OBJCE_P(obj)->parent;
|
||||
#ifdef ZEND_ENGINE_2
|
||||
new_ce->refcount = 1;
|
||||
#else
|
||||
new_ce->refcount = (int *) emalloc(sizeof(int));
|
||||
*new_ce->refcount = 1;
|
||||
#endif
|
||||
new_ce->constants_updated = Z_OBJCE_P(obj)->constants_updated;
|
||||
zend_hash_init(&new_ce->function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0);
|
||||
zend_hash_init(&new_ce->default_properties, 10, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(&new_ce->function_table, &Z_OBJCE_P(obj)->function_table, (copy_ctor_func_t) function_add_ref, &tmp_zend_function, sizeof(zend_function));
|
||||
zend_hash_copy(&new_ce->default_properties, &Z_OBJCE_P(obj)->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
|
||||
#ifdef ZEND_ENGINE_2
|
||||
ALLOC_HASHTABLE(new_ce->static_members);
|
||||
zend_hash_init(new_ce->static_members, 10, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(new_ce->static_members, Z_OBJCE_P(obj)->static_members, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
zend_hash_init(&new_ce->constants_table, 10, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(&new_ce->constants_table, &Z_OBJCE_P(obj)->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
zend_hash_init(&new_ce->class_table, 10, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(&new_ce->class_table, &Z_OBJCE_P(obj)->class_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
|
||||
/*
|
||||
zend_hash_init(&new_ce->private_properties, 10, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(&new_ce->private_properties, &Z_OBJCE_P(obj)->private_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
*/
|
||||
|
||||
new_ce->constructor = Z_OBJCE_P(obj)->constructor;
|
||||
new_ce->destructor = Z_OBJCE_P(obj)->destructor;
|
||||
new_ce->clone = Z_OBJCE_P(obj)->clone;
|
||||
#endif
|
||||
|
||||
new_ce->builtin_functions = Z_OBJCE_P(obj)->builtin_functions;
|
||||
#ifndef ZEND_ENGINE_2
|
||||
new_ce->handle_function_call = Z_OBJCE_P(obj)->handle_function_call;
|
||||
new_ce->handle_property_get = Z_OBJCE_P(obj)->handle_property_get;
|
||||
new_ce->handle_property_set = Z_OBJCE_P(obj)->handle_property_set;
|
||||
#else
|
||||
new_ce->__call = Z_OBJCE_P(obj)->__call;
|
||||
new_ce->__get = Z_OBJCE_P(obj)->__get;
|
||||
new_ce->__set = Z_OBJCE_P(obj)->__set;
|
||||
#endif
|
||||
/*
|
||||
* Okay, that was kind of exhausting. Let's invoke programmer virtue #1
|
||||
* and stuff this where it belongs so we don't have to work so hard next
|
||||
* time.
|
||||
*/
|
||||
/* OBJECT FIXME!! won't work with non-standard objects */
|
||||
#ifndef ZEND_ENGINE_2
|
||||
(Z_OBJ_P(obj))->ce = new_ce;
|
||||
#endif
|
||||
aggr_info_new.new_ce = new_ce;
|
||||
MAKE_STD_ZVAL(aggr_info_new.aggr_members);
|
||||
array_init(aggr_info_new.aggr_members);
|
||||
|
||||
zend_hash_index_update(BG(aggregation_table), (long)obj,
|
||||
(void *)&aggr_info_new, sizeof(aggregation_info), NULL);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Seek and ye shall find.
|
||||
*/
|
||||
new_ce = aggr_info->new_ce;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be easy to understand. If not, ask Rasmus about it at his
|
||||
* next tutorial.
|
||||
*/
|
||||
if (zend_hash_find(Z_ARRVAL_P(aggr_info->aggr_members), class_name_lc,
|
||||
class_name_len+1, (void **)&aggr_members) == FAILURE) {
|
||||
zval *tmp;
|
||||
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
array_init(tmp);
|
||||
MAKE_STD_ZVAL(aggr_methods_new);
|
||||
array_init(aggr_methods_new);
|
||||
MAKE_STD_ZVAL(aggr_props_new);
|
||||
array_init(aggr_props_new);
|
||||
add_assoc_zval_ex(tmp, "methods", sizeof("methods"), aggr_methods_new);
|
||||
add_assoc_zval_ex(tmp, "properties", sizeof("properties"), aggr_props_new);
|
||||
|
||||
zend_hash_add(Z_ARRVAL_P(aggr_info->aggr_members), class_name_lc,
|
||||
class_name_len+1, &tmp, sizeof(zval *), NULL);
|
||||
} else {
|
||||
zend_hash_find(Z_ARRVAL_PP(aggr_members), "methods", sizeof("methods"), (void**)&aggr_methods);
|
||||
zend_hash_find(Z_ARRVAL_PP(aggr_members), "properties", sizeof("properties"), (void**)&aggr_props);
|
||||
}
|
||||
|
||||
if (aggr_type == AGGREGATE_BY_LIST) {
|
||||
aggr_filter = aggr_list;
|
||||
} else if (aggr_type == AGGREGATE_BY_REGEXP) {
|
||||
aggr_filter = &z_aggr_regexp;
|
||||
}
|
||||
|
||||
if (aggr_what == AGGREGATE_METHODS || aggr_what == AGGREGATE_ALL) {
|
||||
aggregate_methods(new_ce, ce, aggr_type, aggr_filter, exclude, *aggr_methods TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (aggr_what == AGGREGATE_PROPERTIES || aggr_what == AGGREGATE_ALL) {
|
||||
aggregate_properties(obj, ce, aggr_type, aggr_filter, exclude, *aggr_props TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes, we have to clean up after monsters. Tsk-tsk.
|
||||
*/
|
||||
efree(class_name_lc);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate(object obj, string class)
|
||||
*/
|
||||
PHP_FUNCTION(aggregate)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_ALL, AGGREGATE_ALL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate_methods(object obj, string class)
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_methods)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_METHODS, AGGREGATE_ALL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate_methods_by_list(object obj, string class, array method_list [, bool exclude])
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_methods_by_list)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_METHODS, AGGREGATE_BY_LIST);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate_properties(object obj, string class)
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_properties)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_PROPERTIES, AGGREGATE_ALL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate_properties_by_list(object obj, string class, array props_list [, bool exclude])
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_properties_by_list)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_PROPERTIES, AGGREGATE_BY_LIST);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
|
||||
/* {{{ proto void aggregate_methods_by_regexp(object obj, string class, string regexp [, bool exclude])
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_methods_by_regexp)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_METHODS, AGGREGATE_BY_REGEXP);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void aggregate_properties_by_regexp(object obj, string class, string regexp [, bool exclude])
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_properties_by_regexp)
|
||||
{
|
||||
aggregate(INTERNAL_FUNCTION_PARAM_PASSTHRU, AGGREGATE_PROPERTIES, AGGREGATE_BY_REGEXP);
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ proto array aggregate_info(object obj)
|
||||
*/
|
||||
PHP_FUNCTION(aggregate_info)
|
||||
{
|
||||
zval *obj;
|
||||
aggregation_info *aggr_info;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BG(aggregation_table) ||
|
||||
zend_hash_index_find(BG(aggregation_table), (long)obj, (void**)&aggr_info) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
*return_value = *aggr_info->aggr_members;
|
||||
zval_copy_ctor(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void deaggregate(object obj [, string class])
|
||||
*/
|
||||
PHP_FUNCTION(deaggregate)
|
||||
{
|
||||
zval *obj;
|
||||
char *class_name = NULL, *class_name_lc;
|
||||
int class_name_len;
|
||||
aggregation_info *aggr_info;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s", &obj,
|
||||
&class_name, &class_name_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BG(aggregation_table) ||
|
||||
zend_hash_index_find(BG(aggregation_table), (long)obj, (void**)&aggr_info) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_name) {
|
||||
zval **aggr_members,
|
||||
**aggr_methods,
|
||||
**aggr_props,
|
||||
**method, **prop;
|
||||
|
||||
class_name_lc = estrndup(class_name, class_name_len);
|
||||
zend_str_tolower(class_name_lc, class_name_len);
|
||||
|
||||
if (zend_hash_find(Z_ARRVAL_P(aggr_info->aggr_members), class_name_lc,
|
||||
class_name_len+1, (void **)&aggr_members) == FAILURE) {
|
||||
efree(class_name_lc);
|
||||
return;
|
||||
}
|
||||
|
||||
zend_hash_find(Z_ARRVAL_PP(aggr_members), "methods", sizeof("methods"), (void**)&aggr_methods);
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(aggr_methods));
|
||||
zend_hash_get_current_data(Z_ARRVAL_PP(aggr_methods), (void**)&method) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_PP(aggr_methods))) {
|
||||
zend_hash_del(&Z_OBJCE_P(obj)->function_table, Z_STRVAL_PP(method), Z_STRLEN_PP(method)+1);
|
||||
}
|
||||
|
||||
zend_hash_find(Z_ARRVAL_PP(aggr_members), "properties", sizeof("properties"), (void**)&aggr_props);
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(aggr_props));
|
||||
zend_hash_get_current_data(Z_ARRVAL_PP(aggr_props), (void**)&prop) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_PP(aggr_props))) {
|
||||
zend_hash_del(Z_OBJPROP_P(obj), Z_STRVAL_PP(prop), Z_STRLEN_PP(prop)+1);
|
||||
}
|
||||
|
||||
zend_hash_del(Z_ARRVAL_P(aggr_info->aggr_members), class_name_lc, class_name_len+1);
|
||||
|
||||
efree(class_name_lc);
|
||||
} else {
|
||||
zend_class_entry *orig_ce;
|
||||
zval **aggr_members;
|
||||
zval **aggr_props, **prop;
|
||||
|
||||
if (zend_hash_find(EG(class_table), Z_OBJCE_P(obj)->name,
|
||||
Z_OBJCE_P(obj)->name_length+1, (void **)&orig_ce) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal deaggregation error");
|
||||
return;
|
||||
}
|
||||
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(aggr_info->aggr_members));
|
||||
zend_hash_get_current_data(Z_ARRVAL_P(aggr_info->aggr_members), (void **)&aggr_members) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(aggr_info->aggr_members))) {
|
||||
zend_hash_find(Z_ARRVAL_PP(aggr_members), "properties", sizeof("properties"), (void**)&aggr_props);
|
||||
for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(aggr_props));
|
||||
zend_hash_get_current_data(Z_ARRVAL_PP(aggr_props), (void**)&prop) == SUCCESS;
|
||||
zend_hash_move_forward(Z_ARRVAL_PP(aggr_props))) {
|
||||
zend_hash_del(Z_OBJPROP_P(obj), Z_STRVAL_PP(prop), Z_STRLEN_PP(prop)+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* OBJECT FIXME!! won't work with non-standard objects */
|
||||
#ifndef ZEND_ENGINE_2
|
||||
(Z_OBJ_P(obj))->ce = orig_ce;
|
||||
#endif
|
||||
zend_hash_index_del(BG(aggregation_table), (long)obj);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
Executable → Regular
+30
-28
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -12,38 +12,40 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
| Author: Andrei Zmievski <andrei@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef SPL_ARRAY_H
|
||||
#define SPL_ARRAY_H
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
#include "php_spl.h"
|
||||
#ifndef AGGREGATION_H
|
||||
#define AGGREGATION_H
|
||||
|
||||
#ifdef SPL_ARRAY_READ
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_R);
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_W);
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW);
|
||||
#endif
|
||||
#define AGGREGATE_ALL 0
|
||||
|
||||
#ifdef SPL_ARRAY_WRITE
|
||||
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN);
|
||||
#endif
|
||||
#define AGGREGATE_METHODS 1
|
||||
#define AGGREGATE_PROPERTIES 2
|
||||
|
||||
SPL_CLASS_FUNCTION(array_writer_default, __construct);
|
||||
SPL_CLASS_FUNCTION(array_writer_default, set);
|
||||
|
||||
zend_object_value spl_array_writer_default_create(zend_class_entry *class_type TSRMLS_DC);
|
||||
|
||||
#endif /* SPL_ARRAY_H */
|
||||
#define AGGREGATE_BY_LIST 1
|
||||
#define AGGREGATE_BY_REGEXP 2
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
* vim600: fdm=marker
|
||||
* vim: noet sw=4 ts=4
|
||||
* Data structure that is stored in aggregation_table hashtable for each object.
|
||||
*/
|
||||
typedef struct {
|
||||
zend_class_entry *new_ce;
|
||||
zval *aggr_members;
|
||||
} aggregation_info;
|
||||
|
||||
PHP_FUNCTION(aggregate);
|
||||
PHP_FUNCTION(aggregate_methods);
|
||||
PHP_FUNCTION(aggregate_methods_by_list);
|
||||
PHP_FUNCTION(aggregate_methods_by_regexp);
|
||||
PHP_FUNCTION(aggregate_properties);
|
||||
PHP_FUNCTION(aggregate_properties_by_list);
|
||||
PHP_FUNCTION(aggregate_properties_by_regexp);
|
||||
PHP_FUNCTION(aggregate);
|
||||
PHP_FUNCTION(deaggregate);
|
||||
PHP_FUNCTION(aggregate_info);
|
||||
|
||||
#endif /* AGGREGATION_H */
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
class simple {
|
||||
var $simple_prop = 100;
|
||||
|
||||
function simple()
|
||||
{
|
||||
print "I'm alive!\n";
|
||||
}
|
||||
}
|
||||
|
||||
class helper {
|
||||
var $my_prop = 5;
|
||||
var $your_prop = array('init' => PHP_VERSION);
|
||||
var $our_prop = '****';
|
||||
var $_priv_prop = null;
|
||||
|
||||
function helper()
|
||||
{
|
||||
print "just trying to help\n";
|
||||
}
|
||||
|
||||
function do_this()
|
||||
{
|
||||
print "I'm helping!\n";
|
||||
}
|
||||
|
||||
function do_that()
|
||||
{
|
||||
print "I'm aggregating!\n";
|
||||
}
|
||||
|
||||
function just_another_method()
|
||||
{
|
||||
print "yep, that's me\n";
|
||||
}
|
||||
|
||||
function _private()
|
||||
{
|
||||
print "Don't touch me!\n";
|
||||
}
|
||||
|
||||
function __wakeup()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class mixin {
|
||||
var $simple_prop = true;
|
||||
var $mix = true;
|
||||
|
||||
function mix_it()
|
||||
{
|
||||
print "mixing\n";
|
||||
}
|
||||
}
|
||||
|
||||
class moby {
|
||||
function mix_it()
|
||||
{
|
||||
print "I'm redundant!\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
aggregating everything
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate($obj, 'helper');
|
||||
$obj->do_this();
|
||||
$obj->do_that();
|
||||
print $obj->our_prop;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
I'm helping!
|
||||
I'm aggregating!
|
||||
****
|
||||
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
aggregating all methods
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_methods($obj, 'mixin');
|
||||
$obj->mix_it();
|
||||
print $obj->simple_prop."\n";
|
||||
print implode(',', get_class_methods($obj))."\n";
|
||||
print implode(',', array_keys(get_object_vars($obj)))."\n";
|
||||
aggregate_methods($obj, 'moby');
|
||||
$obj->mix_it();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
mixing
|
||||
100
|
||||
simple,mix_it
|
||||
simple_prop
|
||||
mixing
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
aggregating methods specified in the list
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_methods_by_list($obj, 'helper', array('just_another_method'));
|
||||
print implode(',', get_class_methods($obj))."\n";
|
||||
$obj2 = new simple();
|
||||
aggregate_methods_by_list($obj2, 'helper', array('just_another_method'), true);
|
||||
print implode(',', get_class_methods($obj2))."\n";
|
||||
$obj->just_another_method();
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
simple,just_another_method
|
||||
I'm alive!
|
||||
simple,do_this,do_that
|
||||
yep, that's me
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
aggregating methods matching regular expression
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_methods_by_regexp($obj, 'helper', '/^do/');
|
||||
print implode(',', get_class_methods($obj))."\n";
|
||||
$obj2 = new simple();
|
||||
aggregate_methods_by_regexp($obj2, 'helper', '/^do/', true);
|
||||
print implode(',', get_class_methods($obj2))."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
simple,do_this,do_that
|
||||
I'm alive!
|
||||
simple,just_another_method
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
aggregating all default properties
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_properties($obj, 'mixin');
|
||||
print implode(',', array_keys(get_object_vars($obj)))."\n";
|
||||
print $obj->simple_prop."\n";
|
||||
print implode(',', get_class_methods($obj))."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
simple_prop,mix
|
||||
100
|
||||
simple
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
aggregating default properties specified in the list
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_properties_by_list($obj, 'helper', array('my_prop', 'our_prop'));
|
||||
print implode(',', array_keys(get_object_vars($obj)))."\n";
|
||||
$obj2 = new simple();
|
||||
aggregate_properties_by_list($obj2, 'helper', array('my_prop'), true);
|
||||
print implode(',', array_keys(get_object_vars($obj2)))."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
simple_prop,my_prop,our_prop
|
||||
I'm alive!
|
||||
simple_prop,your_prop,our_prop
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
aggregating default properties matching regular expression
|
||||
--SKIPIF--
|
||||
<?php if (!function_exists('aggregate_properties_by_regexp')) print "skip"; ?>
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate_properties_by_regexp($obj, 'helper', '/^my/');
|
||||
print implode(',', array_keys(get_object_vars($obj)))."\n";
|
||||
$obj2 = new simple();
|
||||
aggregate_properties_by_regexp($obj2, 'helper', '/^my/', true);
|
||||
print implode(',', array_keys(get_object_vars($obj2)))."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
simple_prop,my_prop
|
||||
I'm alive!
|
||||
simple_prop,your_prop,our_prop
|
||||
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
retrieving aggregation info
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate($obj, 'mixin');
|
||||
print_r(aggregation_info($obj));
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
Array
|
||||
(
|
||||
[mixin] => Array
|
||||
(
|
||||
[methods] => Array
|
||||
(
|
||||
[0] => mix_it
|
||||
)
|
||||
|
||||
[properties] => Array
|
||||
(
|
||||
[0] => mix
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
@@ -0,0 +1,72 @@
|
||||
--TEST--
|
||||
deaggreating
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
include "ext/standard/tests/aggregation/aggregate.lib";
|
||||
|
||||
$obj = new simple();
|
||||
aggregate($obj, 'helper');
|
||||
aggregate($obj, 'mixin');
|
||||
print_r(aggregation_info($obj));
|
||||
deaggregate($obj, 'helper');
|
||||
print_r(aggregation_info($obj));
|
||||
deaggregate($obj);
|
||||
var_dump(aggregation_info($obj));
|
||||
?>
|
||||
--EXPECT--
|
||||
I'm alive!
|
||||
Array
|
||||
(
|
||||
[helper] => Array
|
||||
(
|
||||
[methods] => Array
|
||||
(
|
||||
[0] => do_this
|
||||
[1] => do_that
|
||||
[2] => just_another_method
|
||||
)
|
||||
|
||||
[properties] => Array
|
||||
(
|
||||
[0] => my_prop
|
||||
[1] => your_prop
|
||||
[2] => our_prop
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[mixin] => Array
|
||||
(
|
||||
[methods] => Array
|
||||
(
|
||||
[0] => mix_it
|
||||
)
|
||||
|
||||
[properties] => Array
|
||||
(
|
||||
[0] => mix
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
Array
|
||||
(
|
||||
[mixin] => Array
|
||||
(
|
||||
[methods] => Array
|
||||
(
|
||||
[0] => mix_it
|
||||
)
|
||||
|
||||
[properties] => Array
|
||||
(
|
||||
[0] => mix
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
bool(false)
|
||||
+5
-1
@@ -273,7 +273,11 @@ php_xml_compat_handlers = {
|
||||
_comment_handler, /* comment */
|
||||
NULL, /* warning */
|
||||
NULL, /* error */
|
||||
NULL /* fatalError */
|
||||
NULL, /* fatalError */
|
||||
NULL, /* getParameterEntity */
|
||||
_cdata_handler, /* cdataBlock */
|
||||
NULL, /* externalSubset */
|
||||
1
|
||||
};
|
||||
|
||||
XML_Parser
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP version 4.0 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.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. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sander Steffann (sander@steffann.nl) |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef MAXSYMLINKS
|
||||
#define MAXSYMLINKS 32
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path[]);
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define IS_SLASH(p) ((p) == '/' || (p) == '\\')
|
||||
#else
|
||||
#define IS_SLASH(p) ((p) == '/')
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path []) {
|
||||
char path_construction[MAXPATHLEN]; /* We build the result in here */
|
||||
char *writepos; /* Position to write next char */
|
||||
|
||||
char path_copy[MAXPATHLEN]; /* A work-copy of the path */
|
||||
char *workpos; /* working position in *path */
|
||||
|
||||
#if !defined(PHP_WIN32)
|
||||
char buf[MAXPATHLEN]; /* Buffer for readlink */
|
||||
int linklength; /* The result from readlink */
|
||||
#endif
|
||||
int linkcount = 0; /* Count symlinks to avoid loops */
|
||||
|
||||
struct stat filestat; /* result from stat */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
char *temppos; /* position while counting '.' */
|
||||
int dotcount; /* number of '.' */
|
||||
int t; /* counter */
|
||||
#endif
|
||||
|
||||
/* Set the work-position to the beginning of the given path */
|
||||
strcpy(path_copy, path);
|
||||
workpos = path_copy;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* Find out where we start - Windows version */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
/* We start at the root of the current drive */
|
||||
/* Get the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
/* We only need the first three chars (for example "C:\") */
|
||||
path_construction[3] = 0;
|
||||
workpos++;
|
||||
} else if (workpos[1] == ':') {
|
||||
/* A drive-letter is specified, copy it */
|
||||
strncpy(path_construction, path, 2);
|
||||
strcat(path_construction, "\\");
|
||||
workpos++;
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "\\");
|
||||
}
|
||||
#else
|
||||
/* Find out where we start - Unix version */
|
||||
if (*workpos == '/') {
|
||||
/* We start at the root */
|
||||
strcpy(path_construction, "/");
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "/");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the next-char-position */
|
||||
writepos = &path_construction[strlen(path_construction)];
|
||||
|
||||
/* Go to the end, then stop */
|
||||
while(*workpos != 0) {
|
||||
/* Strip (back)slashes */
|
||||
while(IS_SLASH(*workpos)) workpos++;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* reset dotcount */
|
||||
dotcount = 0;
|
||||
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
/* Windows accepts \...\ as \..\..\, \....\ as \..\..\..\, etc */
|
||||
/* At least Win98 does */
|
||||
|
||||
temppos = workpos;
|
||||
while(*temppos++ == '.') {
|
||||
dotcount++;
|
||||
if (!IS_SLASH(*temppos) && (*temppos != 0) && (*temppos != '.')) {
|
||||
/* This is not a /../ component, but a filename that starts with '.' */
|
||||
dotcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go back dotcount-1 times */
|
||||
for (t=0 ; t<(dotcount-1) ; t++) {
|
||||
workpos++; /* move to next '.' */
|
||||
|
||||
/* Can we still go back? */
|
||||
if ((writepos-3) <= path_construction) return NULL;
|
||||
|
||||
/* Go back */
|
||||
writepos--; /* move to '\' */
|
||||
writepos--;
|
||||
while(!IS_SLASH(*writepos)) writepos--; /* skip until previous '\\' */
|
||||
}
|
||||
workpos++;
|
||||
}
|
||||
|
||||
/* No special case */
|
||||
if (dotcount == 0) {
|
||||
/* Append */
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just one '.', go to next element */
|
||||
if (dotcount == 1) {
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*workpos++;
|
||||
}
|
||||
|
||||
/* Avoid double \ in the result */
|
||||
writepos--;
|
||||
}
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#else /* defined(PHP_WIN32) */
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
if ((workpos[1] == '.') && ((workpos[2] == '/') || (workpos[2] == 0))) {
|
||||
/* One directory back */
|
||||
/* Set pointers to right position */
|
||||
workpos++; /* move to second '.' */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Only apply .. if not in root */
|
||||
if ((writepos-1) > path_construction) {
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
}
|
||||
} else {
|
||||
if (workpos[1] == '/') {
|
||||
/* Found a /./ skip it */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Avoid double / in the result */
|
||||
writepos--;
|
||||
} else {
|
||||
/* No special case, the name just started with a . */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No special case */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SYMLINK
|
||||
/* We are going to use path_construction, so close it */
|
||||
*writepos = 0;
|
||||
|
||||
/* Check the current location to see if it is a symlink */
|
||||
if((linklength = readlink(path_construction, buf, MAXPATHLEN)) != -1) {
|
||||
/* Check linkcount */
|
||||
if (linkcount > MAXSYMLINKS) return NULL;
|
||||
|
||||
/* Count this symlink */
|
||||
linkcount++;
|
||||
|
||||
/* Set end of buf */
|
||||
buf[linklength] = 0;
|
||||
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) return NULL;
|
||||
|
||||
/* Remove the symlink-component wrom path_construction */
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
*++writepos = 0; /* end of string after '/' */
|
||||
|
||||
/* If the symlink starts with a '/', empty path_construction */
|
||||
if (*buf == '/') {
|
||||
*path_construction = 0;
|
||||
writepos = path_construction;
|
||||
}
|
||||
|
||||
/* Insert symlink into path_copy */
|
||||
strcat(buf, workpos);
|
||||
strcpy(path_copy, buf);
|
||||
workpos = path_copy;
|
||||
}
|
||||
#endif /* HAVE_SYMLINK */
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (*workpos == '/') {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#endif /* defined(PHP_WIN32) */
|
||||
}
|
||||
|
||||
/* Check if the resolved path is a directory */
|
||||
if (V_STAT(path_construction, &filestat) != 0) {
|
||||
if (errno != ENOENT) return NULL;
|
||||
} else {
|
||||
if (S_ISDIR(filestat.st_mode)) {
|
||||
/* It's a directory, append a / if needed */
|
||||
if (*(writepos-1) != '/') {
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + 2) >= MAXPATHLEN) {
|
||||
return NULL;
|
||||
}
|
||||
*writepos++ = '/';
|
||||
*writepos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(resolved_path, path_construction);
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
+2
-2
@@ -3,5 +3,5 @@
|
||||
#define PHP_MAJOR_VERSION 5
|
||||
#define PHP_MINOR_VERSION 0
|
||||
#define PHP_RELEASE_VERSION 0
|
||||
#define PHP_EXTRA_VERSION "b2-dev"
|
||||
#define PHP_VERSION "5.0.0b2-dev"
|
||||
#define PHP_EXTRA_VERSION "b1"
|
||||
#define PHP_VERSION "5.0.0b1"
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
#include "php.h"
|
||||
|
||||
#ifndef HAVE_STRTOK_R
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Softweyr LLC. All rights reserved.
|
||||
*
|
||||
* strtok_r, from Berkeley strtok
|
||||
* Oct 13, 1998 by Wes Peters <wes@softweyr.com>
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notices, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notices, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by Softweyr LLC, the
|
||||
* University of California, Berkeley, and its contributors.
|
||||
*
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
|
||||
* REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *spanp;
|
||||
int c, sc;
|
||||
char *tok;
|
||||
|
||||
if (s == NULL && (s = *last) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char *)delim; (sc = *spanp++) != 0; )
|
||||
{
|
||||
if (c == sc)
|
||||
{
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 0) /* no non-delimiter characters */
|
||||
{
|
||||
*last = NULL;
|
||||
return NULL;
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
c = *s++;
|
||||
spanp = (char *)delim;
|
||||
do
|
||||
{
|
||||
if ((sc = *spanp++) == c)
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
s = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *w = s - 1;
|
||||
*w = '\0';
|
||||
}
|
||||
*last = s;
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user