PHP:Operator

PHP运算符

foo()和@foo()之间的区别:@foo()会忽略该表达式产生的任何错误

php的错误控制符
php支持一个错误运算符:@.当其放置在一个php表达式之前,该表达式可能产生的任何错误信息都被忽略掉.

运算符优先级

递增/递减 > ! > 算术运算符 > 大小比较 > (不)相等比较 > 引用 > 位运算符(^) > 位运算符(|) > 逻辑与 > 逻辑或 > 三目 > 赋值 > and > xor > or

使用括号可以增加代码可读性

==和===的区别:等值判断,7中False都相等.

递增/递减运算符

(1)递增/递减运算符不影响布尔值
(2)递减NULL值没有效果
(3)递增NULL值为1
(4)递增和递减在前就先运算符后返回(++$a),反之就先返回后运算($a++)

短路作用

$a = true || $b == 3;结果为true,||后不执行.
$b = false && $a == 1;结果为false,&&后不执行.

||、&&和and、or

$a = false || true;结果$a的值为true,||的优先级高于=
$a = false or true;结果$a的值为false,=的优先级高于or

例题

结果:a:1b:1
分析:$a = ((3 > 0) || $b = 3 > 0)运算顺序.由于3 > 0为true发生短路作用,使得$a=true,$b=0,true的递增仍为true,0的递增为1,所以结果得到a:1b:1.

结果:a:1b:1
分析:$a = ((3 < 0) || ($b = (3 > 0)))运算顺序.由于3 < 0为false,计算下一部分,下一部分中3 > 0优先级高于赋值,得到$b = true,得到false || true,得到$a = true.true的递增仍为true,所以结果为a:1b:1.

PHP:Constant And Data Type

常量及数据类型

php的字符串的定义方式及各自区别

字符串定义方式:单引号、双引号、heredoc和newdoc

单引号

<1> 单引号不能解析变量
<2> 单引号不能解析转义字符,只能解析单引号和反斜杆本身
<3> 变量和变量、变量和字符串、字符串和字符串之间可以用.连接
<4> 效率比双引号高

结果:
My name is {$name}, id is $id, age is $age.\n\t

双引号

<1> 双引号可以解析变量,变量可以使用特殊字符和{}包含
<2> 双引号可以解析所有转义字符
<3> 可以用.连接

结果:
My name is Jhon, id is 1, age is 23.
注意:双引号中包含单引号,单引号中的变量仍然会被解析为变量本身的值,并且单引号仍然以单引号输出.

heredoc和nowdoc

都是用来处理大文本.
注意:heredoc和nowdoc的结束符(EOF等)需要顶格书写.heredoc类似于双引号,newdoc类似于单引号.

heredoc

结果:
My Name is Jhon,
id is 1,
age is 23.

newdoc

结果:
My Name is $name,
id is $id,
age is {$age}. \n

数据类型

三大数据类型:标量、复合、特殊

标量类型

浮点类型:浮点类型不能运用于比较运算中(不能被用于==的比较)

结果:
bool(false)
原因:运算过程中,浮点数会从内存进入到浮点寄存器,浮点数的精度会拓展,计算结果返回内存,导致精度下降,从而使值发生截断.而浮点运算的结果由于下次还要再使用(没有写回内存,一种优化策略),导致数据并不是内存中和内存中的数据进行比较而是内存和浮点寄存器中的数进行比较,由于内存和浮点寄存器的精度不同,所以比较结果是不想等的.

布尔类型:FALSE的7种情况.(0, 0.0, ”, ‘0’, false, array(), NULL)
注意:’ ‘是为true,而”是为false,中间有空格仍然是true.

字符串类型

整型

复合类型

