Actually, this can be done. Via php extension.
File: config.m4
PHP_ARG_ENABLE (test, whether to enable test Extension support, [--enable-test Enable test ext support])
if test "$ PHP_TEST" = "yes"; then
AC_DEFINE (HAVE_TEST, 1, [Enable TEST Extension])
PHP_NEW_EXTENSION (test, test.c, $ ext_shared)
fi
File: php_test.h
#ifndef PHP_TEST_H
#define PHP_TEST_H 1
#define PHP_TEST_EXT_VERSION "1.0"
#define PHP_TEST_EXT_EXTNAME "test"
PHP_FUNCTION (getaddress4);
PHP_FUNCTION (getaddress);
extern zend_module_entry test_module_entry;
#define phpext_test_ptr & test_module_entry
#endif
File: test.c
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_test.h"
ZEND_BEGIN_ARG_INFO_EX (func_args, 1, 0, 0)
ZEND_END_ARG_INFO ()
static function_entry test_functions [] = {
PHP_FE (getaddress4, func_args)
PHP_FE (getaddress, func_args)
{NULL, NULL, NULL}
};
zend_module_entry test_module_entry = {
#if ZEND_MODULE_API_NO> = 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_TEST_EXT_EXTNAME,
test_functions
NULL
NULL
NULL
NULL
NULL
#if ZEND_MODULE_API_NO> = 20010901
PHP_TEST_EXT_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_TEST
ZEND_GET_MODULE (test)
#endif
PHP_FUNCTION (getaddress4)
{
zval * var1;
zval * var2;
zval * var3;
zval * var4;
char r [500];
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "aaaa", & var1, & var2, & var3, & var4) == FAILURE) {
RETURN_NULL ();
}
sprintf (r, "\ n% p -% p -% p -% p \ n% p -% p -% p -% p", var1, var2, var3, var4, Z_ARRVAL_P (var1), Z_ARRVAL_P (var2) , Z_ARRVAL_P (var3), Z_ARRVAL_P (var4));
RETURN_STRING (r, 1);
}
PHP_FUNCTION (getaddress)
{
zval * var;
char r [100];
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "a", & var) == FAILURE) {
RETURN_NULL ();
}
sprintf (r, "% p", Z_ARRVAL_P (var));
RETURN_STRING (r, 1);
}
Then all you have to do is phpize, configure it and do it. Add "extension = / path / to / so / file / modules / test.so" to the php.ini file. Finally, restart the web server just in case.
<? php
$ x = array ("123" => "123");
$ w = $ x;
$ y = $ x;
$ z = & $ x;
var_dump (getaddress4 ($ w, $ x, $ y, $ z));
var_dump (getaddress ($ w));
var_dump (getaddress ($ x));
var_dump (getaddress ($ y));
var_dump (getaddress ($ z));
?>
Returns (at least for me, your memory addresses are likely to be different)
string '
0x9efeb0 - 0x9effe0 - 0x9ef8c0 - 0x9efeb0
0x9efee0 - 0x9f0010 - 0x9ed790 - 0x9efee0 '(length = 84)
string '0x9efee0' (length = 8)
string '0x9f0010' (length = 8)
string '0x9ed790' (length = 8)
string '0x9efee0' (length = 8)
Thanks to Artefacto pointing this out, but my source code passed arrays by value, so arrays, including the reference one, were recreated in this way and gave you bad memory values. Since then I have changed the code to force all parameters to be passed by reference. This will allow the transfer of links, arrays and objects that are not passed by the php engine. $ w / $ z is the same, but $ w / $ x / $ y is not. The old code actually showed a broken link and the fact that memory addresses would change or match when all variables were passed through several calls to the same function. This is because PHP repeats using the same memory when making multiple calls. Comparing the results of the original function would be futile. New code should fix this problem.
FYI - I am using php 5.3.2.