php 数组查找元素-彻底理解PHP中的引用概念

2023-09-02 0 4,011 百度已收录

虽然之前我们已经在几篇文章中谈到了引用的问题,但这次我们将全面梳理一下PHP中发生了什么php 数组查找元素,它与C中的手表指针有何不同,以及使用时应注意什么。

哪些是参考?

在 PHP 中引用意味着访问具有不同名称的同一变量的内容。它不是C手,不保存内存地址,因此难以执行手部操作。引用只是符号表的另一个名称。与Unix系统中的硬链接一样,Windows系统中的快捷方式。

里面是官方指南中的原文,怎么说呢,参考可能和我们印象中的C上面的手概念不一样。指针是实际视频内存的操作,参考是指向此视频内存的符号表的操作。或者从操作系统的快捷方法中,可以删除快捷方法,这是PHP的参考。除了删除快捷键外,C还删除了原始文件,这是C的手动操作。

// 引用不是指针
$a = 1;
$b = &$a;
echo $a, '===', $b, PHP_EOL;
unset($b);
echo $a, '===', $b, PHP_EOL;

里面的代码是PHP的,我们将$b变量指向$a作为$a的引用变量。 之后删除$b对$a没有影响。

#include 
#include 
int main()
{
    // C 中的指针和引用
    int a = 1;
    int* b = &a;
    printf("%in", a); // 1
    free(b); // free b
    printf("%in", a); //get error: *** error for object 0x7fff6350da08: pointer being freed was not allocated
    return 0;
}

C 中的参考引脚不起作用,我们删除 b 变量,然后复制 a 变量直接报错。

其实 PHP 的底层也是用 C 语言写的,但是我们都知道 C 语言中的表针是出了名的,没有一定成就就很容易犯错。因此,PHP开发人员没有公开C的原始针功能php 数组查找元素,而是采用了与Java类似的引用功能。这也是现代语言的一个特点,它不需要我们过多地关注底层功能,而将更多的时间放在业务实现上。

在链表和对象中使用引用

如果复制具有引用的字段,则不会取消引用其值。链表将值传递给函数也是如此。

$arr1 = ["a", "b"];
$t1 = &$arr1[1];
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);
// array(2) {
//     [0]=>
//     string(1) "a"
//     [1]=>
//     &string(1) "c"
// }
$arr1 = ["a", "b"];
$t1 = &$arr1[1];
unset($t1); // unset 掉引用
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);
// array(2) {
//     [0]=>
//     string(1) "a"
//     [1]=>
//     string(1) "b"
// }

这似乎很有趣,通过比较这两个反例,我们可以看到一个问题,其中 $t 变量指向对 $arr[1] 的引用。 $arr 2 直接 = 这个 $arr 1,不使用引用,之后 $arr 2 更改 $arr 2[1] 的内容,并且 $arr 1 的相应内容也会更改,如果未设置$t变量, $arr 1的相应内容不会改变。我在文档中找到了以下解释:

由于 PHP 内部工作的特殊性,如果引用链表的单个元素,然后通过形式参数或在函数调用中传递值来复制链表,则引用将作为链表的一部分进行复制。这意味着对任一字段中任何此类元素的修改将在另一个链表(和其他引用)中复制,尽管这些字段具有不同的范围(例如,一个是函数内的参数,另一个是全局的)!复制时未引用的元素,以及在复制链表后分配给其他元素的元素,将正常工作(即独立于其他链表)。

不仅链表,而且对象引用也有一些有趣的问题。

$o1 = new stdClass();
$o1->a = 'a';
var_dump($o1);
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(1) "a"
// }
$o2 = &$o1;
$o3 = $o1;
$o2->a = 'aa';
var_dump($o1);
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(2) "aa"
// }
var_dump($o3); // $o2修改了$a为'aa',$o3也变成了'aa'
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(2) "aa"
// }
$o1->a = 'aaa';
$o1 = null;
var_dump($o2); // $o2引用变成了null
// NULL
var_dump($o3); // $o3不仅引用还存在,并且$a变成了'aaa'
// object(stdClass)#1 (1) {
//   ["a"]=>
//   string(3) "aaa"
// }

示例中有三个对象,$o 1、$o 2 和 $o 3