数组类型:超全局数组:$GLOBALS、$_GET、$_POST、$_REQUEST、$_SESSION、$_COOKIE、$_SERVER、$_FILES、$_ENV
注意:$GLOBALS包含所有;$_REQUEST包含$_GET、$_POST、$_COOKIE(尽量不要使用$_REQUEST,因为它可以接受三种请求);
$_SERVER[‘SERVER_ADDR’]:服务器的IP,
$_SERVER[‘SERVER_NAME’]:服务器名称,
$_SERVER[‘REQUEST_TIME’]:请求时间,
$_SERVER[‘QUERY_STRING’]:查询字符串,
$_SERVER[‘HTTP_REFERER’]:引导用户来到当前页的上一页地址,
$_SERVER[‘HTTP_USER_AGENT’]:请求头,
$_SERVER[‘REMOTE_ADDR’]:用户IP,
$_SERVER[‘REQUEST_URI’]:URI指定要访问的页面,
$_SERVER[‘PATH_INFO’]:跟在真实脚本名称并在查询语句之前的路径名称.如:http://www.fixbugs.cn/php/ind.php/hello/demo?name=Lan,那么PATH_INFO将是/hello/demo.

对象类型

特殊类型

NULL:直接赋值为NULL,为定义的变量,unset销毁的变量

常量

定义:通过const、define来定义.const更快,是语言结构,define是函数.define不能用于定义类的常量,const可以.常量不能被修改和删除.

预定义常量:
FILE:文件所在的路径以及文件名称,
DIR:文件所在的目录,
LINE:文件中的当前行号,
FUNCTION:函数名称,
CLASS:类名(由命名空间也会显示命名空间),
TRAIT:Trait的名称,
METHOD:类名称和函数名称(有命名空间也会显示命名空间),
NAMESPACE:命名空间的名称.

例题

1.用php写出显示客户端IP和服务端IP的代码.

2.FILE表示什么意思?

返回文件所在路径以及文件名.

PHP:Variable Reference

php引用变量

引用变量概念:意味着使用不同的变量名访问同一个变量内容。

引用变量定义方式:使用&符号。

引用原理

不使用引用:

结果:int(394448) int(394480) int(431400)

使用引用:

结果:int(394448) int(394504) int(394504)

原因:php的COW(Copy Or Write)机制

通过xdebug_debug_zval()查看

不使用引用代码:

结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
a: (refcount=2, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
从refcount看出,变量a改变后,refcount变成1,变量a开辟新的空间,即变量a和变量b指向不同的地址.

使用引用代码:

结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1)
从refcount看出,变量a改变后,refcount不变,变量a没有开辟新的空间,即变量a和变量b指向同一个地址.a和b的值仍然相同.

unset

unset:unset只是取消引用没有取消地址空间.

结果:
a: (refcount=0, is_ref=0)=1
a: (refcount=2, is_ref=1)=1
a: (refcount=1, is_ref=1)=1
1
a的值仍然存在.

对象本身就是引用传递

结果:
stu1: (refcount=1, is_ref=0)=class Student { public $id = (refcount=0, is_ref=0)=1 }
stu1: (refcount=2, is_ref=0)=class Student { public $id = (refcount=0, is_ref=0)=1 }
stu1: (refcount=2, is_ref=0)=class Student { public $id = (refcount=0, is_ref=0)=2 }

例题

运行结果:
array(3) {
[0] =>
string(1) “a”
[1] =>
string(1) “b”
[2] =>
string(1) “c”
}
array(3) {
[0] =>
string(1) “b”
[1] =>
string(1) “b”
[2] =>
string(1) “c”
}
array(3) {
[0] =>
string(1) “b”
[1] =>
string(1) “c”
[2] =>
string(1) “c”
}
解析:
第一次循环:
$key = 0; $value = ‘a’; $value引用$data[0] = ‘a’;
结果:[‘a’, ‘b’, ‘c’]
第二次循环:
$key = 1; $value = ‘b’; 由于上一次循环中, $value引用$data[0], 所以$data[0]的值发生改变, 变为’b’, 即$data[0]=’b’, 且$value引用$data[1] = ‘b’;
结果:[‘b’, ‘b’, ‘c’]
第三次循环:
$key = 2; $value = ‘c’; 由于上一次循环中, $value引用$data[1], 所以$data[1]的值发生改变, 变为’c’, 即$data[1]=’c’, 且$value引用$data[2] = ‘c’;
结果:[‘b’, ‘c’, ‘c’]