PHP - 理论篇-1

PHP 变量

作用域

PHP 有四种不同的变量作用域:

  1. local 局部作用域
  2. global 全局作用域
  3. static 静态作用域
  4. parameter 函数参数作用域
// 1.2、局部和全局作用域	
// 在所有函数外部定义的变量,拥有全局作用域。
// 除了函数外,全局变量可以被脚本中的任何部分访问,
// 要在一个函数中访问一个全局变量,需要使用 global 关键字。
<?php
	$x=5; // 全局变量
	function myTest()
	{
	    global $x;
	    $y=10; // 局部变量
	    echo "<p>测试函数内变量:<p>";
	    echo "变量 x 为: " . $x;
	    echo "<br>";
	    echo "变量 y 为: $y";
	}
?>
// 3、static作用域
// 当一个函数完成时,它所有的变量通常都会被删除。
// 然而业务中我们希望某个局部变量不要被删除。
// 要做到这一点,请在您第一次声明变量时使用 static 关键字:
<?php
	function myTest()
	{
	    static $x=0;
	    echo $x;
	    $x++;
	    echo PHP_EOL;    // 换行符
	}
	myTest();
	myTest();
	myTest();
	// 输出 0 1 2
?>
// 4、参数作用域
// 参数是通过调用代码将值传递给函数的局部变量
// 参数是在参数列表中声明的,作为函数声明的一部分
<?php
	function myTest($x)
	{
	    echo $x;
	}
	myTest(5);
?>

小结:

1.定义在函数外部的就是全局变量,它的作用域从定义处一直到文件结尾
2、函数内定义的变量就是局部变量,它的作用域为函数定义范围内
3、函数之间存在作用域互补影响
4、函数内部需要访问全局变量需要global关键字或者使用$GLOBAL[index]数组
	参数是通过调用代码将值传递给函数的局部变量。
	关于局部变量和全局变量的优先级,因为在PHP中函数都有自己单独的作用域,所以在局部变量的优先级要大于全局变量(在你不声明这个变量之前),声明之后此变量就变成了局部变量如果修改值那么全局变量的值也会改变。
// 示例
<?php
	$a = 10;
	$b = 5;
	function test()
	{
	    $a = 15;
	    $b = 5;
	    $z = $a-$b;
	    echo $z;
	}
	test();
	function test1()
	{
	         global $a,$b;
	         $a = 15;
	         $b = 5;
	         $z = $a-$b;
	         echo PHP_EOL;
	         echo $z;
	}
	test1();
	function test2()
	{
	    global $a,$b;
	    $z= $a-$b;
	    echo PHP_EOL;
	    echo $z;
	}
	test2();
?>	// 输出 10 10 10

PHP echo/print

echo 	可以输出一个或多个字符
print 	只允许输出一个字符串,返回值总为1
   Tips: echo 的输出速度比print快,echo 没有返回值,print有返回值
	     echo(): 可以一次输出多个值,多个值之间用逗号分隔。echo是语言结构(language construct),而并不是真正的函数,因此不能作为表达式的一部分使用。
		 print(): 函数print()打印一个值(它的参数),如果字符串成功显示则返回true,否则返回false。
		 print_r(): 可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头。但print_r()输出布尔值和NULL的结果没有意义,因为都是打印"\n"。因此用var_dump()函数更适合调试。
		 var_dump(): 判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。

PHP EOF(heredoc)

1. 必须后接分号,否则编译不通过
2. EOF可以用任意其他字符代替,只需要保证结尾标识与开始标识一致
3. 结束标志必须顶格独自占一行(必须从行首开始,前后不能衔接任何字符串或空白字符)
4. 开始标识可以不带引号或带单双引号,不带引号与带双引号效果一致,解释内嵌的变量和转义符号,带单引号的则不解释内嵌的变量和转义符号。
5. 当内容需要内嵌引号(单引号或双引号)时,不需要加转义符号,本身对单双引号转义,相当于q与qq的用法
// 实例
<?php
$name="runoob";
$a= <<<EOF
	"abc"$name
	"123"
EOF;
// 结束需要独立一行且前后不能空格
echo $a;
?>
小结:
   1. PHP 定界符 EOF 的作用就是按照原样,包括换行格式什么的,输出在其内部的东西;
   2. 在 PHP 定界符 EOF 中的任何特殊字符都不需要转义;
   3. PHP 定界符 EOF

PHP 数据类型

String		字符串
Integer 	整型
Float 		浮点型
Boolean 	布尔型
Array 		数组
Object 		对象
NULL 		空值
整型可以用三种格式来指定
		十进制、十六进制、八进制
			$x = 0x8C; 		// 十六进制数( 以 0x 为前缀) 	140
			$x = 047; 		// 八进制数(前缀为 0)			39

PHP 类型比较

松散比较 	使用两个等号 == 比较,只比较值,不比较类型。
严格比较		用三个等号  === 比较,除了比较值,也比较类型。

PHP 常量

常量值被定义后,在脚本的其他任何地方都不能被改变
设置常量,使用 define() 函数,函数语法如下:
	bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
		该函数有三个参数:
			name:必选参数,常量名称,即标志符。
			value:必选参数,常量的值。
			case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感。默认是大小写敏感的。
常量是全局的					
	常量在定义后,默认是全局变量,可以在整个运行的脚本的任何地方使用。

PHP 字符串变量

PHP 并置运算符 	并置运算符 (.) 用于把两个字符串值连接起来
	echo $txt1 . " " . $txt2;

PHP 运算符

PHP 算术运算符
	运算符				名称					描述
	x + y				加					x 和 y 的和
	x - y				减					x 和 y 的差
	x * y				乘					x 和 y 的积
	x / y				除					x 和 y 的商
	x % y				模(除法的余数)		x 除以 y 的余数		
	- x					取反	x 				取反
	a . b				并置					连接两个字符串

PHP 赋值运算符			
	运算符				等同于				描述
	x = y				x = y				左操作数被设置为右侧表达式的值		
	x += y				x = x + y			加
	x -= y				x = x - y			减
	x *= y				x = x * y			乘
	x /= y				x = x / y			除	
	x %= y				x = x % y			模(除法的余数)
	a .= b				a = a . b			连接两个字符串

PHP 递增/递减运算符		
	运算符				名称					描述
	++ x				预递增				x 加 1,然后返回 x
	x ++				后递增				返回 x,然后 x 加 1
	-- x				预递减				x 减 1,然后返回 x	
	x --				后递减				返回 x,然后 x 减 1

PHP 比较运算符
	运算符				名称					描述	
	x == y				等于					如果 x 等于 y,则返回 true
	x === y				绝对等于				如果 x 等于 y,且它们类型相同,则返回 true
	x != y				不等于				如果 x 不等于 y,则返回 true
	x <> y				不等于				如果 x 不等于 y,则返回 true	
	x !== y				绝对不等于			如果 x 不等于 y,或它们类型不相同,则返回 true
	x > y				大于					如果 x 大于 y,则返回 true
	x < y				小于					如果 x 小于 y,则返回 true
	x >= y				大于等于				如果 x 大于或者等于 y,则返回 true
	x <= y				小于等于				如果 x 小于或者等于 y,则返回 true
			
PHP 逻辑运算符
	运算符				名称					描述
	x and y				与					如果 x 和 y 都为 true,则返回 true
	x or y				或					如果 x 和 y 至少有一个为 true,则返回 true
	x xor y				异或					如果 x 和 y 有且仅有一个为 true,则返回 true
	x && y				与					如果 x 和 y 都为 true,则返回 true		
	x || y				或					如果 x 和 y 至少有一个为 true,则返回 true
	! x					非					如果 x 不为 true,则返回 true
		Tips
			xor 如果 x 和 y 有且仅有一个为 true,则返回 true
				<?php
					$a = 1;
				    $b = 2;
				    if ($a == 2 xor $b == 2) {
				        echo true;
				    }
				?>	// true  if $a == 1 xor $b == 2 false
