广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP 引用的概念
  • 187
分享到

PHP 引用的概念

2024-04-02 19:04:59 187人浏览 泡泡鱼
摘要

目录什么是引用?引用在数组和对象中的使用引用的传递引用的返回引用的取消总结什么是引用? 在 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变量指向b变量指向a,作为a的引用变量。然后删除a的引用变量。然后删除b,对$a没有任何影响。


#include <stdio.h>
#include <stdlib.h>

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

而C中的引用指针就不行了,我们把b变量删掉后,再打印a变量就直接报错了。

虽然说PHP的底层也是C写得,但我们都知道C中的指针是出了名的变态,没有一定的功底非常容易出错。所以PHP的开发者没有暴露C的原始指针能力,而是采用了和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变量指向t变量指向arr[1]的引用。arr2直接=这个arr2直接=这个arr1,没有使用引用,然后arr2修改了arr2修改了arr2[1]的内容,arr1相应的内容也发生了改变,如果unset掉arr1相应的内容也发生了改变,如果unset掉t变量,则$arr1相应的内容就不会发生改变。对此,我在文档中找到了下面的解释:

由于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"
// }

上面例子中有三个对象,o1、o1、o2、o3,其中,o3,其中,o2是对o1的引用,o1的引用,o3是直接赋值为o1。对o1。对o2属性的操作不仅会反映在o1中,也会反映到o1中,也会反映到o3中。其实我们之前专门有一篇文章就讲的这个问题,首先对象默认赋值就是引用,其次这个例子很好地证明了引用就是一个符号表的绑定。删除了快捷方式对原始对象和其他快捷方式没有任何影响。

引用的传递

关于引用在方法参数上的传递,最重要的是记住两点:一是方法内部修改了变量外部也会变,这是引用的特性嘛;二是只能传递变量、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;

当你想要返回一个引用变量的时候,一定要给方法定义和方法调用的时候都使用&符号。这个是需要注意的点。当其他地方修改原本的变量值或者返回的变量值经过修改后,都会影响到所有调用这个值的地方。所以说,引用的返回是比较危险的,因为你不清楚什么时候在什么地方这个值可能发生了修改,对于bug的排查会非常困难。

引用的取消

取消引用其实就是直接unset掉变量就可以了。但是一定要记住,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的指针相比真的只是娃娃级别,多多练习多多复习自然就能很好地掌握使用啦!

测试代码: GitHub.com/zhangyue050…

以上就是PHP的中引用的概念的详细内容,更多关于PHP 引用的资料请关注编程网其它相关文章!

--结束END--

本文标题: PHP 引用的概念

本文链接: https://www.lsjlt.com/news/124987.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP 引用的概念
    目录什么是引用?引用在数组和对象中的使用引用的传递引用的返回引用的取消总结什么是引用? 在 PHP 中引用意味着用不同的名字访问同一个变量内容。它不是C的指针,保存的并不是内存地址...
    99+
    2022-11-12
  • MYSQL索引的基本概念
    本篇内容介绍了“MYSQL索引的基本概念”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! &nbs...
    99+
    2022-10-18
  • C++变量引用的概念介绍
    本篇介绍的变量引用与之前介绍的指针不是同一概念,它们有本质的区分: 1)不存在空引用。引用必须连接到一块合法的内存。 2)一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可...
    99+
    2022-11-12
  • ps索引的概念是什么
    本文小编为大家详细介绍“ps索引的概念是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“ps索引的概念是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。ps索引是什么意思:答:索引的意思是图片是什么色彩模式...
    99+
    2023-07-02
  • C++引用的基本概念是什么
    本篇文章给大家分享的是有关C++引用的基本概念是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C++编程语言中有很多应用方法和C语言有相同之处。那么作为C语言的升级版本,它...
    99+
    2023-06-17
  • C++变量引用的概念是什么
    这篇文章主要介绍“C++变量引用的概念是什么”,在日常操作中,相信很多人在C++变量引用的概念是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++变量引用的概念是什么”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-20
  • MongoDB索引概念及使用详解
    索引,使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓名(name)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮...
    99+
    2022-10-18
  • MySQL BlackHole引擎的概念和使用场景
    本篇内容介绍了“MySQL BlackHole引擎的概念和使用场景”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有...
    99+
    2022-10-18
  • DM7数组索引的概念是什么
    DM7数组索引的概念是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。数组索引指在一个只包含单个数组成员的对象列上创建的索引。数组索引定义语...
    99+
    2022-10-19
  • mysql全文索引的概念是什么
    这篇“mysql全文索引的概念是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mysq...
    99+
    2023-05-25
    mysql
  • Java中弱引用的概念和作用是什么
    本篇内容介绍了“Java中弱引用的概念和作用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!概览本文会通过对弱引用的定义讲起,然后通过案...
    99+
    2023-06-16
  • php web的概念是什么
    这篇文章主要介绍“php web的概念是什么”,在日常操作中,相信很多人在php web的概念是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php web的概念是什么”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-07-04
  • mysql索引基数概念与用法示例
    本文实例讲述了mysql索引基数概念与用法。分享给大家供大家参考,具体如下: Cardinality(索引基数)是mysql索引很重要的一个概念 索引基数是数据列所包含的不同值的数量。例如,某个数据列包含值...
    99+
    2022-10-18
  • MySQL约束与索引概念详解
    目录一、关系型数据库设计规则二、数据完整性和约束与索引的概念三、约束的应用一、关系型数据库设计规则 遵循ER模型和三范式 E entity 代表实体的意思 对应到数据库当中的一张表R relationship 代表关系的...
    99+
    2023-04-07
    MySQL约束与索引 MySQL约束 MySQL索引
  • Oracle索引的概念及分类是什么
    这期内容当中小编将会给大家带来有关Oracle索引的概念及分类是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一.索引介绍 1.1 索引的创建语法...
    99+
    2022-10-19
  • C++详细分析讲解引用的概念与使用
    目录1.引用的概念2.引用的格式3.引用的特性4.取别名原则5.引用的使用场景做参数做返回值int&Count()的讲解传值传引用效率比较6.引用和指针的不同点1.引用的概念...
    99+
    2022-11-13
  • php对象的概念是什么
    PHP对象是PHP中的一种数据类型,它可以被看作是具有属性和方法的实体。对象是基于类的实例化,类是一个定义对象属性和方法的模板。对象...
    99+
    2023-10-18
    php
  • php里exit的概念是什么
    这篇文章主要介绍“php里exit的概念是什么”,在日常操作中,相信很多人在php里exit的概念是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php里exit的概念是什么”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-02
  • php中strsplt的概念是什么
    本文小编为大家详细介绍“php中strsplt的概念是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“php中strsplt的概念是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在php中,strsplt...
    99+
    2023-06-30
  • php和html的概念是什么
    本篇内容主要讲解“php和html的概念是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php和html的概念是什么”吧! PH...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作