你真的了解PHP中的引用符号(&)吗


Posted in PHP onMay 12, 2021

引言

最近接手了五六年前的老项目,用的是CI2.0框架,在看框架源码的时候有个地方让我楞了一下,于是有了这篇文章。

字符&的最早历史可以追溯到公元1世纪,最早是拉丁语et (意为and)的连写。

&是指逻辑上表示两者属于缺一不可的关系,还表示意思是一个人和另外一个人之意,与and同义。

&在PHP项目中是经常使用的一个操作符, 例如按位与丶逻辑操作丶引用变量丶引用传递丶引用返回。

按位与

$a & $b 将把 $a 和 $b 中都为1的位设为1.

奇偶数判断

整数与1进行按位与运算,运算结果为1表示为奇数, 运算结果为0表示为偶数。例如:

 

十进制 二进制
5 101
1 001

6和1进行按位与&, 得到结果为0。

 

十进制 二进制
6 110
1 001

但是项目中我们都不会这么写, 都是使用n % 2 == 0, 因为奇偶性判断使用%的效率比较高,也比较容易理解。

用户权限判断

假设有个系统中有用户权限分配模块, 其权限设置如下:

 

权限名称 权限值
查看 1
新增 2
修改 4
删除 8

那么存储该用户的权限不需要存储逗号分割的字符串1,2,4,8, 只需要存储一个整形:15即可。

如果用户1拥有新增丶查看丶修改权限, 那么需要存储的权限值为: 1+2+4=7。

如果用户2拥有所有权限, 那么需要存储的权限值为:1+2+4+8=15。

检查用户1是否有修改权限:7 & 4结果为4, 表示拥有修改权限。

检查用户2是否有删除权限:15 & 8结果为8, 表示拥有删除权限。

条件操作符

$a && $b只有$a和$b均为真,结果才为真。

引用变量

PHP的引用允许你用两个变量来指向同一个内容。无论对哪个变量名的值进行了修改,其他变量名访问的内容也会随之改变。

与C语言中的指针是有差别的。C语言中的指针里面存储的是变量的内容,在内存中存放的地址。

<?php
$a = 10;
$b = &$a; 
$a = 11;
var_dump($a, $b); // 输出11, 11
$b = 12;
var_dump($a, $b); // 输出12, 12

foreach循环时加&符号会有什么问题? 例如以下代码能正常输出期望值吗?

<?php

$values = ['Python', 'Php', 'Go'];

foreach ($values as &$value)
{
    $value = strtoupper($value);
}

foreach ($values as $value){
    echo $value . PHP_EOL;
}

预期结果是: ['PYTHON', 'PHP', 'GO'] 实际结果是['PYTHON', 'PHP', 'PHP']。

这是因为第一次foreach中使用了引用, 使$value成为了引用变量, 并且$arr[2]和$value指向了同一个地址空间(共享变量值), 第二次foreach时, 不断的将$values中的值赋给$value, 导致$arr[2]的值也被修改了。

引用传递

可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值。

/**
 * 对传入的值进行平方
 * Author: ClassmateLin
 * Email: classmatelin.site@gmail.com
 * Site: https://www.classmatelin.top
 * @param $n
 */
function f(&$n)
{
    $n *= $n;
}

$n = 2;
f($n);
var_dump($n); // 输出4

按值传递是需要对变量进行拷贝, 引用传递是同一内存空间。

如果是大型字符串或对象,那么使用引用传递比按值传递可以节省一些内存, 但是使用引用传递代码可读性稍微低点。

引用返回

函数的引用返回,在方法前加&符号定义。同时需要接收返回值也需要&, 否则将不起作用, 例如:

<?php

class Foo {

    public $value = 10;

    /**
     * 返回value, 引用返回, 对返回的值修改会影响到该值。
     * Author: ClassmateLin
     * Wechat: ClassmateLin_
     * Email: classmatelin.site@gmail.com
     * Site: https://www.classmatelin.top
     * @return int
     */
    public function &getValue()
    {
        return $this->value;
    }

}

$foo = new Foo();