PHP 数组运算符	
	运算符				名称					述	
	x + y				集合					x 和 y 的集合
	x == y				相等					如果 x 和 y 具有相同的键/值对,则返回 true
	x === y				恒等					如果 x 和 y 具有相同的键/值对,且顺序相同类型相同,则返回 true
	x != y				不相等				如果 x 不等于 y,则返回 true
	x <> y				不相等				如果 x 不等于 y,则返回 true
	x !== y				不恒等				如果 x 不等于 y,则返回 true
		Tips
			x + y (集合)
				索引数组和关联数组都可以合并 注意键名与键值不能重复 否则会合并为一个

三元运算符
	语法格式		(expr1) ? (expr2) : (expr3) 
		对 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。
		自 PHP 5.3 起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。
			// PHP 5.3+ 版本写法
			<?php
				$test = "测试";
				$username = $test ?: 'nobody';
				echo $username, PHP_EOL; // 输出 测试nobody;
			?>

		在 PHP7+ 版本多了一个 NULL 合并运算符 ??,实例如下:
			<?php
				// 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值
				$username = $_GET['user'] ?? 'nobody';
				// 类似的三元运算符
				$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
			?>

组合比较符(PHP7+)
	PHP7+ 支持组合比较符(combined comparison operator)也称之为太空船操作符,符号为 <=>。组合比较运算符可以轻松实现两个变量的比较,当然不仅限于数值类数据的比较。
		语法格式如下:
			$c = $a <=> $b;
			解析如下:
				如果 $a > $b, 则 $c 的值为 1。
				如果 $a == $b, 则 $c 的值为 0。
				如果 $a < $b, 则 $c 的值为 -1。
			实例
			<?php
				// 整型
				echo 1 <=> 1; // 0
				echo 1 <=> 2; // -1
				echo 2 <=> 1; // 1
				// 浮点型
				echo 1.5 <=> 1.5; // 0
				echo 1.5 <=> 2.5; // -1
				echo 2.5 <=> 1.5; // 1
				// 字符串
				echo "a" <=> "a"; // 0
				echo "a" <=> "b"; // -1
				echo "b" <=> "a"; // 1
			?>				

运算符优先级
	下表按照优先级从高到低列出了运算符。同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。
	说明:左 = 从左到右,右 = 从右到左。
		结合方向								运算符								附加信息	
		无									clone new							clone 和 new
		左									[									array()													
		右		++ -- ~ (int) (float) (string) (array) (object) (bool) @		类型和递增/递减
		无									instanceof							类型
		右									!									逻辑运算符
		左									* / %								算术运算符
		左									+ – .								算术运算符和字符串运算符
		左									<< >>								位运算符
		无									== != === !== <>					比较运算符
		左									&									位运算符和引用
		左									^									位运算符
		左									|									位运算符
		左									&&									逻辑运算符
		左									||									逻辑运算符
		左									? :									三元运算符
		右				= += -= *= /= .= %= &= |= ^= <<= >>= =>					赋值运算符
		左									and									逻辑运算符
		左									xor									逻辑运算符
		左									or									逻辑运算符
		左									,									多处用到
			运算符优先级中,or 和 ||,&& 和 and 都是逻辑运算符,效果一样,但是其优先级却不一样。
				实例
					<?php
						// 优先级: &&  >  =  >  and
						// 优先级: ||  >  =  >  or
						$a = 3;
						$b = false;
						$c = $a or $b;
						var_dump($c);          // 这里的 $c 为 int 值3,而不是 boolean 值 true
						$d = $a || $b;
						var_dump($d);          //这里的 $d 就是 boolean 值 true 
					?>
						以上实例输出结果为:
							int(3)
							bool(true)

		运算符的优先级口诀:括(号)、单(操作数)、算(术)、移(位)、关(系);位(运算符)、逻(辑)、条(件)、赋(值)、逗(号)。

PHP If…Else 语句

if、 if else、 switch

PHP 数组

在 PHP 中,有三种类型的数组:
	数值数组 - 带有数字 ID 键的数组
	关联数组 - 带有指定的键的数组,每个键关联一个值
	多维数组 - 包含一个或多个数组的数组

PHP 数组排序

数组中的元素可以按照数字或字母顺序进行升序或降序
	sort() 		对数组进行升序排序
	rsort() 	对数组进行降序排序
	asort() 	根据关联数组的值,对数组进行升序排序
	ksort() 	根据关联数组的键,对数组进行升序排序
	arsort() 	根据关联数组的值,对数组进行降序排序
	krsort() 	根据关联数组的键,对数组进行降序排序

PHP 超级全局变量

PHP中预定义了几个超级全局变量(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明,就可以在函数及类中使用。
	PHP 超级全局变量列表:
		$GLOBALS
		$_SERVER
		$_REQUEST
		$_POST
		$_GET
		$_FILES
		$_ENV
		$_COOKIE
		$_SESSION
			下表列出了所有 $_SERVER 变量中的重要元素:
				元素/代码									描述
			$_SERVER['PHP_SELF'] 						当前执行脚本的文件名,与 document root 有关
			$_SERVER['GATEWAY_INTERFACE'] 				服务器使用的 CGI 规范的版本;例如,"CGI/1.1"。
			$_SERVER['SERVER_ADDR'] 					当前运行脚本所在的服务器的 IP 地址。
			$_SERVER['SERVER_NAME'] 					当前运行脚本所在的服务器的主机名。
			$_SERVER['SERVER_SOFTWARE'] 				服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24)
			$_SERVER['SERVER_PROTOCOL']  				请求页面时通信协议的名称和版本。例如,"HTTP/1.0"。
			$_SERVER['REQUEST_METHOD'] 					访问页面使用的请求方法;例如,"GET", "HEAD","POST","PUT"。
			$_SERVER['REQUEST_TIME'] 					请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496)
			$_SERVER['QUERY_STRING'] 					query string(查询字符串),如果有的话,通过它进行页面访问。
			$_SERVER['HTTP_ACCEPT'] 					当前请求头中 Accept: 项的内容,如果存在的话。
			$_SERVER['HTTP_ACCEPT_CHARSET'] 			当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:"iso-8859-1,*,utf-8"。
			$_SERVER['HTTP_HOST'] 						当前请求头中 Host: 项的内容,如果存在的话。
			$_SERVER['HTTP_REFERER'] 					引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。)
			$_SERVER['HTTPS'] 							如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
			$_SERVER['REMOTE_ADDR'] 					浏览当前页面的用户的 IP 地址。
			$_SERVER['REMOTE_HOST'] 					浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。
			$_SERVER['REMOTE_PORT'] 					用户机器上连接到 Web 服务器所使用的端口号。
			$_SERVER['SCRIPT_FILENAME'] 				当前执行脚本的绝对路径。
			$_SERVER['SERVER_ADMIN'] 					该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@runoob.com)
			$_SERVER['SERVER_PORT'] 					Web 服务器使用的端口。默认值为 "80"。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
			$_SERVER['SERVER_SIGNATURE'] 				包含了服务器版本和虚拟主机名的字符串。
			$_SERVER['PATH_TRANSLATED'] 				当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。
			$_SERVER['SCRIPT_NAME'] 					包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。
			$_SERVER['SCRIPT_URI'] 						URI 用来指定要访问的页面。例如 "/index.html"。

PHP 循环 - While 循环

