【问题标题】:PHP Array element assignment for readonly - is value copied?只读的PHP数组元素分配 - 是否复制了值?
【发布时间】:2017-03-09 09:56:23
【问题描述】:

例子

$value1 = $array[ 0 ][ $key ];
$value2 = (string) $array[ 0 ][ $key ];

变量是只读的,我不修改它们的值。 PHP 是否复制这些元素的值或引用?

编辑:
复制值需要时间和内存。我想知道是否进行了复制?例如 - 在函数中 PHP 不会复制值,除非你修改它

EDIT2:
https://stackoverflow.com/a/3845530/1398264
我不确定这是否适用于作业。

【问题讨论】:

  • @AbraCadaver 复制值需要时间和内存。我想知道是否进行了复制?例如 - 在函数中 PHP 不会复制值,除非你修改它
  • PHP 使用写时复制。除非需要,否则它会尽量避免物理复制任何内容。
  • @ShiraNai7 选角怎么样?这算不算写?请添加您的答案,以便我批准。

标签: php


【解决方案1】:

是的,PHP 将值从 $array[ 0 ][ $key ] 复制到变量 $value1(您的代码:$value1 = $array[ 0 ][ $key ];)。
在 PHP 中作为参考使用了保留符号 &,您可以像在其他编程语言中一样使用参考。要使用参考,您需要修改代码: $value1 = & $array[ 0 ][ $key ];使用 unset($value1) 删除从变量到数组的引用。

【讨论】:

  • stackoverflow.com/questions/11074970/… 如本主题所述 - PHP 使用 COW 机制。但是我不知道铸造是否会改变
  • 我认为您无法参考自动转换值。如果您使用严格类型,则可以在任何表达式中使用函数或强制转换值。函数 string_cast
  • 抱歉之前回答错了,我不能编辑它。使用类似的东西: $variable1=&$var2;然后将其与以下类型的转换一起使用: (string)$variable1;
  • 我想避免参考性能方面的原因。引用总是比复制值慢。
  • 我不能准确地说出你的代码行为,因为我没有看到你的代码。当我有大量对象并且需要对它们做一些事情时,我经常使用引用,经常用函数改变对象内部的值。如果没有参考,您将有 2 次复制操作。一是把值复制到函数作用域,二是把改变的值写入变量。参考可以直接修改,大数据速度更快。
【解决方案2】:

PHP 使用写时复制。除非需要,否则它会尝试避免物理复制数据。

来自PHP docs - Introduction to Variables

PHP 是一种动态的、松散类型的语言,它使用写时复制和引用计数。

您可以轻松测试:

/* memory usage helpers */

$mem_initial = memory_get_usage();
$mem_last = $mem_initial;

$mem_debug = function () use ($mem_initial, &$mem_last) {
    $mem_current = memory_get_usage();
    $mem_change = $mem_current - $mem_last;
    echo 'Memory usage change: ', $mem_change >= 0 ? '+' : '-', $mem_change, " bytes\n";
    $mem_last = $mem_current;
};

/* test */

echo "Allocating 10kB string\n";
$string = str_repeat('x', 10000);
$mem_debug();
echo "\n";

echo "Copying string by direct assignment\n";
$string2 = $string;
$mem_debug();
echo "\n";

echo "Modyfing copied string\n";
$string2 .= 'x';
$mem_debug();
echo "\n";

echo "Copying string with a (string) cast\n";
$string3 = (string) $string;
$mem_debug();

PHP 5.x 的输出:

Allocating 10kB string
Memory usage change: +10816 bytes

Copying string by direct assignment
Memory usage change: +56 bytes

Modyfing copied string
Memory usage change: +10048 bytes

Copying string with a (string) cast
Memory usage change: +10104 bytes
  • 直接赋值不会按预期将字符串复制到内存中
  • 修改复制的字符串确实会复制内存中的字符串 - 写时复制发生了
  • 使用额外的(string) 强制转换分配字符串似乎会复制内存中的字符串,即使它没有改变

PHP 7.0 的输出:

Allocating 10kB string
Memory usage change: +13040 bytes

Copying string by direct assignment
Memory usage change: +0 bytes

Modyfing copied string
Memory usage change: +12288 bytes

Copying string with a (string) cast
Memory usage change: +0 bytes
  • 写时复制行为与 5.x 版本相同,但无意义的 (string) 强制转换不会导致字符串在内存中重复

【讨论】:

    猜你喜欢
    • 2021-07-22
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多