浅谈PHP变量作用域以及地址引用问题


Posted in PHP onDecember 27, 2013

作用域的概念:

在PHP脚本的任何位置都可以声明变量,但是,声明变量的位置会大大影响访问变量的范围。这个可以访问的范围称为作用域。

主要的常用的包括:局部变量、全局变量、静态变量。

1、局部变量:就是在函数内声明的变量,他保存在内存的栈内,所以访问速度很快。仅在函数内有效。

2、全局变量:与局部变量相反,全局变量可以在程序的任何地方访问。只要在变量前面加关键字GLOBAL,就可以将其识别为全局变量。在整个php文件内有效。

3、静态变量:用static修饰只存在于函数作用域的变量,函数执行结束后其值并不消失。注:初始化后不能再次进行初始化,不能用表达式来赋值。

function test() 
{ 
static $b=0;//申明静态变量,放在函数外部声明的话,在函数内部是用不到的
$b=$b+1; 
echo $b; 
} 
test();//这条语句会输出 $b的值 为1 
test();//这条语句会输出 $b的值 为2

注:static $b=0 这一赋值操作只会在变量第一次被初始化的时候执行。

附A:类中静态成员和静态方法,差不多只是调用的时候统一使用类名或者self或者parent加::xxx,他们的作用域和这个一样,但是他的声明是在方法外部的

附B:js里面的作用域使:用var aa=‘xxx';在函数外面声明的就是全局变量(不管是否带有修饰符var)。在函数内部使用 var声明的是局部变量,不使用var修饰的是全局变量。

附C:关于引用

PHP引用:就是在变量、函数或者对象前加&.php中的引用就是想用不同的名字访问同一个变量的内容。

1、变量的引用:

$a="ABC"; 
$b =&$a; 
echo $a;//这里输出:ABC 
echo $b;//这里输出:ABC 
$b="EFG"; 
echo $a;//这里$a的值变为EFG 所以输出EFG 
echo $b;//这里输出EFG

2、函数的传址调用

function test(&$a) 
{ 
$a=$a+100; 
} 
$b=1; 
echo $b;//输出1 
test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值 就可以改变$b的值了 
echo "<br>"; 
echo $b;//输出101

3、函数的引用返回

function &test() 
{ 
static $b=0;//申明一个静态变量 
$b=$b+1; 
echo $b; 
return $b; 
} 
$a=test();//这条语句会输出 $b的值 为1 
$a=5; 
$a=test();//这条语句会输出 $b的值 为2 
$a=&test();//这条语句会输出 $b的值 为3 
$a=5; 
$a=test();//这条语句会输出 $b的值 为6

解析:使用$a=test()得到的其实不是函数的引用返回。只是将函数的返回值复制给$a,而不会影响到$b。这样调用和普通的调用没区别。

Php规定:$a=&test()方式得到才是函数的引用返回。他将$b变量的内存地址和$a变量的内存地址指向了同一个地方。即相当于$a=&$b;

4、取消引用

$a = 1; 
$b =& $a; 
unset ($a); 
echo $b;

解析:unset一个引用,只是取消了变量名和变量的内容之间的绑定,并不意味着内容被销毁,其值还是真实存在的。

5、global引用:使用global $var  声明一个变量时,其实就是建立了一个到全局变量的引用。Global $val <=> $var=&$GLOBALS[‘var'] ;

6、对象的引用:在对象的方法中,$this调用的对象都是调用它的引用

注:php中对于地址的指向不是由用户自己来实现的,而是通过zend核心实现的,php的引用采用的是“写拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或对象是不会被拷贝的。

$a = 1; 
$b =$a;

$a和$b都是指向同一个内存地址,并不是$a和$b占用不同的内存。

若是现在执行一句$a=”dsd”:$a和$b所指向的内存数据需要重新写一次,此时zend核心会自动判断。自动为$b产生一个$a的数据拷贝,重新申请一块内存进行存储。

PHP 相关文章推荐
利用PHP创建动态图像
Oct 09 PHP
PHP 和 MySQL 开发的 8 个技巧
Jan 02 PHP
PHP var_dump遍历对象属性的函数与应用代码
Jun 04 PHP
整理的一些实用WordPress后台MySQL操作命令
Jan 07 PHP
php广告加载类用法实例
Sep 23 PHP
PHP获取数组最后一个值的2种方法
Jan 21 PHP
php字符串分割函数用法实例
Mar 17 PHP
Symfony2 session用法实例分析
Feb 04 PHP
PHP带节点操作的无限分类实现方法详解
Nov 09 PHP
php实现文件预览功能
May 23 PHP
php验证码生成器
May 24 PHP
PHP封装的数据库模型Model类完整示例【基于PDO】
Mar 14 PHP
一个好用的PHP验证码类实例分享
Dec 27 #PHP
PHP连接SQLServer2005方法及代码
Dec 26 #PHP
php截取中文字符串不乱码的方法
Dec 25 #PHP
php输入流php://input使用示例(php发送图片流到服务器)
Dec 25 #PHP
php二维数组排序方法(array_multisort usort)
Dec 25 #PHP
php缩小png图片不损失透明色的解决方法
Dec 25 #PHP
php查看请求头信息获取远程图片大小的方法分享
Dec 25 #PHP
You might like
分享一个Laravel好用的Cache宏
2015/03/02 PHP
php微信支付接口开发程序
2016/08/02 PHP
PHP编程获取音频文件时长的方法【基于getid3类】
2017/04/20 PHP
PHP Trait代码复用类与多继承实现方法详解
2019/06/17 PHP
javascript整除实现代码
2010/11/23 Javascript
返回页面顶部top按钮通过锚点实现(自写)
2013/08/30 Javascript
用unescape反编码得出汉字示例
2014/04/24 Javascript
node.js集成百度UE编辑器
2015/02/05 Javascript
学习javascript面向对象 掌握创建对象的9种方式
2016/01/04 Javascript
Angularjs 滚动加载更多数据
2016/03/17 Javascript
JS/jQ实现免费获取手机验证码倒计时效果
2016/06/13 Javascript
javascript DOM的详解及实例代码
2017/03/06 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
2017/03/09 Javascript
easyUI下拉列表点击事件使用方法
2017/05/18 Javascript
jquery与js实现全选功能的区别
2017/06/11 jQuery
vue.js实现点击后动态添加class及删除同级class的实现代码
2018/04/04 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
vue.js+element-ui动态配置菜单的实例
2018/09/07 Javascript
分享一款超好用的JavaScript 打包压缩工具
2020/04/26 Javascript
vue-i18n实现中英文切换的方法
2020/07/06 Javascript
javascript实现拼图游戏
2021/01/29 Javascript
[01:11:32]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python数据操作方法封装类实例
2017/06/23 Python
Python 查找list中的某个元素的所有的下标方法
2018/06/27 Python
python 文件查找及内容匹配方法
2018/10/25 Python
使用Django简单编写一个XSS平台的方法步骤
2019/03/25 Python
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
高分子材料与工程专业个人求职信
2013/12/15 职场文书
自我推荐信范文
2014/05/09 职场文书
考博专家推荐信
2014/05/10 职场文书
语文课外活动总结
2014/08/27 职场文书
目标责任书格式范文
2015/05/11 职场文书
严以律己专题学习研讨会发言材料
2015/11/09 职场文书
中学音乐课教学反思
2016/02/18 职场文书
利用Nginx代理如何解决前端跨域问题详析
2021/04/02 Servers
css布局巧妙技巧之css三角示例的运用
2022/03/16 HTML / CSS