while 		- 只要指定的条件成立,则循环执行代码块
do...while 	- 首先执行一次代码块,然后在指定的条件成立时重复这个循环
for 		- 循环执行代码块指定的次数
foreach 	- 根据数组中每个元素来循环代码块			
	1. while 循环
		while 循环将重复执行代码块,直到指定的条件不成立。
		语法
		while (条件)
		{
		    要执行的代码;
		}

	2. do...while 语句
		do...while 语句会至少执行一次代码,然后检查条件,只要条件成立,就会重复进行循环。
		语法
		do
		{
		    要执行的代码;
		}
		while (条件);

PHP 魔术常量

PHP 向它运行的任何脚本提供了大量的预定义常量。
不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。
有八个魔术常量它们的值随着它们在代码中的位置改变而改变。
例如 __LINE__ 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写,如下:
	
	__LINE__		文件中的当前行号。
	__FILE__		文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
	__DIR__ 		文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。
	__FUNCTION__	函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
	__CLASS__ 		类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。
	__TRAIT__ 		Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。Trait 名包括其被声明的作用区域(例如 Foo\Bar)。从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。
	__METHOD__		类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
		__FUNCTION__ 与 __METHOD__ 的区别,都可以取出当前访问的函数名字,__METHOD__可以附加取出当前的类名
	__NAMESPACE__ 	当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。
<?php
	class test {
	    function _print() {
	        echo '类名为:'  . __CLASS__ . "<br>";
	        echo  '函数名为:' . __FUNCTION__ ;
	    }
	}
	$t = new test();
	$t->_print();
?>
// 多个 trait 的情况:
<?php
	trait Hello {
	    public function sayHello() { 
	        echo 'Hello ';    
	    }
	}
	trait World {    
	    public function sayWorld() {     
	        echo 'World';  
	    }
	}
	class MyHelloWorld { 
	    use Hello, World;  
	    public function sayExclamationMark() {   
	        echo '!'; 
	    }
	}
	$o = new MyHelloWorld();
	$o->sayHello();
	$o->sayWorld();
	$o->sayExclamationMark();
?>	// 最终输出:Hello World!

PHP 命名空间(namespace)

PHP 命名空间可以解决以下两类问题:
	用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
	为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
	可以在同一个文件中定义不同的命名空间代码,如: ⬇️ ⬇️ ⬇️
<?php
	namespace MyProject {
	    const CONNECT_OK = 1;
	    class Connection { /* ... */ }
	    function connect() { /* ... */  }
	}

	namespace AnotherProject {
	    const CONNECT_OK = 1;
	    class Connection { /* ... */ }
	    function connect() { /* ... */  }
	}
?>
将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,例如:⬇️⬇️⬇️
<?php
	namespace MyProject {

	const CONNECT_OK = 1;
	class Connection { /* ... */ }
		function connect() { /* ... */  }
	}

	namespace { // 全局代码
		session_start();
		$a = MyProject\connect();
		echo MyProject\Connection::start();
	}
?>
// 在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。

PHP 面向对象

在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。
	对象的主要三个特性:
		对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为。
		对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
		对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。

面向对象内容	
	类 		定义了一件事的抽象特点。类的定义包含了数据的形式以及对数据的操作
	对象 	类的实例
	成员变量 定义在类内部的变量。该变量对外不可见,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可成为对象的属性
	成员函数 定义在类的内部,可用于访问对象的数据
	继承		继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干个新的内容
	父类 	一个类被其他类集成,可将该类称为父类,或基类,或超类
	子类 	一个类继承其他类称为子类,也可以成为派生类
	多态 	多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态
	重载 	就是函数或方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或方法
	抽象性 	抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反应了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用相关。
	封装 	封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个单元内
	构造函数 主要用来在创建对象时创建初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中
	析构函数 析构函数与构造函数相反,当对象结束生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做'清理善后'工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)


访问控制
	PHP对属性或方法的访问控制,是通过在前面添加关键字public、protected、private来实现的。
		public 		共有的类成员可以在任何地方访问
		protected 	受保护的类成员则可以被其自身、子类、父类访问
		private 	私有的类成员则只能被其定义所在的类访问

	属性的访问控制
		类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。

	方法的访问控制
		类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。

	接口
		使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
		接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义的所有方法都是空的。
		接口中定义的所有方法必须共有,这就是接口的特性。
		要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分割多个接口的名称
		<?php
			// 申明一个iTemplate的接口
			interface iTemplate 
			{
				public function a($name, $var) {}
				public function b($template) {}
			}

			// 实现接口
			class a implements iTemplate
			{
				private $var = [];

				public function a($name, $var)
				{
					$this->var[$name] = $var;
				}

				public function b($template)
				{
					foreach($this->var as $name => $value) {
			            $template = str_replace('{' . $name . '}', $value, $template);
			        }
			        return $template;
				}
			}
		?>
		常量
		可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不要使用 $ 符号
		常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。
		自PHP5.3起,可以用一个变量来动态调用类。但该变量的值不能是关键字(如self,parent或者static)。
			<?php
			class ClassName
			{	
				const number = 22;
				public function a()
				{
					echo self::number . PHP_EOL;
				}
			}
			echo ClassName::number . PHP_EOL;

			echo ClassName::number . PHP_EOL; 	// 自 5.3.0 起

			$class = new ClassName();
			$class->a();

			echo $class::number . PHP_EOL; 		// 自 PHP 5.3.0 起

			?>

	抽象类
		任何一个类,如果它里面至少有一个方法是被申明为抽象的,那么这个类就必须被申明为抽象的
		定义为抽象类不能被实例化
		被定义为抽象的方法只是申明了其调用的方式(参数),不能定义其具体的功能实现。
		继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中的一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或公有的,而不能定义为私有的。
			<?php
				abstract class AbstractClass
				{
				 // 强制要求子类定义这些方法
				    abstract protected function getValue();
				    abstract protected function prefixValue($prefix);

				    // 普通方法(非抽象方法)
				    public function printOut() {
				        print $this->getValue() . PHP_EOL;
				    }
				}

				class ConcreteClass1 extends AbstractClass
				{
				    protected function getValue() {
				        return "ConcreteClass1";
				    }

				    public function prefixValue($prefix) {
				        return "{$prefix}ConcreteClass1";
				    }
				}

				class ConcreteClass2 extends AbstractClass
				{
				    public function getValue() {
				        return "ConcreteClass2";
				    }

				    public function prefixValue($prefix) {
				        return "{$prefix}ConcreteClass2";
				    }
				}

				$class1 = new ConcreteClass1;
				$class1->printOut();
				echo $class1->prefixValue('FOO_') . PHP_EOL;

				$class2 = new ConcreteClass2;
				$class2->printOut();
				echo $class2->prefixValue('FOO_') . PHP_EOL;
			?>
			执行以上代码,输出结果为:
				ConcreteClass1
				FOO_ConcreteClass1
				ConcreteClass2
				FOO_ConcreteClass2

		此外,子类方法可以包含父类抽象方法中不存在的可选参数。
		例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则也是可以正常运行的。
			<?php
				abstract class AbstractClass
				{
				    // 我们的抽象方法仅需要定义需要的参数
				    abstract protected function prefixName($name);

				}

				class ConcreteClass extends AbstractClass
				{

				    // 我们的子类可以定义父类签名中不存在的可选参数
				    public function prefixName($name, $separator = ".") {
				        if ($name == "Pacman") {
				            $prefix = "Mr";
				        } elseif ($name == "Pacwoman") {
				            $prefix = "Mrs";
				        } else {
				            $prefix = "";
				        }
				        return "{$prefix}{$separator} {$name}";
				    }
				}

				$class = new ConcreteClass;
				echo $class->prefixName("Pacman"), "\n";
				echo $class->prefixName("Pacwoman"), "\n";
			?>
			输出结果为:
				Mr. Pacman
				Mrs. Pacwoman
	
	Static 关键字
		声明类属性或方法为 static,就可以不实例化类而直接访问
		静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)	
		由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用
		静态属性不可以由对象通过 -> 操作符来访问
		自php5.3起,可以用一个变量来动态调用类。但该变量的值不能为关键字 self、parent、static
			<?php
			class Foo {
			  public static $my_static = 'foo';
			  
			  public function staticValue() {
			     return self::$my_static;
			  }
			}

			print Foo::$my_static . PHP_EOL;
			$foo = new Foo();

			print $foo->staticValue() . PHP_EOL;
			?>    	
			执行以上程序,输出结果为:
			foo
			foo

	Final 关键字
		PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
		以下代码执行会报错:
			<?php
			class BaseClass {
			   public function test() {
			       echo "BaseClass::test() called" . PHP_EOL;
			   }
			   
			   final public function moreTesting() {
			       echo "BaseClass::moreTesting() called"  . PHP_EOL;
			   }
			}

			class ChildClass extends BaseClass {
			   public function moreTesting() {
			       echo "ChildClass::moreTesting() called"  . PHP_EOL;
			   }
			}
			// 报错信息 Fatal error: Cannot override final method BaseClass::moreTesting()
			?>

	调用父类构造方法
		PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct() 。
			<?php
			class BaseClass {
			   function __construct() {
			       print "BaseClass 类中构造方法" . PHP_EOL;
			   }
			}
			class SubClass extends BaseClass {
			   function __construct() {
			       parent::__construct();  // 子类构造方法不能自动调用父类的构造方法
			       print "SubClass 类中构造方法" . PHP_EOL;
			   }
			}
			class OtherSubClass extends BaseClass {
			    // 继承 BaseClass 的构造方法
			}

			// 调用 BaseClass 构造方法
			$obj = new BaseClass();

			// 调用 BaseClass、SubClass 构造方法
			$obj = new SubClass();

			// 调用 BaseClass 构造方法
			$obj = new OtherSubClass();
			?>
			执行以上程序,输出结果为:

			BaseClass 类中构造方法
			BaseClass 类中构造方法
			SubClass 类中构造方法
			BaseClass 类中构造方法

