1.PHP引用变量
概念:用不同的名字访问同一个变量内容,使用&
符号定义。
PHP引用变量的工作原理
写入时复制:COW(Copy On Write)
当将一个变量赋值给另一个变量时$a = $b;
,俩个变量指向的是同一个内存空间。只有当对$a
或$b
进行再次写入时,才会开辟新的内存空间。
但是当使用引用变量时$a = &$b
,俩个变量永远指向同一个内存空间,不再存在COW的操作。无论修改$a
或是$b
,俩个变量的值都会一同修改。
unset 只会取消引用,不会销毁内存空间
当使用unset
销毁一个指定变量时,只会取消该变量的引用,而该变量之前所引用的内存空间不会被销毁。
对象本身就是引用传递
实例:
<?php
//写出如下程序的输出结果:
$data = ['a', 'b', 'c'];
foreach ($data as $key => $val) {
$val = &$data[$key];
}
//程序运行时,每次循环结束后变量$data的值是什么?请解释
//程序执行完成后变量$data的值是什么?请解释
?>
解析:
//第一次循环
//$key = 0;$val = a; $val = &$data[0] = a;
//
//第二次循环
//$key = 1;$val = &$data[0] = b; $val = &$data[1] = b;
//
//第三次循环
//$key = 2;$val = &$data[1] = c; $val = &$data[2] = c;
//结果输出
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"
}
array(3) {
[0]=>
string(1) "b"
[1]=>
string(1) "c"
[2]=>
&string(1) "c"
}
2.常量及数据类型
PHP支持9种原始数据类型
四种标量类型:布尔型boolean
,整型integer
,浮点型float
,字符串string
三种复合类型:数组array
,对象object
,可调用callable
俩种特殊类型:资源resource
,无类型NULL
PHP中字符串的三种定义方式及各自区别
单引号
单引号不能解析变量
单引号不能解析转义字符,只能解析单引号和反斜线本身
变量和变量、变量和字符串、字符串和字符串之间可以用.
连接
单引号效率更高,高于双引号
双引号
双引号可以解析变量,变量可以使用特殊字符和{}
包含
双引号可以解析所有的转义字符
也可以使用.
来连接
$sql = "SELECT * FROM user WHERE name = '$name' ";
//单引号效率更高
$sql = 'SELECT * FROM user WHERE name = \''.$name.'\'';
Heredoc结构和Nowdoc结构
Heredoc结构与双引号功能一致,Nowdoc结构与单引号功能一致。
俩者用于处理大文本。
!!!结束时所引用的标识符必须在该行的第一列,而且,标识符的命名也要像其它标签一样遵守 PHP 的规则:只能包含字母、数字和下划线,并且必须以字母和下划线作为开头。
示例:
<?php
//Heredoc结构
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
//Nowdoc结构
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
浮点类型
0.1 + 0.7 !== 0.8
不能运用在比较运算中,因为浮点类型在转换为二进制进行运算的时候会有一定的损耗。
布尔类型
FALSE的七种情况:0
,0.0
,''
,'0'
,false
,array()
,NULL
数组类型
超全局数组:
$GLOABALS
(包含下列所有的超全局变量):超全局变量是在全部作用域中始终可用的内置变量
$_GET
:HTTP GET 变量
$_POST
:HTTP POST 变量
$_REQUEST
(包含$_GET,$_POST,$_COOKIE
,谨慎使用):HTTP Request 变量
$_SESSION
:Session 变量
$_COOKIE
:HTTP Cookies
*$_SERVER
:服务器和执行环境信息
*$_SERVER['SERVER_ADDR']
:当前运行脚本所在的服务器的 IP 地址。
$_SERVER['SERVER_NAME']
:当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。
$_SERVER['REQUEST_TIME']
:请求开始时的时间戳。
$_SERVER['QUERY_STRING']
:query string
(查询字符串),如果有的话,通过它进行页面访问。
$_SERVER['HTTP_REFERER']
:引导用户代理到当前页的前一页的地址(如果存在)。由 user agent
设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER
的功能。简言之,该值并不可信。
$_SERVER['HTTP_USER_AGENT']
:当前请求头中 User-Agent: 项的内容,如果存在的话。该字符串表明了访问该页面的用户代理的信息。
*$_SERVER['REMOTE_ADDR']
:浏览当前页面的用户的 IP 地址,即客户端 IP 地址。
$_SERVER['REQUEST_URI']
:URI 用来指定要访问的页面。
$_SERVER['PATH_INFO']
:包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息,如果存在的话。
$_FILES
:HTTP 文件上传变量
$_ENV
:环境变量
NULL
三种情况:
直接赋值为NULL、未定义的变量、unset销毁的变量
常量
定义方式:const
,define
区别:
const
更快,是语言结构,define
是函数
define
不能用于类常量的定义,const
可以
常量一经定义,不能被修改,不能被删除
八个魔术常量
__FILE__
:文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
__LINE__
:文件中的当前行号。
__DIR__
:文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。
__FUNCTION__
:函数名称。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)
__CLASS__
:类的名称。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。
__TRAIT__
:Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。
__METHOD__
:类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
__NAMESPACE__
:当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。
3.运算符
PHP运算符中的错误控制符@
PHP 支持一个错误控制运算符:@
。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
运算符优先级
重点运算符优先级
递增/递减 > ! > 算术运算符 > 大小比较 > (不)相等比较 > 引用 > 位运算符(^
) > 位运算符(|
) > 逻辑与(&&
) > 逻辑或(||
) > 三目运算符(?? > 赋值(= += -= *= **= /= .= %= &= |= ^= <<= >>=
) >
and > xor > or
与=的区别
==
比较值是否相等,===
比较值和类型
等值判断
FALSE的七种情况等值
递增/递减运算符
1.递增/递减运算符不影响布尔值
2.递减NULL
值没有效果
3.递增NULL
值为1
4.递增和递减在前就先运算后返回,反之就先返回后运算
逻辑运算符
短路作用
||
和&&
与or
和and
的优先级不同
实例:
<?php
//请写出下列程序打印输出的结果
$a = 0;
$b = 0;
if ($a = 3 > 0 || $b = 3 > 0) {
$a++;
$b++;
echo $a. "<br/>";
echo $b;
}
解析:
//考虑优先级与短路作用
//(>) > (||) > (=)
//if($a = ( ( 3 > 0 ) || $b = 3 > 0))
//3 > 0 为true,||被短路,($b = 3 > 0)不执行
//所以$a = true;$b = 0;
//进入if体,得到$a = 1;$b = 1;
//输出
1
1
4.流程控制
PHP遍历数组的三种方式及各自区别
使用for
循环
使用foreach
循环
使用while、list()、each()
组合循环
区别:
for
循环只能遍历索引数组
foreach
可以遍历索引和关联数组
联合使用list()
,each()
,while
循环同样可以遍历索引和关联数组
list()
,each()
,while
组合不会reset()
操作
foreach()
遍历会对数组进行reset()
操作
PHP分支结构
if...elseif
在elseif
语句中只能有一个表达式为true
,即在elseif
语句中只能有一个语句块被执行,多个elseif
从句是排斥关系。
使用elseif
语句有一个基本原则,总把优先范围小的条件放在前面处理(即可能性大的条件放前面处理)。
switch...case...
和if
不同的是,switch
后面的控制表达式的数据类型只能是整型、浮点类型或者是字符串。
continue
语句作用于switch
的作用类似于break
跳出switch
外的循环,可以使用continue2
switch...case...
会生成跳转表,直接跳转到对应的case
效率:如果条件比一个简单的比较要复杂的多或者在一个很多次的循环中,那么用switch
语句可能会快一些
实例:
PHP中如何优化多个if..else
语句的情况?
1.将可能性大的条件放在前面判断
2.若是判断一个较为复杂的结构,且判断的是整型、浮点类型或者字符串,就可以使用switch...case...
5.自定义函数及内部函数
变量的作用域和静态变量
变量的作用域
变量的作用域也称变量的范围,变量的范围即它定义的上下文背景(也就是它的生效范围)。大部分的 PHP 变量只有一个单独的范围。这个单独的范围跨度同样包含了 include
和 require
引入的文件。
全局变量不能在局部使用。全局变量在函数(局部)使用时必须声明为global
(global $a, $b;
);全局范围访问变量的第二个办法极速使用$GLOBALS
数组($GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
)
静态变量
静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。
在静态声明中用表达式的结果对其赋值会导致解析错误。
static
关键字
1.仅初始化一次
2.初始化时需要赋值
3.每次执行函数该值会被保留
4.static
修饰的变量是局部的,仅在函数内部有效
5.可以记录函数的调用次数,从而可以在某些条件下终止递归
实例:
<?php
//写出如下程序的输出结果
$count = 5;
function get_count()
{
static $count; //静态变量定义未赋值->NULL
return $count++; //NULL++->1
}
echo $count; //全局变量->5
++$count; //全局变量->6
echo get_count(); //先输出后加加->NULL
echo get_count(); //第二次调用返回上一次$count++的结果->1
?>
//输出
51
函数的参数以及参数的引用传递
默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数。
如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &
。
函数的返回值及引用返回
值通过使用可选的返回语句return
返回。可以返回包括数组和对象的任意类型。
返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。
如果省略了 return,则返回值为 NULL。函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。
从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用运算符 &
。
实例1:
<?php
function &myFunc()
{
static $b = 10;
return $b;
}
$a = myFunc(); //->10
$a = &myFunc(); //对函数的返回进行了引用
$a = 100; //改变了引用空间的值
echo myFunc(); //->100
实例2:
<?php
function foo(&$my_var)
{
global $var1; //引入全局变量->5
$var1 += 2; //->7
$var2 = 4; //局部变量->4
$my_var += 3; //引用->8
return $var2; //->4
}
$my_var = 5;
echo foo($my_var).'<br/>'; //->4
echo $my_var.'<br/>'; //引用赋值后改变->8
echo $var1.'<br/>'; //->7
echo $var2.'<br/>'; //->4
$bar = 'foo';
$my_var = 10;
echo $bar($my_var).'<br/>'; //foo($my_var)->4
//输出
4
8
7
10
4
外部文件的导入
include/require
语句包含并运行指定文件
如果给出路径名按照路径来找,否则从include_path
中找
如果include_path
中也没有,则从调用脚本文件所在的目录和当前工作目录下寻找
当一个文件被包含时,其中所包含的代码继承了include
所在行的变量范围
include和require的区别
加载过程中未找到文件则include
结构会发出一条警告;
而require
不同,后者会发出一个致命错误。
require
在出错时产生E_COMPILE_ERROR
级别的错误
也就是require
出错将导致脚本终止,而include
只产生警告E_WARNING
,脚本会继续执行。
require(include)/require_once(include_once)
的区别是PHP会检查文件是否被包含锅,如果是则不会再次包含。
系统内置函数
时间日期函数
date()
:格式化一个本地时间/日期
strtotime()
:将任何字符串的日期时间描述解析为 Unix 时间戳
mktime()
:取得一个日期的 Unix 时间戳
time()
:返回当前的 Unix 时间戳
microtime()
:返回当前 Unix 时间戳和微秒数
date_default_timezone_set()
:设定用于一个脚本中所有日期时间函数的默认时区
IP处理函数
ip2long ( string $ip_address )
:将 IPV4 的字符串互联网协议转换成长整型数字。返回IP地址转换后的数字 或 FALSE 如果 ip_address 是无效的。
long2ip ( int $proper_address )
:将长整型转化为字符串形式带点的互联网标准格式地址(IPV4)
打印处理函数
print ( string $arg ) : int
(语言结构,非函数): 输出字符串
和 echo
最主要的区别: print
仅支持一个参数,并总是返回 1。
printf ( string $format [, mixed $args [, mixed $... ]] ) : int
:输出格式化字符串,返回输出字符串的长度。
print_r ( mixed $expression [, bool $return = FALSE ] ) : mixed
:以易于理解的格式打印变量。
如果输入的内容是 string、 integer 或 float,会直接输出值本身。 如果输入的内容是 array,展示的格式会显示数组的键和包含的元素。object 也类似。
echo ( string $arg1 [, string $... ] ) : void
(语言结构,非函数):输出一个或多个字符串,无返回值。
传递多个参数是不需要考虑()
的优先级;但若是使用连接运算符.
,相对于加号和三目运算符就需要考虑优先级,使用()
。
sprintf ( string $format [, mixed $... ] ) : string
:返回格式化的字符串。
var_dump ( mixed $expression [, mixed $... ] ) : void
:打印变量的相关信息,此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构,无返回值。
var_export ( mixed $expression [, bool $return ] ) : mixed
: 输出或返回一个变量的字符串表示。此函数返回关于传递给该函数的变量的结构信息,它和 var_dump() 类似,不同的是其返回的表示是合法的 PHP 代码。
序列化及反序列化函数
*seserialize ( mixed $value ) : string
: 产生一个可存储的值的表示,返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
*unserialize ( string $str ) : mixed
:从已存储的表示中创建 PHP 的值,对单一的已序列化的变量进行操作,将其转换回 PHP 的值。
字符串处理函数
implode()
: 将一个一维数组的值转化为字符串。
explode()
:使用一个字符串分割另一个字符串。
join()
:此函数是inplode()的别名
strrev()
:反转字符串,返回反转后的字符串。
trim()
:除字符串首尾处的空白字符(或者其他字符)
ltrim()
:删除字符串开头的空白字符(或其他字符)
rtrim()
:删除字符串末端的空白字符(或者其他字符)
strstr()
:查找字符串的首次出现,该函数区分大小写。
number_format()
:以千位分隔符方式格式化一个数字
数组处理函数
array_keys()
:返回数组中部分的或所有的键名
array_values()
:返回数组中所有的值并给其建立数字索引。
array_diff()
:计算数组的差集,对比 array1 和其他一个或者多个数组,返回在 array1 中但是不在其他 array 里的值。
array_intersect()
:计算数组的交集,返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。
array_merge()
:将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
array_shift()
:将数组开头的单元移出数组
array_unshift()
:在数组开头插入一个或多个单元
array_pop()
:弹出数组最后一个单元(出栈),并将数组 array 的长度减一。
array_push()
:将一个或多个单元压入数组的末尾(入栈)
sort()
:本函数对数组进行排序。当本函数结束时数组单元将被从最低到最高重新安排。
array_rand()
:从数组中取出一个或多个随机的单元,并返回随机条目的一个或多个键。