在写代码的时候,碰到了在函数和变量前家 @和$的的问题,于是就借这个机会,学习下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的两个符号@和$的更多相关文章

  1. python从字符串内取两个符号之间的内容

    #取字符串中两个符号之间的东东 def txt_wrap_by(self,start_str, end, html): start = html.find(start_str) if start &g ...

  2. php的两个符号@和&---php总会要知道的系列

    在写代码的时候,碰到了在函数和变量前家 @和$的的问题,于是就借这个机会,学习下php的传值和传引用这两种方式 首先 @ 运算符只对表达式有效.对新手来说一个简单的规则就是:如果能从某处得到值,就能在 ...

  3. MathType中常见的两种符号的运用

    想要让公式编辑得快速又高效,MathType数学公式编辑器这个神助攻是少不了的.MathType是一款专用的数学公式编辑器,用它来编辑公式非常方便实用,并且排版也非常简单.下面介绍两种常见符号的应用. ...

  4. [No0000A0]批处理命令学习之:常用的特殊符号

    学习要点:1.>.>>重定向符2.| 命令管道符3.&.&&.|| 组合命令4.^ 转义字符5.% 变量引导符6."" 界定符—————— ...

  5. 两个int的和判断溢出

    long a,b; cin>>a>>b; long i; i = a+b; if((i^a)<0 && (i^b)<0) cout<<& ...

  6. Windbg符号与源码 《第二篇》

    符号文件是一种辅助数据,它包含了对应用程序代码的一些标注信息,这些信息在调试过程中非常有用.如果没有辅助数据,那么能获得的信息就只有应用程序的二进制文件.二进制文件很难调试,因为无法看到代码中的函数名 ...

  7. go语言指针符号的*和&

    先看一段代码 先放一段代码,人工运行一下,看看自己能做对几题? package main import "fmt" func main() { var a int = 1 var ...

  8. (转)Linux上的Shebang符号(#!)

    https://linux.cn/article-3664-1.html 本文了将给你简单介绍一下Shebang(”#!”)这个符号. 首先,这个符号(#!)的名称,叫做”Shebang”或者”Sha ...

  9. linux shell中的特殊符号

    该内容,均来自此网址(http://www.92csz.com/study/linux/12.htm).在下只是把那些命令的截图给去了. 你在学习linux的过程中,也许你已经接触过某个特殊符号,例如 ...

随机推荐

  1. Code First 更新数据库结构(简单实现方法:会删除原来的数据)

    之前在 http://www.cnblogs.com/mmcmmc/p/3833265.html 写到关于“Code First 更新数据库结构”的东西. 可是由于某种原因,新手们会出现各种问题,好了 ...

  2. 1.2CPU和GPU的设计区别

    CPU和GPU之所以大不相同,是由于其设计目标的不同,它们分别针对了两种不同的应用场景.CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理.这些都使得C ...

  3. 让浏览器进行跨域访问, 开发阶段需要跨域访问的测试方案 chrome的快捷方式里面 加 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-web-security

    Chrome浏览器 的快捷方式里加一个 命令可以使浏览器进行跨域访问 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe ...

  4. Code Understanding Step by Step - We Need a Task

      Code understanding is a task we are always doing, though we are not even aware that we're doing it ...

  5. D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建

    说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...

  6. jquery完成带复选框的表格行高亮显示

    jquery完成带复选框的表格行高亮显示 通过jquery技术来操作表格是件简单的事,通过jquery的语法,可以很轻松的完成表格的隔行换色,悬浮高亮,在实际的应用中可能会出现表格中带复选框的,删除时 ...

  7. Notepad++的一些常用的快捷键

    ctrl+/  一个一个单词的往后跳Ctrl+H 替换Ctrl+F  查找Ctrl+D 复制当前行到下一行Ctrl+L 删除当前行Ctrl+Shift+F 在文件中找F5 打开run对话框F11 全屏 ...

  8. iframe中的各种跳转方法

    iframe中的各种跳转方法(转)   一.背景A,B,C,D都是jsp,D是C的iframe,C是B的iframe,B是A的iframe,在D中跳转页面的写法区别如下. 二.JS跳转window.l ...

  9. hdu3589 Jacobi symbol(二次剩余 数论题)

    本题的注意点:n=p1*p2*p3......Pm 解法:直接利用公式a^((p-1)/2)=(a/p)mod p 即可求解. #include<stdio.h> #include< ...

  10. [Heroku] How to pull, push changes

    1. First you need to login heroku: heroku login 2. Then you need to download the code: heroku git:cl ...