PHP 表单

htmlspecialchars
htmlspecialchars函数把一些预定义的字符转换为html实体。
	预定义的字符是
		& 	和号  	&amp;
		"	双引号 	&quot;
		' 	单引号 	&#039;
		< 	小于 	&lt;
		> 	大于 	&gt;
stripslashes
删除反斜杠	

PHP date() 函数

语法格式如下:
string date ( string $format [, int $timestamp ] )
	$format 		必需。规定时间戳的格式。
	$timestamp 		可选。规定时间戳。默认是当前的日期和时间。
		
PHP Date() - 格式化日期
date函数的第一个必须参数format规定了如何格式化时间、日期
这里列举了一些可用的字符
	d - 代表月中的天
	m - 代表月
	Y - 代表年

格式字符串可以识别以下format参数的字符串
format字符 						说明 								返回值例子
日 							--- 								  ---
d 					月份中的第几天,有前导0的两位数字 				01到31
D 					星期中的第几天,文本表示,3个字母 				Mon到Sun
j 					月份中的第几天,没有前导0 						1到31
l(L的小写字母) 		星期几,完整的文本格式    						Sunday 到 Saturday
N 					ISO-8601格式数字表示的星期中的第几天 				1表示星期一 到 7表示星期天
S 					每月天数后面的英文后缀,2个字符 					st,nd,rd,th。可以和j一起用
w 					星期中的第几天,数字表示 						0代表周天 6代表周六
z 					年份中的第几天 								0到365

星期 						--- 								  ---
W 					ISO-8601格式年份中的第几周,每周从星期一开始 		例如42当年的第42周

月 							--- 								  ---
F 					月份,完整的文本格式,例如January或March 			January到December
m 					数字表示的月份,有前导0    						01到12
M 					三个字母缩写表示的月份							Jan 到 Dec
n  					数字表示月份,没有前导0  						1到12
t 					给定月份所应有的天数 							28到31

年 							--- 								  ---
L 					是否为闰年 									是闰年为1 否为0
o   				ISO-8601 格式年份数字,这和Y的值相同,只除了  		1999 or 2003
					如果ISO的星期数(W)属于前一年或下一年
					则用那一年 
Y 					四位数子完整表示的年份 							1999 或 2003
y 					两位数字表示的年份 								99 或 03

时间 						--- 								  ---
a 					小写的上午和下午的值	 						am或pm
A 					大写的上午和下午的值 							AM或PM
B 					Swatch Internet标准时 						000 到 999
g 					小时 12小时制 没有前导0 						1 到 12
G 					小时 24小时制 没有前导0 						0 到 23
h 					小时 12小时格式 有前导0 						01 到 12
H 					小时 24小时格式 有前导0 						00 到 23
i 					有前导0的分钟数 								00 到 59
s 					秒 有前导0  									00 到 59
u 					毫秒,需要注意的是date()函数总是返回000000因为	654321
					它只接受int参数,而DateTime::format()才支持毫秒 	

时区 						--- 									---
e 					时区标识 										如UTC、GMT、Atlantic/Azores
I  					是否为夏令时 									是返回1 否返回0
O 					与格林尼治时间相差的小时数 						+0200
P 					与格林威治时间的差别,小时和分钟之间有冒号分割 		+02:00
T 					本机所在时间 									例如:EST,MDT(【译者注】在 Windows 下为完整文本格式,例如"Eastern Standard Time",中文版会显示"中国标准时间")。
Z 					时差偏移量的秒数,UTC西边的时区偏移量总是负数的, 	-43200 到 43200
					UTC东边的时区偏移量总是正的

完整的日期/时间 				--- 								    ---
c 					ISO 8601 格式的日期 							2021-01-29T13:35:20+08:00
r 					RFC 822 格式的日期							Fri, 29 Jan 2021 13:38:48 +0800
U 					从Unix纪元开始至今的秒数 						参见time()

PHP 包含文件

PHP include 和 require 语句
在php中,可以在服务器执行PHP的文件之前在该文件中插入一个文件的内容
include 与 require 语句用于在执行流中插入写在其他文件中的有用的代码
include 与 require 在处理方式上不同之外,在其他方面都是相同的
	require生成一个致命错误,在错误发生之后脚本会停止执行
	incloud生成一个警告,在错误发生之后脚本会继续执行
因此,如果您希望继续执行,并向用户输出结果,即使包含文件已丢失,那么就使用include。否则 在框架、CMS或者复杂的PHP应用程序编程中,请始终使用require向执行流引用关键文件。这有助于提高应用程序的安全性和完整性,在某个文件以外丢失的情况下。
语法
	include 'filename';
	或者
	require 'filename';	
小结:
	include 与 require 的区别
		require 一般放在PHP文件的最前面,程序在执行前就会先导入要引用的文件
		include 一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程
		require 引入的文件有错误时,执行会中断,并返回一个致命错误
		include 引入的文件有错误时,会继续执行,并返回一个警告

PHP 文件处理

fopen()函数用于在PHP中打开文件
该函数的第一个参数含有要打开文件的名字,第二个参数规定了使用哪种模式来打开文件
文件可以通过下列的模式来打开
	模式 			描述
	 r 				只读。在文件的开头开始
	 r+ 			读/写。在文件的开头开始
	 w 				只写。打开并清空文件的内容;如果文件不存在,则创建新的文件
	 w+ 			读/写。打开并清空文件的内容;如果文件不存在,则创建新的文件
	 a 				追加。打开并向文件末尾进行写操作,如果文件不存在,则创建新文件
	 a+ 			读/追加。通过向文件末尾写内容,来保持文件内容
	 x 				只写。创建新文件。如果文件已存在,则返回false和一个错误
	 x+ 			读/写。创建新文件。如果文件已存在,则返回false和一个错误
	 	Tips:如果fopen()函数无法打开指定文件,则返回0 false
