На самом деле это можно сделать.Через расширение php.
Файл: 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
Файл: 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
Файл: 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);
}
Тогда все, что вам нужно сделать, это phpize, настроить и сделать это.Добавьте «extension = / path / to / so / file / modules / test.so» в файл php.ini.И, наконец, перезапустите веб-сервер, на всякий случай.
<?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));
?>
Возвращает (по крайней мере для меня ваши адреса памяти, вероятно, будут другими)
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)
Спасибо Artefacto за указаниеэто, но мой исходный код передавал массивы по значению, поэтому воссоздавал массивы, включая ссылочный, и давал вам неверные значения памяти.С тех пор я изменил код, чтобы все параметры передавались по ссылке.Это позволит ссылкам, массивам и объектам передаваться в unmoled движком php.$ w / $ z - это то же самое, но $ w / $ x / $ y - нет.Старый код фактически показывал разрыв ссылок и тот факт, что адреса памяти изменились или совпали, когда все переменные были переданы в сравнении с несколькими вызовами одной и той же функции.Это потому, что PHP будет использовать одну и ту же память при выполнении нескольких вызовов.Сравнивать результаты оригинальной функции было бы бесполезно.Новый код должен решить эту проблему.
К вашему сведению - я использую php 5.3.2.