关于php的两个符号@和$
在写代码的时候,碰到了在函数和变量前家 @和$的的问题,于是就借这个机会,学习下php的传值和传引用这两种方式
首先
@ 运算符只对表达式有效。对新手来说一个简单的规则就是:如果能从某处得到值,就能在它前面加上 @ 运算符。例如,可以把它放在变量,函数和 include() 调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。目前的“@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或类型错误的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。
一句话,即 抑制报错的一种手段
对于$ 则是我们的重点问题
PHP代码:
基本形式:
function &find_var($param) //这里用&在对象前面,作用为声明
{
/* ...code... */
return $found_var;
}
$foo =& find_var($bar); //这里用&,作用为联系变量
$foo-<x = 2; //赋值给函数
例子:
function &test()
{
static $b=0;//申明一个静态变量
$b=$b+1;
echo $b;
return $b;
}
$a=test();//这条语句会输出$b的值为1,
$a=5;
$a=test();//这条语句会输出$b的值为2 ,因为没有引用返回,$a=5,不对对象起赋值作用
$a=&test();//这条语句会输出$b的值为3 ,成功引用返回,下面的代码起作用
$a=5;
$a=test();//这条语句会输出$b的值为6
下面解释下:
通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别。至于原因:这是PHP的规定,
php规定通过$a=&test(); 方式得到的才是函数的引用返回。
至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。)
这句狗屁话害我半天没看懂。
用上面的例子来解释就是
$a=test()方式调用函数,只是将函数的值赋给$a而已,而$a做任何改变都不会影响到函数中的$b,通过$a=&test()方式调用函数呢, 他的作用是将return $b中的$b变量的内存地址与$a变量的内存地址,向了同一个地方,产生了相当于这样的效果($a=&b;) 所以改变$a的值,也同时改变了$b的值,所以在执行了:$a=&test();
$a=5;
以后,$b的值变为了5 ......
php函数前面加&符号是什么意思?有的函数前面会加&,因为很少见到,所以不明白php函数前面加&符号是什么意思
那么,php函数前面加&符号有什么作用呢?
Java代码
function &test()
{
static $b=0;//申明一个静态变量
$b=$b+1;
echo $b;
return $b;
}
$a=&test();//这条语句会输出 $b的值 为1
$a=6;
test();//这条语句会输出$b的值 为7
php变量前面加&符号是什么意思
先看一个示例
Php代码
$foo = 321;
$bar = &$foo;
$bar = 123;
print $foo;那么输出的结果将会是什么呢
Php代码
123
为什么会这样呢?
改动新的变量将影响到原始变量,这种赋值操作更加快速。
注意:只有命名变量才可以传地址赋值,就是说,改变了$bar的值,也就改变了$foo的值了。
另一个例子:
$_GET[1] = 1;
function &a()
{
$a = $_GET[1];
return $a;
}
$x =& a();
$x = 'MoontoC';
echo $_GET[1]; // 此时这里会显示 MoontoC, 而不是最初赋值的1, 你明白其中的意义了吗, 使用函数传值时必须双方都使用引用符号才有意义,才能真正引用, 而任何一边少了引用符号, 都不会得到错误的内容, 但内容是传值, 而不是传引用了。没有程序基础的人最初学php的确很难理解传值和传引用的重要性, 觉得反正都能得到自己要的东西, 其实不是的, 很多时候虽然得到的东西一样, 但是代价却完全不一样, 一个长达200万字的值, 被当作值传送就是400万字同时放在内存中待用, 多耗费一倍内存的意思,而传引用就只是一个快捷方式传送过去而已。
解释2:
就是在变量或者函数、对象等前面加上&符号
在PHP 中引用的意思是:不同的名字访问同一个变量内容.
与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址
变量的引用
PHP 的引用允许你用两个变量来指向同一个内容
[php]
< br style='font-size:14px;font-style:normal;font-weight:normal;color:rgb(0, 0, 0);' />$a="ABC";
$b =&$a;
echo $a;//这里输出:ABC
echo $b;//这里输出:ABC
$b="EFG";
echo $a;//这里$a的值变为EFG 所以输出EFG
echo $b;//这里输出EFG
?<
[/php]
函数的传址调用
传址调用我就不多说了 下面直接给出代码
[php]
function test(&$a)
{
$a=$a+100;
}
$b=1;
echo $b;//输出1
test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值 就可以改变$b的值了
echo "
";
echo $b;//输出101
[/php]
要注意的是,在这里test(1);的话就会出错,原因自己去想
函数的引用返回
先看代码
[php]
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
[/php]
下面解释下:
通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别 至于原因: 这是PHP的规定
PHP规定通过$a=&test(); 方式得到的才是函数的引用返回
至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话 害我半天没看懂
用上面的例子来解释就是
$a=test()方式调用函数,只是将函数的值赋给$a而已, 而$a做任何改变 都不会影响到函数中的$b
而通过$a=&test()方式调用函数呢, 他的作用是 将return $b中的 $b变量的内存地址与$a变量的内存地址 指向了同一个地方
即产生了相当于这样的效果($a=&b;) 所以改变$a的值 也同时改变了$b的值 所以在执行了
$a=&test();
$a=5;
以后,$b的值变为了5
这里是为了让大家理解函数的引用返回才使用静态变量的,其实函数的引用返回多用在对象中
对象的引用
[php]
< br style='font-size:14px;font-style:normal;font-weight:normal;color:rgb(0, 0, 0);' />class a{
var $abc="ABC";
}
$b=new a;
$c=$b;
echo $b-<abc;//这里输出ABC
echo $c-<abc;//这里输出ABC
$b-<abc="DEF";
echo $c-<abc;//这里输出DEF
?<
[/php]
以上代码是在PHP5中的运行效果
在PHP5中 对象的复制 是通过引用来实现的。上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&$b;
PHP5中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本 . 为了这样的目的,PHP定义了一个特殊的方法,称为__clone.
引用的作用
如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 "&" 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 "&" 方式, 毕竟节省内存空间使用。
取消引用
当你 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如:
< phpbr style='font-size:14px;font-style:normal;font-weight:normal;color:rgb(0, 0, 0);' />$a = 1;
$b =& $a;
unset ($a);
?<
不会 unset $b,只是 $a。
global 引用
当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:
< phpbr style='font-size:14px;font-style:normal;font-weight:normal;color:rgb(0, 0, 0);' />$var =& $GLOBALS["var"];
?<
这意味着,例如,unset $var 不会 unset 全局变量。
$this
在一个对象的方法中,$this 永远是调用它的对象的引用。
//下面再来个小插曲
php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。
通俗的讲
1:如果有下面的代码
[php]
$a="ABC";
$b=$a;
[/php]
其实此时 $a与$b都是指向同一内存地址 而并不是$a与$b占用不同的内存
2:如果在上面的代码基础上再加上如下代码
[php]
$a="EFG";
[/php]
由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断 自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储
关于php的两个符号@和$的更多相关文章
- python从字符串内取两个符号之间的内容
#取字符串中两个符号之间的东东 def txt_wrap_by(self,start_str, end, html): start = html.find(start_str) if start &g ...
- php的两个符号@和&---php总会要知道的系列
在写代码的时候,碰到了在函数和变量前家 @和$的的问题,于是就借这个机会,学习下php的传值和传引用这两种方式 首先 @ 运算符只对表达式有效.对新手来说一个简单的规则就是:如果能从某处得到值,就能在 ...
- MathType中常见的两种符号的运用
想要让公式编辑得快速又高效,MathType数学公式编辑器这个神助攻是少不了的.MathType是一款专用的数学公式编辑器,用它来编辑公式非常方便实用,并且排版也非常简单.下面介绍两种常见符号的应用. ...
- [No0000A0]批处理命令学习之:常用的特殊符号
学习要点:1.>.>>重定向符2.| 命令管道符3.&.&&.|| 组合命令4.^ 转义字符5.% 变量引导符6."" 界定符—————— ...
- 两个int的和判断溢出
long a,b; cin>>a>>b; long i; i = a+b; if((i^a)<0 && (i^b)<0) cout<<& ...
- Windbg符号与源码 《第二篇》
符号文件是一种辅助数据,它包含了对应用程序代码的一些标注信息,这些信息在调试过程中非常有用.如果没有辅助数据,那么能获得的信息就只有应用程序的二进制文件.二进制文件很难调试,因为无法看到代码中的函数名 ...
- go语言指针符号的*和&
先看一段代码 先放一段代码,人工运行一下,看看自己能做对几题? package main import "fmt" func main() { var a int = 1 var ...
- (转)Linux上的Shebang符号(#!)
https://linux.cn/article-3664-1.html 本文了将给你简单介绍一下Shebang(”#!”)这个符号. 首先,这个符号(#!)的名称,叫做”Shebang”或者”Sha ...
- linux shell中的特殊符号
该内容,均来自此网址(http://www.92csz.com/study/linux/12.htm).在下只是把那些命令的截图给去了. 你在学习linux的过程中,也许你已经接触过某个特殊符号,例如 ...
随机推荐
- “Clean Code” 读书笔记序
最近开始研读 Robert C.Martin 的 “Clean Code”,为了巩固学习,会把每一章的笔记整理到博客中.而这篇博文作为一个索引和总结,会陆续加入各章的笔记链接,以及全部读完后的心得体会 ...
- Docker系列(八)Kubernetes介绍
Kubernetes组件功能图 各组件说明: 节点 节点在Kubernetes由虚拟机或者实体机表示,常称为Minion,即从属主机.当一个节点加入到Kubernetes系统中时,它将会创建一个数 ...
- Android下NFC的简单使用
现在很多手机已经配备了NFC(Near Field Communication 近场通信)的功能,我就为此专门研究过,可以到本文末尾下载源代码. Android官方资料:http://develope ...
- Android实例-解决启动黑屏问题(XE8+小米2)
结果: 1.在启动时马上出现图片界面,但在出现程序界面前会有黑屏,大约有0.2秒左右. 实现: 1.建立2个文件:loading.png和styles.xml: ①其中loading.png是启动时替 ...
- keil中的存储模式
存储模式 存储模式决定了默认的存储器类型此存储器类型将应用于函数参数局部变量和定义时未包含存储器类型的变量你可以在命令行用SMALL COMPACT和LARGE参数定义存储模式,定义变量时使用存储器类 ...
- 网络操作与AFNetworking
众所周知,苹果搞的一套框架NSContention发送请求与接收请求的方式十分繁琐.操作起来很不方便.不仅要做区分各种请求设置各种不同的参数,而且还要经常在多线程里操作,同时还要对请求与返回的数据做各 ...
- Keil : Contents missmatch at:08000E84H Verify Failed!
Keil 下载时出以下错误: Device: STM32F103VB VTarget = 3.300V State of Pins: TCK: 0, TDI: 0, TDO: 1, TMS: 0, T ...
- tomcat+JNDI+spring 的配置问题
在做spring有关的项目时,往往需要配置数据源,当然配置的方式有很多种,可以单独写在一个properties文件中,这样修改数据源配置的话比较容易,也比较简单,下面介绍另外一种数据源的配置 利用jn ...
- Behavioral模式State模式
1.意向 同意一个目标,然后改变其内部状态,改变它的行为. 对象似乎改变它的类别. 2.别名 状态对象(Objects for States) 3.动机 考虑一个表示网络连接的类TCPConnecti ...
- iOS开发——swift精讲&MVC应用实战
MVC应用实战 iOS开发中设计模式是很重要的,其中,使用最多的就是MVC模式,今天就简单介绍一下在Swift中这么使用MVC模式来实现我们想要的功能: 模型-视图-控制器(Model-View-Co ...