fclose() 函数用于关闭打开的文件

检测文件末尾(EOF)
feof() 函数检测是否已到达文件末尾(EOF)。
在循环遍历未知长度的数据时,feof() 函数很有用。
注释:在 w 、a 和 x 模式下,您无法读取打开的文件!
if (feof($file)) echo "文件结尾";

逐行读取文件
fgets() 函数用于从文件中逐行读取文件。
注释:在调用该函数之后,文件指针会移动到下一行。
	下面的实例逐行读取文件,直到文件末尾为止:
		<?php
		$file = fopen("welcome.txt", "r") or exit("无法打开文件!");
		// 读取文件每一行,直到文件结尾
		while(!feof($file))
		{
		    echo fgets($file). "<br>";
		}
		fclose($file);
		?>

逐字符读取文件
fgetc()函数用于从文件中逐字符的读取文件
注释:在调用该函数之后,文件指针会移动到下一个字符。
	下面的实例逐字符的读取文件,直到文件末尾为止:
		<?php
		$file=fopen("welcome.txt","r") or exit("无法打开文件!");
		while (!feof($file))
		{
		    echo fgetc($file);
		}
		fclose($file);
		?>
	如果打开一个文件,文件名为中文,如果系统编程和当前文档编码不一致,会导致文件找不到无法打开,解决方法是用 iconv 函数编码转换成一致,如下:
		<?php
		$fpath=iconv('UTF-8','GB2312',"题库.csv");
		$file=fopen($fpath,"r") or exit("无法打开文件!");
		//此处省略相关操作
		fclose($file);
		?>

PHP 文件上传

通过使用PHP的全局数组$_FILES
$_FILES	- name 		上传文件的名称
$_FILES - type 		上传文件的类型
$_FILES - size 		上传文件的大小,以字节计
$_FILES - tmp_name 	存储在服务器的文件的临时副本的名称
$_FILES - error 	由文件上传导致错误的代码	
	UPLOAD_ERR_OK 			- 	0 	- 	没有发生错误,文件上传成功
	UPLOAD_ERR_INI_SIZE 	- 	1 	- 	上传的文件超过了php.ini中 upload_max_filesize 选项限制的值
	UPLOAD_ERR_FROM_SIZE 	- 	2 	- 	上传文件大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值
	UPLOAD_ERR_PARTIAL 		- 	3	- 	文件只有部分被上传。 
	UPLOAD_ERR_NO_FILE 		- 	4 	- 	没有文件被上传。 
	UPLOAD_ERR_NO_TMP_DIR 	- 	6	- 	找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
	UPLOAD_ERR_CANT_WRITE 	- 	7 	- 	文件写入失败。PHP 5.1.0 引进。

	文件被上传结束后,默认的被存储在了临时目录中,这事需要将他从临时文件目录中删除或者移动到其他地方,如果没有,则会被删除。也就是不管是否上传成功,脚本执行完后临时目录里的文件肯定会被删除。所以在删除之前要用PHP的 copy() 函数将它复制到其它位置,此时,才算完成了上传文件过程。

PHP Cookie

Cookie 是什么?
cookie常用于识别用户。cookie是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送cookie。通过PHP,您能够创建并取回 cookie 的值。

如何创建 Cookie?
语法
	setcookie(name, value, expire, path, domain);
在下面的例子中,我们将创建名为 "user" 的 cookie,并为它赋值 "runoob"。我们也规定了此 cookie 在一小时后过期:
	<?php
	setcookie("user", "runoob", time()+3600);
	?>

您还可以通过另一种方式设置 cookie 的过期时间。这也许比使用秒表示的方式简单。
	<?php
	$expire=time()+60*60*24*30;
	setcookie("user", "runoob", $expire);
	?>
	在上面的实例中,过期时间被设置为一个月(60 秒 * 60 分 * 24 小时 * 30 天)。

如何取回 Cookie 的值?
	PHP 的 $_COOKIE 变量用于取回 cookie 的值。
		在下面的实例中,我们取回了名为 "user" 的 cookie 的值,并把它显示在了页面上:
			<?php
			// 输出 cookie 值
			echo $_COOKIE["user"];

			// 查看所有 cookie
			print_r($_COOKIE);
			?>

如何删除 Cookie?
	当删除 cookie 时,您应当使过期日期变更为过去的时间点。
		<?php
		// 设置 cookie 过期时间为过去 1 小时
		setcookie("user", "", time()-3600);
		?>

如果浏览器不支持 Cookie 该怎么办?
	如果您的应用程序需要与不支持 cookie 的浏览器打交道,那么您不得不使用其他的办法在您的应用程序中的页面之间传递信息。

PHP Session

PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置。Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的。
PHP Session 变量
	在计算机上操作某个应用程序时,您打开它,做些更改,然后关闭它。这很像一次对话(Session)。计算机知道您是谁。它清楚您在何时打开和关闭应用程序。然而,在因特网上问题出现了:由于 HTTP 地址无法保持状态,Web 服务器并不知道您是谁以及您做了什么。
	PHP session 解决了这个问题,它通过在服务器上存储用户信息以便随后使用(比如用户名称、购买商品等)。然而,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久存储信息,可以把数据存储在数据库中。
	Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

开始 PHP Session
	在您把用户信息存储到 PHP session 中之前,首先必须启动会话。
		<?php session_start(); ?>
		上面的代码会向服务器注册用户的会话,以便您可以开始保存用户信息,同时会为用户会话分配一个 UID。

存储 Session 变量
	存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:
		<?php
		session_start();
		// 存储 session 数据
		$_SESSION['views']=1;
		?>

		<?php
		// 检索 session 数据
		echo "浏览量:". $_SESSION['views'];
		?>

销毁 Session
	如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy() 函数。
		unset() 函数用于释放指定的 session 变量:
			<?php
			session_start();
			if(isset($_SESSION['views']))
			{
			    unset($_SESSION['views']);
			}
			?>
		您也可以通过调用 session_destroy() 函数彻底销毁 session:
			<?php
			session_destroy();
			?>

PHP 发送电子邮件

PHP mail() 函数
	语法 mail(to,subject,message,headers,parameters)
	参数					描述
	to 				必须。规定email接收者。
	subject 		必须。规定email的主题。注释:该参数不能包含任何新行字符。
	message 		必须。定义要发送的消息。应使用LF(\n)来分割各行。每行应该限制在70个字符内。
	headers 		可选。规定附加的标题,比如From、Cc和Bcc。应当使用CRLF(\r\n)分隔附加的标题。
	parameters 		可选。对邮件发送程序规定额外的参数。

PHP 简易 E-Mail
	通过PHP发送电子邮件的最简单的方式是发送一封文本 email
	在下面的实例中,我们首先声明变量 ($to, $subject, $message, $from, $headers),然后我们在mail()函数中使用这些变量来发送一封E-mail
		<?php
		$to = "someone@example.com";         // 邮件接收者
		$subject = "参数邮件";                // 邮件标题
		$message = "Hello! 这是邮件的内容。";  // 邮件正文
		$from = "someonelse@example.com";   // 邮件发送者
		$headers = "From:" . $from;         // 头部信息设置
		mail($to,$subject,$message,$headers);
		echo "邮件已发送";
		?>

PHP 错误处理

