• php数组时按值传递还是按地址传递


    php数组时按值传递还是按地址传递

    一、总结

    1、数组都是按值:php普通变量和数组的赋值(=)是按值传递,对象的赋值(=)是按址传递

    2、对象和按值和按址对象的clone(用clone关键字)是按值传递 

    二、PHP 数组的拷贝是按值传递 or 按引用传递

    在记忆中 PHP 简单变量的拷贝是按值传递,数组和对象的拷贝是按引用传递,即通过引用来实现。

    简单变量和对象好理解:

    <?php
    
    // 简单变量的拷贝
    $a = 'human';
    $b = $a;
    $b = 'cat';
    var_dump($a); // string 'human' (length=5)
    
    // 对象的拷贝
    class A{}
    $a = new A();
    $b = $a;
    $b->name = 'jack';
    var_dump($a); // object(A)[1] public 'name' => string 'jack' (length=4)

    对象 $a 和 对象 $b 的内存地址指向了同一个地方,即针对 $a 和 $b 所做的操作都针对同一个实例。

    PHP 中可以通过 clone 关键字按值拷贝对象:clone关键字让对象按值传递,因为clone就是拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
     
    class A{
        public $name 'Vardy';
    }<br>
    $a new A();
    $b clone $a;
    $b->name = 'dee';
    var_dump($a); // object(A)[1] public 'name' => string 'Vardy' (length=5)
    var_dump($b); // object(A)[2] public 'name' => string 'dee' (length=3)

      

    数组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
     
    // 数组的拷贝
    $a = ['human''orc'];
    $b $a;
    $b[0] = 'elve';
    var_dump($a);
    // array (size=2)
    //   0 => string 'human' (length=5)
    //   1 => string 'orc' (length=3)

    这样看,数组的拷贝是按值传递的.

    另一个例子 数组的迭代器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
     
    $a = ['human''orc''elven''undead'];
    next($a);
     
    $b $a// 此时指针位置也随着数组的复制而复制
     
    var_dump(current($a)); // string 'orc' (length=3)
    var_dump(current($b)); // string 'orc' (length=3)

    当数组拷贝时,数组的指针位置也随着复制。

    (next:http://php.net/manual/zh/function.next.php

    current:http://php.net/manual/zh/function.current.php

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
     
    $a = ['human''orc''elven''undead'];
    end($a);
    next($a); // 数组指针非法,返回 FALSE
     
    $b $a;
     
    var_dump(current($a)); // string 'human' (length=5)
    var_dump(current($b)); // boolean false

    当数组在拷贝前,指针的位置是非法时,拷贝后分别打印两个数组指针所指向的当前单元时,出现了不一样的情况。

    原因是数组变量发生拷贝后,两个变量中先发生写操作的,其指针被初始化,即指向第一个元素,而 current 方法也会产生写操作,因此 $a 的数组指针当前指向的是 'human',而 $b  current 方法则返回 FALSE。

    以下代码同理, $b 首先发生了写操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
     
    $a = ['human''orc''elven''undead'];
    end($a);
    next($a);
     
    $b $a;
     
    $b[] = 'dwarf';
     
    var_dump(current($a)); // boolean false
    var_dump(current($b)); // string 'human' (length=5)

      

    解析:数组的拷贝是值传递。PHP 在管理内存方面有一个机制叫写时复制(COW,Copy On Write),保证了变量间复制值不浪费内存:当一个变量的值复制到另一个变量时,PHP 没有为复制值使用更多的内存,相反,它会更新符号表来说明两个变量拥有相同的内存块,所以当执行下面的代码时并没有创建一个新的数组:

    1
    2
    3
    4
    <?php
     
    $a = ['human''orc''elven''undead'];
    $b $a;

    当修改了 $a 或 $b 任意一个副本时,PHP 将分配所需的内存来进行复制:

    1
    $b[] = 'dwarf';

      

     

    参考:

    php基础语法之数组和数组指针

    php中引用&的真正理解-变量引用、函数引用、对象引用

    Programming PHP 3rd Edition

    参考:

    PHP 数组的拷贝是按值传递 or 按引用传递 - 黄棣-dee - 博客园
    https://www.cnblogs.com/dee0912/p/5605323.html

  • 相关阅读:
    git rror: RPC失败
    linux加载模块报错:could not insert module xxx.ko: Unknown symbol in module
    Ubuntu 20.04 添加当前用户 Root 权限
    C程序编译过程
    静态代码块和非静态代码块
    java反射
    ==和equal的区别
    solr中配置域
    Solr的简介以及安装
    Spring Data Redis 小demo
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/8995785.html
Copyright © 2020-2023  润新知