PHP数组引用不一致
我有一个HTML表单,它发布了名为thing$0和thing$1的字段,我想将这些字段映射到名为$gvar[0]->thing和$gvar[1]->thing的全局PHP变量。我解析字段名以获得'thing'和下标值0和1。我想要一个PHP函数,它将返回对$gvar的引用。[对象名称比$gvar更复杂——我正在极大地简化整个问题。] 以下是函数的两个版本:PHP数组引用不一致,php,Php,我有一个HTML表单,它发布了名为thing$0和thing$1的字段,我想将这些字段映射到名为$gvar[0]->thing和$gvar[1]->thing的全局PHP变量。我解析字段名以获得'thing'和下标值0和1。我想要一个PHP函数,它将返回对$gvar的引用。[对象名称比$gvar更复杂——我正在极大地简化整个问题。] 以下是函数的两个版本: function testfunc1($junk) { global $gvar1; $obj = &$gv
function testfunc1($junk)
{
global $gvar1;
$obj = &$gvar1;
$obj[0] = new stdClass;
$obj[0]->foo = $junk;
return $obj;
}
function testfunc2($junk)
{
global $gvar2;
$obj = &$gvar2;
$obj[0] = new stdClass;
$obj[0]->foo = $junk;
$obj[1] = new stdClass;
return $obj;
}
function test($parms)
{ // session::test
global $gvar1, $gvar2;
$obj1 = $this->testfunc1(42);
$obj1[1] = new stdClass;
$obj1[1]->foo = 43;
// At this point: $gvar1 is [1] with [0]->foo === 42
// $obj1 is [2] with [0]->foo === 42, [1]->foo === 43
$obj2 = $this->testfunc2(42);
$obj2[1]->foo = 43;
// At this point: $gvar2 AND $obj2 are [2] with [0]->foo === 42, [1]->foo === 43
return 666;
} // session::test
两个版本都在目标数组中创建[0]元素。第一个版本让调用者创建[1]元素。第二个版本创建两个数组元素。从C++背景来看,我认为两个版本都应该产生相同的结果,但它们没有。PHP似乎不允许您从函数返回对数组的引用——您只能返回数组的副本,该数组的元素与函数中看到的元素相同
是否有一种方法可以避免函数创建超过[0]的数组元素,以便调用函数可以使用发布的字段名称(例如$1、$2等)来创建尽可能多的$gvar[1]、$gvar[2]、。。。元素是否需要?我认为您的问题来自传递到函数或从函数返回时对类型的不同处理。如果您返回null、bool、int或float,它们将被有效地复制。如果它们是像STDC类之类的对象,那么传递给函数的行为就像C++引用,所以函数内部和外部都引用相同的对象。意外的部分(至少对我来说,还有C++背景)是数组不被当作对象的事实。因此,当您返回一个数组时,它会被复制,如果它包含一个对象,那么副本中有一个引用同一对象的元素 注:我写“有效复制”是有原因的。我不确定PHP的内部结构,但对于像bool这样的简单类型,可能无法修改它们。然后,您唯一能做的就是将不同的实例分配给变量。此外,PHP可能使用“写时复制”来避免复制开销。两者都是不影响语义的实现细节
现在,关于您的目标,您的函数同时写入全局变量并返回这些全局变量似乎有些奇怪。我会选择这两种语言中的任何一种,最好是不使用globals的。实际上,您可以获取HTTP请求参数并将其转换为不同的表示形式。为此,我将使用一个函数,该函数只执行此操作并返回结果。因为它是一个纯函数,所以单元测试也可以简单得多。您如何设置变量
$gvar
?为什么要用thing$0
作为表单名,而不是像thing[0]
这样的数组表达式呢?奇怪的是,我已经把这个问题简化为它的绝对本质。事实上,我的对象名可能是一长串点分隔的组件,其中每个组件命名一个主题。示例目标可能是$\u会话['USERINFO']['alldata']->ExpenseInfo->OtherExpenses[0]->what,它被持久保存在数据库中。此目标对应于表单上的一个值,该表单提供一个字段SaveAs=“ExpenseInfo.OtherExpenses[]”和另一个名为what$0的字段。正如您所看到的,OtherExpenses的下标值完全来自另一个字段。