错误报告级别
	值 			常量 					描述
	2			E_WARNING 				非致命的run-time错误。不暂停脚本执行。
	8			E_NOTICE 				run-time通知。在脚本发现可能有错误时发生,但也可能在脚本正常运行时发生。
	256 		E_USER_ERROR 			致命的用户生成的错误。这类似于程序员使用php函数trigger_error()设置的E_ERROR。
	512 		E_USER_WARNING 			非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。
	1024 		E_USER_NOTICE 			用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。
	4096 		E_RECOVERABLE_ERROR 	可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler())
	8191 		E_ALL 					所有错误和警告。(在 PHP 5.4 中,E_STRICT 成为 E_ALL 的一部分)
		<?php
		// 错误处理函数
		function customError($errno, $errstr)
		{
		    echo "<b>Error:</b> [$errno] $errstr<br>";
		    echo "脚本结束";
		    die();
		}

		// 设置错误处理函数
		set_error_handler("customError",E_USER_WARNING);

		// 触发错误
		$test=2;
		if ($test>1)
		{
		    trigger_error("变量值必须小于等于 1",E_USER_WARNING);
		}
		?>
			以上代码的输出如下所示:
			Error: [512] 变量值必须小于等于 1
			脚本结束

PHP 过滤器

PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入。
什么是 PHP 过滤器?
	PHP 过滤器用于验证和过滤来自非安全来源的数据。
	测试、验证和过滤用户输入或自定义数据是任何Web应用程序的重要组成部分。
	PHP的过滤器扩展的设计目的是使数据过滤更轻松快捷

什么是外部数据?	
	来自表单的输入数据
	cookie
	Web Server data
	服务器变量
	数据库查询结果

函数和过滤器
	如需过滤变量,使用下列的过滤器函数之一
		filter_var() 		-  		通过一个指定的过滤器来过滤单一的变量
		filter_var_array() 	- 		通过相同或者不同的过滤器来过滤多个变量
		filter_input() 		- 		获取一个输入变量,并对他进行过滤
		filter_input_array()- 		获取多个输入变量,并通过相同或者不同的过滤器对他们进行过滤
			实例	使用filter_var()函数验证一个整数
				<?php
				$int = 123;
				if (!filter_var($int, FILTER_VALIDATE_INT)) 
				?>

Validating 和 Sanitizing
	有两种过滤器
	Validating 过滤器
		用于验证用户输入
		严格的格式规则
		成功返回预期的类型,失败返回FALSE
	Sanitizing 过滤器
		用于允许或禁止字符串中指定的字符
		无数据格式规则
		始终返回字符串

PHP 高级过滤器

检测一个数字是否在一个范围内
	<?php
	$int = 122;
	$min = 1;
	$max = 200;

	if (filter_var($int, FILTER_VALIDATE_INT, array("options" => array("min_range"=>$min, "max_range"=>$max))) === false) {
	    echo("变量值不在合法范围内");
	} else {
	    echo("变量值在合法范围内");
	}
	?>

检测 IPv6 地址
	<?php
	$ip = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334";

	if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
	    echo("$ip 是一个 IPv6 地址");
	} else {
	    echo("$ip 不是一个 IPv6 地址");
	}
	?>

检测 URL - 必须包含QUERY_STRING(查询字符串)
	<?php
	$url = "http://www.runoob.com";

	if (!filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED) === false) {
	    echo("$url 是一个合法的 URL");
	} else {
	    echo("$url 不是一个合法的 URL");
	}
	?>