$val1 = $foo->getValue();
$val1 = 11; // $val1没有用&接收,不是引用, 修改不会影响实例$foo的值.
var_dump($val1, $foo->getValue()); // 输出11, 10


$val2 = &$foo->getValue(); // $val2是引用
$val2 = 13;
var_dump($val2, $foo->getValue()); // 输出13, 13

你真的了解PHP中的引用符号(&)吗

总结

到此这篇关于PHP中引用符号(&)的文章就介绍到这了,更多相关PHP引用符号&内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
php中对xml读取的相关函数的介绍一
Jun 05 PHP
PHP CURL模拟登录新浪微博抓取页面内容 基于EaglePHP框架开发
Jan 16 PHP
基于PHP 面向对象之成员方法详解
May 04 PHP
基于php设计模式中单例模式的应用分析
May 15 PHP
php获取从百度搜索进入网站的关键词的详细代码
Jan 08 PHP
php实现判断访问来路是否为搜索引擎机器人的方法
Apr 15 PHP
php metaphone()函数的定义和用法
May 15 PHP
Ajax提交表单时验证码自动验证 php后端验证码检测
Jul 20 PHP
PHP请求Socket接口测试实例
Aug 12 PHP
Yii2实现增删改查后留在当前页的方法详解
Jan 13 PHP
Laravel给生产环境添加监听事件(SQL日志监听)
Jun 19 PHP
php多进程应用场景实例详解
Jul 22 PHP
php中配置文件保存修改操作 如config.php文件的读取修改等操作
May 12 #PHP
php7中停止php-fpm服务的方法详解
May 09 #PHP
解析laravel使用workerman用户交互、服务器交互
Apr 28 #PHP
PHP实现创建以太坊钱包转账等功能
Apr 21 #PHP
如何使用php生成zip压缩包
Apr 21 #PHP
PHP使用非对称加密算法RSA
laravel ajax curd 搜索登录判断功能的实现
You might like
相对路径转化成绝对路径
2007/04/10 PHP
CodeIgniter中实现泛域名解析
2014/07/19 PHP
php5.3以后的版本连接sqlserver2000的方法
2014/07/28 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
js 页面执行时间计算代码
2009/03/04 Javascript
javascript 时间比较实现代码
2009/10/28 Javascript
js点击更换背景颜色或图片的实例代码
2013/06/25 Javascript
原生js和jQuery写的网页选项卡特效对比
2015/04/27 Javascript
javascript瀑布流式图片懒加载实例
2020/06/28 Javascript
使用vue.js开发时一些注意事项
2016/04/27 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
JS实现自动阅读单词(有道单词本添加功能)
2016/11/14 Javascript
jQuery拖拽通过八个点改变div大小
2020/11/29 Javascript
Vue 过渡(动画)transition组件案例详解
2017/01/22 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
nodejs结合socket.io实现websocket通信功能的方法
2018/01/12 NodeJs
微信小程序实现长按删除图片的示例
2018/05/18 Javascript
vue中使用axios post上传头像/图片并实时显示到页面的方法
2018/09/27 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
Python实现公历(阳历)转农历(阴历)的方法示例
2017/08/22 Python
python实现kmp算法的实例代码
2019/04/03 Python
python将print输出的信息保留到日志文件中
2019/09/27 Python
python实现大学人员管理系统
2019/10/25 Python
pytorch实现seq2seq时对loss进行mask的方式
2020/02/18 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
2020/03/06 Python
django rest framework使用django-filter用法
2020/07/15 Python
实例讲解CSS3中的box-flex弹性盒属性布局
2016/06/09 HTML / CSS
移动端解决悬浮层(悬浮header、footer)会遮挡住内容的3种方法
2015/03/27 HTML / CSS
悬挂训练绳:TRX
2017/12/14 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
物理教师自荐信范文
2013/12/28 职场文书
大学生学习自我评价
2014/01/13 职场文书
绩效工资实施方案
2014/03/15 职场文书
党员对照检查剖析材料
2014/10/13 职场文书
2016猴年开门红标语口号
2015/12/26 职场文书