- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对以下示例中的行为感到困惑。我在一个项目中偶然发现了这个问题,我花了几个小时将问题缩小到一个简单的例子。所以这是我的简单测试类:
<?php
class Foo {
public $sess = [['name' => 'John']];
public function info() {
$this->runTest();
echo $this->sess[0]['name'];
}
private function runTest() {
$localSess = &$this->sess[0];
$this->sessTest();
}
private function sessTest() {
$sessCopy = $this->sess;
$this->sess[0]['name'] = 'Bob';
$this->sess = $sessCopy;
}
}
$myFoo = new Foo;
$myFoo->info();
意外的结果输出是:
Bob
如果 $localSess
只是一个简单的赋值而不是引用,输出是(如预期的):John
我不明白这是怎么回事。由于类属性 $sess
是一个数组而不是对象,因此对 $sessCopy
的赋值应该是一个简单的副本。但是,如果您在修改 $this->sess
后立即打印 $sessCopy
的内容,它将包含“name”的更改值。所以看起来好像 $sessCopy
毕竟是一个引用?但前提是调用方法中的 $localSess
是引用。为什么这很重要?顺便说一句,如果 $localSess
是对类属性的整个数组的引用,而不仅仅是它的第一个索引,那么一切都会按预期工作。
有人可以解释一下吗?如果一个函数中仅存在一个变量引用就可以影响另一个函数中局部变量(不是引用!)的内容,那么这似乎是危险和可怕的。
最佳答案
所以我决定创建一个更简单的示例来说明相同的问题:
$a = [['name' => 'John']];
$b = $a; // makes a copy of `$a`
$b[0]['name'] = "Bob";
echo $a[0]['name]; // returns "John" as expected
但是如果你这样做了:
$a = [['name' => 'John']];
/* var_dump($a) returns:
array(1) {
[0]=>
array(1) {
["name"]=>
string(4) "John"
}
}
*/
$local = &$a[0]; // seems to modify $a[0], so its type &array
/* var_dump($a) returns:
array(1) {
[0]=>
&array(1) {
["name"]=>
string(4) "John"
}
}
*/
$b = $a; // makes a copy of `$a`
$b[0]['name'] = "Bob";
echo $a[0]['name]; // returns "Bob"
我承认这种行为很奇怪,但在多个 PHP 文档注释中都有记录:
事实证明,这实际上是 2000 年首次报告的 PHP 错误:
本应更新文档,但我找不到:
Due to peculiarities of the internal workings of PHP, if a reference is made to a single element of an array and then thearray is copied, whether by assignment or when passed by value in afunction call, the reference is copied as part of the array. Thismeans that changes to any such elements in either array will beduplicated in the other array (and in the other references), evenif the arrays have different scopes (e.g. one is an argumentinside a function and the other is global)! Elements that did not havereferences at the time of the copy, as well as references assigned tothose other elements after the copy of the array, will behavenormally (i.e. independent of the other array).
但是,它已被标记为 Wont fixed
,可能是出于性能原因。值得注意的评论:
We have discussed this issue and it will put a considerable slowdown on php's performance, to fix this properly.
Therefore this behaviour will be documented.
即使它从未被记录。
我已决定就此问题提出另一个错误报告,以查看在这个问题上的立场是否发生了变化。
我现在重新报告了这个问题: https://bugs.php.net/bug.php?id=80955
一种解决方法是:
$b = unserialize(serialize($a));
另一个是:
function array_clone($array) {
return array_map(function($element) {
if ((is_array($element))) {
return array_clone($element);
} else if (is_object($element)) {
return clone $element;
} else {
return $element;
}
}, $array);
}
$b = array_clone($a);
关于PHP 类 : referenced variable in one method affects non-referenced variable in other method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67106717/
我不确定这个语法是否是 Informix 特有的,但是我在创建触发器时遇到了麻烦,直到我找到了一些包含这些行之一或两者的语法: CREATE TRIGGER accuplacer_trig
我是 Android Studio 和 gradle 的新手。我有一个 Android 项目,部分在 Eclipse 中工作。原始代码在Android中使用derby数据库。旧代码通过 JDBC 直接
我对以下示例中的行为感到困惑。我在一个项目中偶然发现了这个问题,我花了几个小时将问题缩小到一个简单的例子。所以这是我的简单测试类: 'John']]; public function inf
我在 pgAdmin 4 中创建了一些表,但由于某种原因我一直收到标题错误,你能找出原因吗?我没有看到任何问题,并且我已经查看了与我的代码示例相似的其他代码示例,这些示例编译得很好。它在 IDEone
我正在创建一个表,但出现此错误: number of referencing and referenced columns for foreign key disagree. 不知道怎么解决。我认为声
假设我有一个名为“C”的库 (.NETStandard 2.0),它定义了一个名为“CRecord”(记录)的类型。 假设我从名为“B”的 .NET 4.7.2 库中使用这个库。有一个使用“CReco
我已经尝试解决这个错误几分钟了,但我不知道表定义中缺少什么。 表格的代码如下: 表Autocare: CREATE TABLE [dbo].[Autocare] ( [IDAutocar]
DROP DATABASE IF EXISTS ProviderPatients; CREATE DATABASE ProviderPatients; USE ProviderPatients; CR
假设我有这个表stuff_property: | stuff_id (fk) | property_id | | ------------- | ----------- | 现在我想要进行查询,该查询
我是 MySQL 的新手。我完全有能力进行查询和创建表,但之前从未尝试过触发器。 CREATE TRIGGER TrigMora AFTER INSERT ON cliente REFEREN
我可以创建一个具有四个这样的属性的对象 $pocketKnife = New-Object PSObject -property @{ Color = 'Black' Weight =
我有一个名为 App 的对象,它包含主干应用程序的所有相关部分。 问题:当我从应用程序中的其他对象调用应用程序中的对象时,它们是未定义的。 我认为发生这种情况是因为在定义其自身的 App 对象之前,它
我有一个ArrayClass并且mergeSortArray扩展了它。并且 mergeSortArray 包含一个 mergeSort() 方法。但是,由于我使用 super 从父类(super cl
public class foo{ private String label; foo(String whereto){ label = whereto; } publi
我正在尝试以编程方式将库添加到引用的库中。这是我的代码: String filename = "myfile.jar"; InputStream is; try { is = new Buffe
我使用@Reference来获取我需要的所有信息: 吗菲亚: Query query = INSTANCE.createQuery(User.class); return query.asLi
我在 eclipse 中有一个 Java 项目,我想在其中添加 3 个 jar 文件到构建路径: 但是,当我选择它们并将它们添加到构建路径(右键单击/构建路径/添加到构建路径)时,它们将与成为类的“j
希望获得 Java 遵循的一些幕后内存引用和规则。 这是一段代码。基本上,此类用于实例化一些其他对象 (MyOtherObject),然后将此对象的 doClose() 方法的引用发送到 Vector
我打开了this关于转发引用的帖子,这是一个(希望如此)MCVE 代码: #include #include using namespace std; struct MultiMemoizator
MySQL 表: categoryID categoryName categoryParent 每个类别都有一个父类别,尽管它可以是 NULL,我将其视为根类别。 我想从表中获取所有类别,将其存储
我是一名优秀的程序员,十分优秀!