移除 ASCII 值大于 127 的字符
	<?php
	$str = "<h1>Hello WorldÆØÅ!</h1>";

	$newstr = filter_var($str, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
	echo $newstr;
	?>

PHP JSON

JSON 函数
	函数					描述
	json_encode			对变量进行 JSON 编码
	json_decode			对 JSON 格式的字符串进行解码,转换为 PHP 变量
	json_last_error		返回最后发生的错误

json_encode
	PHP json_encode() 用于对变量进行 JSON 编码,该函数如果执行成功返回 JSON 数据,否则返回 FALSE 。
	语法 string json_encode ( $value [, $options = 0 ] )
		参数
			value: 				要编码的值。该函数只对 UTF-8 编码的数据有效。
			options:			由以下常量组成的二进制掩码 JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR。
			要注意的是  			JSON_UNESCAPED_UNICODE 选项,如果我们不希望中文被编码,可以添加该选项。

json_decode
	PHP json_decode() 函数用于对 JSON 格式的字符串进行解码,并转换为 PHP 变量。
	语法  mixed json_decode ($json_string [,$assoc = false [, $depth = 512 [, $options = 0 ]]])
		参数
			json_string: 		待解码的 JSON 字符串,必须是 UTF-8 编码数据
			assoc: 				当该参数为 TRUE 时,将返回数组,FALSE 时返回对象。
			depth: 				整数类型的参数,它指定递归深度
			options: 			二进制掩码,目前只支持 JSON_BIGINT_AS_STRING 

PHP 7 新特性

1、PHP标量类型与返回值类型声明

	标量类型声明
		默认情况下,所有的PHP文件都处于弱类型校验模式。
		PHP7增加了标量类型声明的特性,标量类型声明有两种模式
			强制模式(默认)
			严格模式
		标量类型声明语法格式
			declare(strict_types=1);
				代码中通过指定declare值 1或0,1代表严格类型校验模式,作用于函数调用和返回语句;0表示若类型校验模式
				可以使用的类型有
					int、float、bool、string、interface、array、callable

	强制模式实例	
		<?php
		// 强制模式
		function sum(int ...$ints)
		{
		   return array_sum($ints);
		}

		print(sum(2, '3', 4.1));
		?>	
			以上程序执行输出结果为:9

	严格模式实例
		<?php
		// 严格模式
		declare(strict_types=1);

		function sum(int ...$ints)
		{
		   return array_sum($ints);
		}

		print(sum(2, '3', 4.1));
		?>	
			以上程序由于采用了严格模式,所以如果参数中出现不适整数的类型会报错,执行输出结果为:PHP Fatal error:  Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, called in……

	返回类型声明
		PHP7增加了对返回类型声明的支持,返回类型声明指明了函数返回值的类型。
		可以声明返回值的类型有:
			int、float、bool、string、interfaces、array、callable
		返回类型声明实例
		实例中,要求返回结果为整数:
			<?php
			declare(strict_types=1);

			function returnIntValue(int $value): int
			{
			   return $value;
			}

			print(returnIntValue(5));
			?>
				以上程序执行输出结果为:5

		返回类型声明错误实例
			<?php
			declare(strict_types=1);

			function returnIntValue(int $value): int
			{
			   return $value + 1.0;
			}

			print(returnIntValue(5));
			?>
			以上程序由于采用了严格模式,返回值必须是 int,但是计算结果是float,所以会报错,执行输出结果为:Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned...

	void 函数
		一个新的返回值类型void被引入。返回值声明为void类型的方法要么干脆省去return语句,要么使用一个空的return语句。对于void函数来说,NULL 不是一个合法的返回值。
		返回的类型还有 void,定义返回类型为 void 的函数不能有返回值,即使返回 null 也不行。
		void 函数可以省去 return 语句,或者使用一个空的 return 语句。
			<?php
			function swap(&$left, &$right) : void
			{
			    if ($left === $right) {
			        return;
			    }

			    $tmp = $left;
			    $left = $right;
			    $right = $tmp;
			}

			$a = 1;
			$b = 2;
			var_dump(swap($a, $b), $a, $b);
			?>
				以上实例输出结果:null、int(2)、int(1)

	小结:
		对于标量类型声明:在严格模式下,有一种例外的情况是:当函数参数为float时,传入int型变量不会跑出typeerror,而是正常执行,在返回类型声明中,也是同样的:
			<?php
			declare(strict_types = 1);
			function test (float $inter) {
			    return $inter;
			}

			echo test(2); // 结果为2

			function test1(int $inte) : float{
			    return $inte;
			}
			echo test1(1); // 结果为1
			?>

2、PHP NULL 合并运算符

PHP 7 新增加的 NULL 合并运算符(??)是用于执行isset()检测的三元运算的快捷方式。
	NULL 合并运算符会判断变量是否存在且值不为NULL,如果是,它就会返回自身的值,否则返回它的第二个操作数。
		以前我们这样写三元运算符:
			$site = isset($_GET['site']) ? $_GET['site'] : 'value';
		现在我们可以直接这样写:
			$site = $_GET['site'] ?? 'value';
			<?php
			// 获取 $_GET['site'] 的值,如果不存在返回 'value'
			$site = $_GET['site'] ?? 'value';

			print($site);
			print(PHP_EOL); // PHP_EOL 为换行符


			// 以上代码等价于
			$site = isset($_GET['site']) ? $_GET['site'] : 'value';

			print($site);
			print(PHP_EOL);
			// ?? 链
			$site = $_GET['site'] ?? $_POST['site'] ?? 'value';

			print($site);
			?>
	
	?? 与 ?: 的区别
		$a = 10;
		var_dump($a ?? "a"); // 相当于: isset($a) ? $a : 'a' => 输出 10  
		var_dump($a ?: "b"); // 相当于: $a ? $a : 'a' =>输出 10
		如果:
		$a = false;
		var_dump($a ?? "a"); // 相当于: isset($a) ? $a : 'a' => 输出 false
		var_dump($a ?: "b"); // 相当于: $a ? $a : 'a' =>输出 10

3、PHP 太空船运算符(组合比较符)

PHP 7 新增加的太空船运算符(组合比较符)用于比较两个表达式 $a 和 $b,如果 $a 小于、等于或大于 $b时,它分别返回-1、0或1。
		<?php
		// 整型比较
		print( 1 <=> 1);print(PHP_EOL);
		print( 1 <=> 2);print(PHP_EOL);
		print( 2 <=> 1);print(PHP_EOL);
		print(PHP_EOL); // PHP_EOL 为换行符

		// 浮点型比较
		print( 1.5 <=> 1.5);print(PHP_EOL);
		print( 1.5 <=> 2.5);print(PHP_EOL);
		print( 2.5 <=> 1.5);print(PHP_EOL);
		print(PHP_EOL);

		// 字符串比较
		print( "a" <=> "a");print(PHP_EOL);
		print( "a" <=> "b");print(PHP_EOL);
		print( "b" <=> "a");print(PHP_EOL);
		?>
		以上程序执行输出结果为:
							0
							-1
							1

							0
							-1
							1

							0
							-1
							1

4、PHP 常量数组

在 PHP 5.6 中仅能通过 const 定义常量数组,PHP 7 可以通过 define() 来定义。
		<?php
		// 使用 define 函数来定义数组
		define('sites', [
		   'Google',
		   'Runoob',
		   'Taobao'
		]);

		print(sites[1]);
		?>

5、PHP 匿名类

PHP 7 支持通过 new class 来实例化一个匿名类,这可以用来替代一些"用后即焚"的完整类定义。
		<?php
		interface Logger {
		   public function log(string $msg);
		}

		class Application {
		   private $logger;

		   public function getLogger(): Logger {
		      return $this->logger;
		   }

		   public function setLogger(Logger $logger) {
		      $this->logger = $logger;
		   }  
		}

		$app = new Application;
		// 使用 new class 创建匿名类
		$app->setLogger(new class implements Logger {
		   public function log(string $msg) {
		      print($msg);
		   }
		});

		$app->getLogger()->log("我的第一条日志");
		?>
			以上程序执行输出结果为:
				我的第一条日志

6、PHP Closure::call()

PHP 7 的 Closure::call() 有着更好的性能,将一个闭包函数动态绑定到一个新的对象实例并调用执行该函数。
		<?php
		class A {
		    private $x = 1;
		}

		// PHP 7 之前版本定义闭包函数代码
		$getXCB = function() {
		    return $this->x;
		};

		// 闭包函数绑定到类 A 上
		$getX = $getXCB->bindTo(new A, 'A'); 

		echo $getX();
		print(PHP_EOL);

		// PHP 7+ 代码
		$getX = function() {
		    return $this->x;
		};
		echo $getX->call(new A);
		?>
			以上程序执行输出结果为:
				1
				1

7、PHP 过滤 unserialize()

PHP 7 增加了可以为 unserialize() 提供过滤的特性,可以防止非法数据进行代码注入,提供了更安全的反序列化数据。
		<?php
		class MyClass1 { 
		   public $obj1prop;   
		}
		class MyClass2 {
		   public $obj2prop;
		}


		$obj1 = new MyClass1();
		$obj1->obj1prop = 1;
		$obj2 = new MyClass2();
		$obj2->obj2prop = 2;

		$serializedObj1 = serialize($obj1);
		$serializedObj2 = serialize($obj2);

		// 默认行为是接收所有类
		// 第二个参数可以忽略
		// 如果 allowed_classes 设置为 false, unserialize 会将所有对象转换为 __PHP_Incomplete_Class 对象
		$data = unserialize($serializedObj1 , ["allowed_classes" => true]);

		// 转换所有对象到 __PHP_Incomplete_Class 对象,只允许 MyClass1 和 MyClass2 转换到 __PHP_Incomplete_Class
		$data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);

		print($data->obj1prop);
		print(PHP_EOL);
		print($data2->obj2prop);
		?>
			以上程序执行输出结果为:
				1
				2

8、PHP IntlChar()

PHP 7 通过 intl 扩展来支持国际化 (i18n) 和本地化 (l10n) 。此扩展仅仅是对 ICU 库的基础包装,并提供了和 ICU 库类似的方法和特性。
	PHP 7 通过新的 IntlChar 类暴露出 ICU 中的 Unicode 字符特性。这个类自身定义了许多静态方法用于操作多字符集的 unicode 字符。
		<?php
		printf('%x', IntlChar::CODEPOINT_MAX);
		echo IntlChar::charName('@');
		var_dump(IntlChar::ispunct('!'));
		?>
			以上程序执行输出结果为:
				10ffff
				COMMERCIAL AT
				bool(true)

9、PHP CSPRNG

CSPRNG(Cryptographically Secure Pseudo-Random Number Generator,伪随机数产生器)。
	PHP 7 通过引入几个 CSPRNG 函数提供一种简单的机制来生成密码学上强壮的随机数。
		random_bytes() 	- 加密生存被保护的伪随机字符串。
		random_int() 	- 加密生存被保护的伪随机整数。
	random_bytes()
		语法格式
		 	string random_bytes ( int $length )
		参数
			length - 随机字符串返回的字节数。
		返回值
			返回一个字符串,接受一个int型入参代表返回结果的字节数。
		<?php
		$bytes = random_bytes(5);
		print(bin2hex($bytes));
		?>
			以上程序执行输出结果为:
			6f36d48a29
	random_int()
		语法格式
		int random_int ( int $min , int $max )
		参数
			min - 返回的最小值,必须是大于或等于 PHP_INT_MIN 。
			max - 返回的最大值,必须是小于或等于 PHP_INT_MAX 。
			返回值
			返回一个指定范围内的int型数字。
			<?php
			print(random_int(100, 999));
			print(PHP_EOL);
			print(random_int(-1000, 0));
			?>
			以上程序执行输出结果为:
				723
				-64

10、PHP 7 异常