,其中 $o 2 是对 $O 1 的引用,$o 3 是对直接参数 $O 1 的引用。对 $O 2 属性的操作将反映在 $O 1 和 $O 3 中。虽然我们之前有一篇关于这个问题的专文,但首先,对象的默认参数是引用,其次,这个例子证明了引用是符号表的绑定。删除快捷方法对原始对象和其他快捷方法没有影响。您可以参考:对象参数是否在 PHP 中引用?

引用的传递

关于 mode 参数上引用的传递,最重要的是记住两点:第一,方法内部改变变量,外部会改变,这是引用的特征;第二种是只能传递三种类型:变量、New 句子和从函数返回的引用。

error_reporting(E_ALL);
function foo(&$var)
{
    $var++;
    echo 'foo:', $var;
}
function bar() // Note the missing &
{
    $a = 5;
    return $a;
}
foo(bar()); // 自 PHP 5.0.5 起导致致命错误,自 PHP 5.1.1 起导致严格模式错误
            // 自 PHP 7.0 起导致 notice 信息,Notice: Only variables should be passed by reference
foo($a = 5); // 表达式,不是变量, Notice: Only variables should be passed by reference
// foo(5); // 导致致命错误 !5是个常量!
///////////////////////////////
// 正确的传递类型
$a = 5;
foo($a); // 变量
function &baz()
{
    $a = 5;
    return $a;
}
foo(baz()); // 从函数中返回的引用
function foo1(&$var)
{
    print_r($var);
}
foo1(new stdClass()); // new 表达式

引用的返回

引用的返回不是常用的功能。文档中的原始文本是:不要使用返回引用降低性能,引擎足够智能,可以自行优化它。只有在有合理的技术原因的情况下才返回报价!

$a = 1;
function &test(){
    global $a;
    return $a;
}
$b = &test($a);
$b = 2;
echo $a, PHP_EOL;

如果要返回引用变量,请确保对方法定义和方法调用都使用 & 符号。这是需要注意的一点。当原始变量值在其他地方更改或返回的变量值更改时,它将影响调用此值的所有位置。因此,引用的返回更加危险,因为您不知道此值可能在何时何地更改,并且很难解决错误。

取消引用取消

php 数组查找元素-彻底理解PHP中的引用概念

引用可能意味着简单地取消设置变量。并且必须记住,PHP 中的引用指向符号表,这些表不适用于原始实值,因此尽管 unset 删除了最原始的变量类型,但它不会影响引用参数的其他变量!!

$a = 1;
$b = &$a;
$c = &$b;
$b = 2;
echo '定义引用后:', $a, '===', $b, '===', $c, PHP_EOL;
unset($b);
$b = 3;
echo '取消$b的引用,不影响$a、$c:', $a, '===', $b, '===', $c, PHP_EOL;
$b = &$a;
unset($a);
echo '取消$a,不影响$b、$c:', $a, '===', $b, '===', $c, PHP_EOL;
// 定义引用后:2===2===2
// 取消$b的引用:2===3===2
// 取消$a,不影响$c:===3===2
$a = 1;
$b = & $a;
$c = & $b; // $a, $b, $c reference the same content '1'
$a = NULL; // All variables $a, $b or $c are unset
echo '所有引用成空:', $a, '===', $b, '===', $c, PHP_EOL;

总结

这一次,是对报价的比较彻底的解释。对 PHP 的引用只要记住它的定义就很容易理解,最直观的就是把它作为操作系统的捷径方法,并没有我们想象的那么难,相比 C 表针真的只是娃娃级别,多练习多准备自然就能很好地掌握使用!测试代码: %E5%BD%BB%E5%BA%95%E6%90%9E%E6%98%8E%E7%

99%BDPHP%E7%9A%84%E4%B8%AD%E5%BC%95%E7%94%A8%E7%94%E6%

A6%82%E5%BF%B5.php

参考文档:https://www.php.net/manual/zh/language.references.whatdo.phphttps://www.php.net/manual/zh/language.references.pass.phphttps://www.php.net/manual/zh/language.references.unset.php

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php 数组查找元素-彻底理解PHP中的引用概念 https://www.wkzy.net/game/189180.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务