Rah*_*hly 15
实际上,这可以做到.通过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它,配置它,然后制作它.在php.ini文件中添加"extension =/path/to/so/file/modules/test.so".最后,重启Web服务器,以防万一.
<?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指出这一点,但是我的原始代码是按值传递数组,因此重新创建了包含引用的数组,并为您提供了错误的内存值.我已经改变了代码以强制所有参数通过引用传递.这将允许引用,数组和对象在php引擎中不受干扰地传递.$ w/$ z是相同的,但是$ w/$ x/$ y不是.旧代码实际上显示了引用破坏以及当所有变量传递给多个调用同一函数时内存地址将改变或匹配的事实.这是因为PHP在进行多次调用时会重用相同的内存.比较原始函数的结果将是无用的.新代码应该解决这个问题.
仅供参考 - 我使用的是php 5.3.2.
你的问题实际上有点误导."指向相同的内存位置"和"是相同的数组"(这对我来说意味着是一个引用,至少在PHP中)是不一样的东西.
内存位置指的是指针.指针不适用于PHP.引用不是指针.
无论如何,如果你想检查是否$b实际上是一个参考$a,这是你可以得到一个真正的答案:
function is_ref_to(&$a, &$b) {
if (is_object($a) && is_object($b)) {
return ($a === $b);
}
$temp_a = $a;
$temp_b = $b;
$key = uniqid('is_ref_to', true);
$b = $key;
if ($a === $key) $return = true;
else $return = false;
$a = $temp_a;
$b = $temp_b;
return $return;
}
$a = array('foo');
$b = array('foo');
$c = &$a;
$d = $a;
var_dump(is_ref_to($a, $b)); // false
var_dump(is_ref_to($b, $c)); // false
var_dump(is_ref_to($a, $c)); // true
var_dump(is_ref_to($a, $d)); // false
var_dump($a); // is still array('foo')
Run Code Online (Sandbox Code Playgroud)
PHP中的引用是一种通过不同名称访问相同变量内容的方法.它们不像C指针; 例如,您不能使用它们执行指针运算,它们不是实际的内存地址,依此类推.
结论:不,你不能
来自:http://www.php.net/manual/en/language.references.whatare.php
| 归档时间: |
|
| 查看次数: |
1939 次 |
| 最近记录: |