PHP 7 异常用于向下兼容及增强旧的assert()函数。它能在生产环境中实现零成本的断言,并且提供抛出自定义异常及错误的能力。
	老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean。

	assert() 配置	
		配置项				默认值			可选值
		zend.assertions		1				1 - 生成和执行代码 (开发模式)
											0 - 生成代码,但在执行时跳过它
											-1 - 不生成代码 (生产环境)
		assert.exception	0				1 - 断言失败时抛出,可以抛出异常对象,如果没有提供异常,则抛出 AssertionError 对象实例。
											0 - 使用或生成 Throwable, 仅仅是基于对象生成的警告而不是抛出对象(与 PHP 5 兼容)

	参数
	assertion
		断言。在 PHP 5 中,是一个用于执行的字符串或者用于测试的布尔值。在 PHP 7 中,可以是一个返回任何值的表达式, 它将被执行结果用于指明断言是否成功。
	description
		如果 assertion 失败了,选项 description 将会包括在失败信息里。
	exception
		在 PHP 7 中,第二个参数可以是一个 Throwable 对象,而不是一个字符串,如果断言失败且启用了 assert.exception 该对象将被抛出。

		将 zend.assertions 设置为 0:
			实例
			<?php
			ini_set('zend.assertions', 0);

			assert(true == false);
			echo 'Hi!';
			?>
			以上程序执行输出结果为:
			Hi!
			
			将 zend.assertions 设置为 1,assert.exception 设置为 1:
			实例
			<?php
			ini_set('zend.assertions', 1);
			ini_set('assert.exception', 1);

			assert(true == false);
			echo 'Hi!';
			?>
			以上程序执行输出结果为:
			Fatal error: Uncaught AssertionError: assert(true == false) in -:2
			Stack trace:
			#0 -(2): assert(false, 'assert(true == ...')
			#1 {main}
			  thrown in - on line 2

11、 PHP 7 use 语句

PHP 7 可以使用一个 use 从同一个 namespace 中导入类、函数和常量:
		<?php
		// PHP 7 之前版本需要使用多次 use
		use some\namespace\ClassA;
		use some\namespace\ClassB;
		use some\namespace\ClassC as C;

		use function some\namespace\fn_a;
		use function some\namespace\fn_b;
		use function some\namespace\fn_c;

		use const some\namespace\ConstA;
		use const some\namespace\ConstB;
		use const some\namespace\ConstC;

		// PHP 7+ 之后版本可以使用一个 use 导入同一个 namespace 的类
		use some\namespace\{ClassA, ClassB, ClassC as C};
		use function some\namespace\{fn_a, fn_b, fn_c};
		use const some\namespace\{ConstA, ConstB, ConstC};
		?>

12、 PHP 7 错误处理

PHP 7 改变了大多数错误的报告方式。不同于 PHP 5 的传统错误报告机制,现在大多数错误被作为 Error 异常抛出。
	这种 Error 异常可以像普通异常一样被 try / catch 块所捕获。如果没有匹配的 try / catch 块, 则调用异常处理函数(由 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。
	Error 类并不是从 Exception 类 扩展出来的,所以用 catch (Exception $e) { ... } 这样的代码是捕获不 到 Error 的。你可以用 catch (Error $e) { ... } 这样的代码,或者通过注册异常处理函数( set_exception_handler())来捕获 Error。
	Error 异常层次结构
		Error
			ArithmeticError
			AssertionError
			DivisionByZeroError
			ParseError
			TypeError

			<?php
			class MathOperations 
			{
			   protected $n = 10;

			   // 求余数运算,除数为 0,抛出异常
			   public function doOperation(): string
			   {
			      try {
			         $value = $this->n % 0;
			         return $value;
			      } catch (DivisionByZeroError $e) {
			         return $e->getMessage();
			      }
			   }
			}
			$mathOperationsObj = new MathOperations();
			print($mathOperationsObj->doOperation());
			?>
			以上程序执行输出结果为:
			Modulo by zero

13、PHP intdiv() 函数

PHP 7 新增加了 intdiv() 函数,接收两个参数,返回值为第一个参数除于第二个参数的值并取整。
		<?php
		echo intdiv(9,3),PHP_EOL;
		echo intdiv(10,3),PHP_EOL;
		echo intdiv(5,10),PHP_EOL;
		?>
			以上程序执行输出结果为:
				3
				3
				0

14、PHP 7 Session 选项

PHP 7 session_start() 函数可以接收一个数组作为参数,可以覆盖 php.ini 中 session 的配置项。
	这个特性也引入了一个新的 php.ini 设置(session.lazy_write), 默认情况下设置为 true,意味着 session 数据只在发生变化时才写入。
	除了常规的会话配置指示项, 还可以在此数组中包含 read_and_close 选项。如果将此选项的值设置为 TRUE, 那么会话文件会在读取完毕之后马上关闭, 因此,可以在会话数据没有变动的时候,避免不必要的文件锁。

		把 cache_limiter 设置为私有的,同时在阅读完 session 后立即关闭。
		<?php
		session_start([
		   'cache_limiter' => 'private',
		   'read_and_close' => true,
		]);
		?>
	
	小结
		php7 以前,我们使用 session 前都是要先代用 session_strat() 函数来初始化的,但这个函数是没有参数可以传的,session 的配置都在 php.ini 文件中。
		在 php7 后 session_start() 可以接受一个 array 作为参数, 用来覆盖 php.ini 文件中设置的会话配置选项。
		session_start([
		   'cache_limiter' => 'private', //在读取完毕会话数据之后马上关闭会话存储文件
		    'cookie_lifetime'=>3600,   //SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废
		    'read_and_close'=>true   //在读取完会话数据之后, 立即关闭会话存储文件,不做任何修改
		]);
		$_SESSION['name']='quan';
		echo $_SESSION['name'];

15、PHP 7 废弃特性

 PHP4 风格的构造函数
		在 PHP4 中类中的函数可以与类名同名,这一特性在 PHP7 中被废弃,同时会发出一个 E_DEPRECATED 错误。当方法名与类名相同,且类不在命名空间中,同时PHP5的构造函数(__construct)不存在时,会产生一个 E_DEPRECATED 错误。
			<?php
			class A {
			   function A() {
			      print('Style Constructor');
			   }
			}
			?>
			以上程序执行输出结果为:
			Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor in...


		以静态的方式调用非静态方法
			以静态的方式调用非静态方法,不再支持:
			<?php
			class A {
			   function b() {
			      print('Non-static call');
			   }
			}
			A::b();
			?>
			以上程序执行输出结果为:
			Deprecated: Non-static method A::b() should not be called statically in...
			Non-static call
					

		password_hash() 随机因子选项
			函数原 salt 量不再需要由开发者提供了。函数内部默认带有 salt 能力,无需开发者提供 salt 值。

		capture_session_meta SSL 上下文选项
			废弃了 "capture_session_meta" SSL 上下文选项。 在流资源上活动的加密相关的元数据可以通过 stream_get_meta_data() 的返回值访问。

16、PHP 7 移除的扩展

PHP 7+ 版本移除了以下扩展:
		ereg
		mssql
		mysql
		sybase_ct

17、PHP 7 移除的 SAPI

PHP 7+ 版本移除了以下 SAPI:
		aolserver
		apache
		apache_hooks
		apache2filter
		caudium
		continuity
		isapi
		milter
		nsapi
		phttpd
		pi3web
		roxen
		thttpd
		tux
		webjames

PHP XML

PHP XML Expat 解析器
	内建的expat解析器在php中处理mxl文档
	两种基本的XML解析器
		基于树的解析器:这种解析器把 XML 文档转换为树型结构。它分析整篇文档,并提供了对树中元素的访问,例如文档对象模型 (DOM)。
		基于事件的解析器:将 XML 文档视为一系列的事件。当某个具体的事件发生时,解析器会调用函数来处理。

	工作原理:
		1. 通过 xml_parser_create() 函数初始化 XML 解析器
		2. 创建配合不同事件处理程序的的函数
		3. 添加 xml_set_element_handler() 函数来定义,当解析器遇到开始和结束标签时执行哪个函数
		4. 添加 xml_set_character_data_handler() 函数来定义,当解析器遇到字符数据时执行哪个函数
		5. 通过 xml_parse() 函数来解析文件 "test.xml"
		6. 万一有错误的话,添加 xml_error_string() 函数把 XML 错误转换为文本说明
		7. 调用 xml_parser_free() 函数来释放分配给 xml_parser_create() 函数的内存
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值