Home >Backend Development >PHP Tutorial >Detailed explanation of new features from PHP5.2 to 5.6_PHP Tutorial
As of now (2014.2), the latest stable version of PHP is PHP5.5, but almost half of the users are still using PHP5.2 which is no longer maintained [note], and the remaining half of the users are Use PHP5.3 [Note].
Because of PHP's painful syntax that "gathers the strengths of hundreds of schools of thought" and the poor community atmosphere, many people are not interested in new versions and new features.
This article will introduce the new features added in PHP5.2 starting from PHP5.6.
<span>function</span> __autoload(<span>$classname</span><span>) { </span><span>require_once</span>("{<span>$classname</span>}.php"<span>) }</span>However, the use of this function is no longer recommended because there can only be one such __autoload() function in a project because PHP does not allow functions with duplicate names. But when you use some class libraries, you will inevitably need multiple autoload functions, so spl_autoload_register() replaces it:
spl_autoload_register(<span>function</span>(<span>$classname</span><span>) { </span><span>require_once</span>("{<span>$classname</span>}.php"<span>) });</span>spl_autoload_register() will register a function into the autoload function list. When an undefined class appears, SPL [Note] will call the registered autoload functions one by one in the reverse order of registration, which means you can use spl_autoload_register() to register Multiple autoload functions.
<span>//</span><span> 连接到服务器,选择数据库</span> <span>$conn</span> = <span>mysql_connect</span>("localhost", "user", "password"<span>); </span><span>mysql_select_db</span>("database"<span>); </span><span>//</span><span> 执行 SQL 查询</span> <span>$type</span> = <span>$_POST</span>['type'<span>]; </span><span>$sql</span> = "SELECT * FROM `table` WHERE `type` = {<span>$type</span>}"<span>; </span><span>$result</span> = <span>mysql_query</span>(<span>$sql</span><span>); </span><span>//</span><span> 打印结果</span> <span>while</span>(<span>$row</span> = <span>mysql_fetch_array</span>(<span>$result</span>,<span> MYSQL_ASSOC)) { </span><span>foreach</span>(<span>$row</span> <span>as</span> <span>$k</span> => <span>$v</span><span>) </span><span>print</span> "{<span>$k</span>}: {<span>$v</span>}\n"<span>; } </span><span>//</span><span> 释放结果集,关闭连接</span> <span>mysql_free_result</span>(<span>$result</span><span>); </span><span>mysql_close</span>(<span>$conn</span>);
为了能够让代码实现数据库无关,即一段代码同时适用于多种数据库(例如以上代码仅仅适用于MySQL),PHP 官方设计了 PDO.
<span>//</span><span> 连接到数据库</span> <span>$conn</span> = <span>new</span> PDO("mysql:host=localhost;dbname=database", "user", "password"<span>); </span><span>//</span><span> 预编译SQL, 绑定参数</span> <span>$query</span> = <span>$conn</span>->prepare("SELECT * FROM `table` WHERE `type` = :type"<span>); </span><span>$query</span>->bindParam("type", <span>$_POST</span>['type'<span>]); </span><span>//</span><span> 执行查询并打印结果</span> <span>foreach</span>(<span>$query</span>->execute() <span>as</span> <span>$row</span><span>) { </span><span>foreach</span>(<span>$row</span> <span>as</span> <span>$k</span> => <span>$v</span><span>) </span><span>print</span> "{<span>$k</span>}: {<span>$v</span>}\n"<span>; }</span>PDO 是官方推荐的,更为通用的数据库访问方式,如果你没有特殊需求,那么你最好学习和使用 PDO.
<span>//</span><span> 限制第一个参数为 MyClass, 第二个参数为可执行类型,第三个参数为数组</span> <span>function</span> MyFunction(MyClass <span>$a</span>, callable <span>$b</span>, <span>array</span> <span>$c</span><span>) { </span><span>//</span><span> ...</span> }
<span>$array</span> = <span>array</span>("key" => "value", "array" => <span>array</span>(1, 2, 3, 4<span>)); </span><span>$json</span> = json_encode(<span>$array</span><span>); </span><span>echo</span> "{<span>$json</span>}\n"<span>; </span><span>$object</span> = json_decode(<span>$json</span><span>); </span><span>print_r</span>(<span>$object</span>);输出:
{"key":"value","array":[1,2,3,4<span>]} stdClass </span><span>Object</span><span> ( [</span><span>key</span>] =><span> value [</span><span>array</span>] => <span>Array</span><span> ( [</span>0] => 1<span> [</span>1] => 2<span> [</span>2] => 3<span> [</span>3] => 4<span> ) )</span>值得注意的是 json_decode() 默认会返回一个对象而非数组,如果需要返回数组需要将第二个参数设置为 true.
<span>if</span><span>(isAuth()) </span><span>$authorized</span> = <span>true</span><span>; </span><span>if</span>(<span>$authorized</span><span>) </span><span>include</span>("page.php");这段代码在通过验证时,将 $authorized 设置为 true. 然后根据 $authorized 的值来决定是否显示页面.
<span>$func</span> = <span>function</span>(<span>$arg</span><span>) { </span><span>print</span> <span>$arg</span><span>; }; </span><span>$func</span>("Hello World");以上代码定义了一个匿名函数,并赋值给了 $func.
<span>function</span> arrayPlus(<span>$array</span>, <span>$num</span><span>) { </span><span>array_walk</span>(<span>$array</span>, <span>function</span>(&<span>$v</span>) <span>use</span>(<span>$num</span><span>){ </span><span>$v</span> += <span>$num</span><span>; }); }</span>上面的代码定义了一个 arrayPlus() 函数(这不是匿名函数), 它会将一个数组($array)中的每一项,加上一个指定的数字($num).
<span>class</span><span> A { </span><span>public</span> <span>function</span> __invoke(<span>$str</span><span>) { </span><span>print</span> "A::__invoke(): {<span>$str</span>}"<span>; } } </span><span>$a</span> = <span>new</span><span> A; </span><span>$a</span>("Hello World");输出毫无疑问是:
A::__invoke(): Hello World__callStatic() 则会在调用一个不存在的静态方法时被调用。
<?<span>php </span><span>//</span><span> 命名空间的分隔符是反斜杠,该声明语句必须在文件第一行。 // 命名空间中可以包含任意代码,但只有 **类, 函数, 常量** 受命名空间影响。</span> <span> namespace XXOO\Test; </span><span>//</span><span> 该类的完整限定名是 \XXOO\Test\A , 其中第一个反斜杠表示全局命名空间。</span> <span>class</span><span> A{} </span><span>//</span><span> 你还可以在已经文件中定义第二个命名空间,接下来的代码将都位于 \Other\Test2 .</span> <span> namespace Other\Test2; </span><span>//</span><span> 实例化来自其他命名空间的对象:</span> <span>$a</span> = <span>new</span><span> \XXOO\Test\A; </span><span>class</span><span> B{} </span><span>//</span><span> 你还可以用花括号定义第三个命名空间</span> <span> namespace Other { </span><span>//</span><span> 实例化来自子命名空间的对象:</span> <span>$b</span> = <span>new</span><span> Test2\B; </span><span>//</span><span> 导入来自其他命名空间的名称,并重命名, // 注意只能导入类,不能用于函数和常量。</span> <span>use</span> \XXOO\Test\A <span>as</span><span> ClassA }</span>
更多有关命名空间的语法介绍请参见官网 [注].
<span> spl_autoload_register( </span><span>function</span> (<span>$class</span><span>) { spl_autoload(</span><span>str_replace</span>("\\", "/", <span>$class</span><span>)); } );</span>当你实例化一个类 \XXOO\Test\A 的时候,这个类的完整限定名会被传递给 autoload 函数,autoload 函数将类名中的命名空间分隔符(反斜杠)替换为斜杠,并包含对应文件。
<span>class</span><span> A { </span><span>public</span> <span>function</span><span> callFuncXXOO() { </span><span>print</span> <span>$this</span>-><span>funcXXOO(); } </span><span>public</span> <span>function</span><span> funcXXOO() { </span><span>return</span> "A::funcXXOO()"<span>; } } </span><span>class</span> B <span>extends</span><span> A { </span><span>public</span> <span>function</span><span> funcXXOO() { </span><span>return</span> "B::funcXXOO"<span>; } } </span><span>$b</span> = <span>new</span><span> B; </span><span>$b</span>->callFuncXXOO();
输出是:
B::funcXXOO可以看到,当在 A 中使用 $this->funcXXOO() 时,体现了“虚函数”的机制,实际调用的是 B::funcXXOO().
<span>class</span><span> A { </span><span>static</span> <span>public</span> <span>function</span><span> callFuncXXOO() { </span><span>print</span> self::<span>funcXXOO(); } </span><span>static</span> <span>public</span> <span>function</span><span> funcXXOO() { </span><span>return</span> "A::funcXXOO()"<span>; } } </span><span>class</span> B <span>extends</span><span> A { </span><span>static</span> <span>public</span> <span>function</span><span> funcXXOO() { </span><span>return</span> "B::funcXXOO"<span>; } } </span><span>$b</span> = <span>new</span><span> B; </span><span>$b</span>->callFuncXXOO();
情况就没这么乐观了,输出是:
A::funcXXOO()
这是因为 self 的语义本来就是“当前类”,所以 PHP5.3 给 static 关键字赋予了一个新功能:后期静态绑定:
<span>class</span><span> A { </span><span>static</span> <span>public</span> <span>function</span><span> callFuncXXOO() { </span><span>print</span> <span>static</span>::<span>funcXXOO(); } </span><span>//</span><span> ...</span> <span> } </span><span>//</span><span> ...</span>这样就会像预期一样输出了:
B::funcXXOO
<span>$name</span> = "MyName"<span>; </span><span>echo</span> <<<<span> TEXT My name is </span>"{<span>$name</span>}".<span> TEXT;</span>Heredoc 以三个左尖括号开始,后面跟一个标识符(TEXT), 直到一个同样的顶格的标识符(不能缩进)结束。
<span>var_dump</span>(<<<<span>EOD Hello World EOD ); </span><span>class</span><span> A { </span><span>const</span> xx = <<<<span> EOD Hello World EOD; </span><span>public</span> <span>$oo</span> = <<<<span> EOD Hello World EOD; }</span>
Nowdoc 的行为像一个单引号字符串,不能在其中嵌入变量,和 Heredoc 唯一的区别就是,三个左尖括号后的标识符要以单引号括起来:
<span>$name</span> = "MyName"<span>; </span><span>echo</span> <<< 'TEXT'<span> My name is </span>"{<span>$name</span>}".<span> TEXT;</span>输出:
My name is "{<span>$name</span>}".
<span>define</span>("XOOO", "Value");新式风格:
<span>const</span> XXOO = "Value";const 形式仅适用于常量,不适用于运行时才能求值的表达式:
<span>//</span><span> 正确</span> <span>const</span> XXOO = 1234<span>; </span><span>//</span><span> 错误</span> <span>const</span> XXOO = 2 * 617;
<span>echo</span> <span>$a</span> ? <span>$a</span> : "No Value";可简写成
<span>echo</span> <span>$a</span> ?: "No Value";即如果省略三元运算符的第二个部分,会默认用第一个部分代替。
<span>require</span>("xxoo.phar"<span>); </span><span>require</span>("phar://xxoo.phar/xo/ox.php");更多信息请参见官网 [注].
<?<span>php </span><span>//</span><span> Code...</span> ?>通常就是上面的形式,除此之外还有一种简写形式:
<? <span>/*</span><span> Code... </span><span>*/</span> ?>还可以把
<?php <span>echo</span> <span>$xxoo</span>;?>简写成
<?= <span>$xxoo</span>;?>这种简写形式被称为 Short Open Tag, 在 PHP5.3 起被默认开启,在 PHP5.4 起总是可用。
<span>//</span><span> 原来的数组写法</span> <span>$arr</span> = <span>array</span>("key" => "value", "key2" => "value2"<span>); </span><span>//</span><span> 简写形式</span> <span>$arr</span> = ["key" => "value", "key2" => "value2"];
<span>//</span><span> Traits不能被单独实例化,只能被类所包含</span> <span> trait SayWorld { </span><span>public</span> <span>function</span><span> sayHello() { </span><span>echo</span> 'World!'<span>; } } </span><span>class</span><span> MyHelloWorld { </span><span>//</span><span> 将SayWorld中的成员包含进来</span> <span>use</span><span> SayWorld; } </span><span>$xxoo</span> = <span>new</span><span> MyHelloWorld(); </span><span>//</span><span> sayHello() 函数是来自 SayWorld 构件的</span> <span>$xxoo</span>->sayHello();
Traits还有很多神奇的功能,比如包含多个Traits, 解决冲突,修改访问权限,为函数设置别名等等。
php -S localhost:8000这样就在当前目录建立起了一个Web服务器,你可以通过 http://localhost:8000/ 来访问。
php -S localhost:8000 index.php这样一来,所有的请求都会由index.php来处理。
<span>$func</span> = "funcXXOO"<span>; A</span>::{<span>$func</span>}();新增在实例化时访问类成员的特征:
(<span>new</span> MyClass)->xxoo();新增支持对函数返回数组的成员访问解析(这种写法在之前版本是会报错的):
<span>print</span> func()[0];
<span>function</span><span> number10() { </span><span>for</span>(<span>$i</span> = 1; <span>$i</span> <= 10; <span>$i</span> += 1<span>) yield </span><span>$i</span><span>; }</span>该函数的返回值是一个数组:
<span>$array</span> =<span> [ [</span>1, 2, 3],<span> [</span>4, 5, 6],<span> ]; </span><span>foreach</span> (<span>$array</span> <span>as</span> <span>list</span>(<span>$a</span>, <span>$b</span>, <span>$c</span><span>)) </span><span>echo</span> "{<span>$a</span>} {<span>$b</span>} {<span>$c</span>}\n";结果:
1 2 3 4 5 6
<span>const</span> A = 2<span>; </span><span>const</span> B = A + 1<span>; </span><span>class</span><span> C { </span><span>const</span> STR = "hello"<span>; </span><span>const</span> STR2 = self::STR + ", world"<span>; }</span>允许常量作为函数参数默认值:
<span>function</span> func(<span>$arg</span> = C::STR2)
<span>function</span> add(...<span>$args</span><span>) { </span><span>$result</span> = 0<span>; </span><span>foreach</span>(<span>$args</span> <span>as</span> <span>$arg</span><span>) </span><span>$result</span> += <span>$arg</span><span>; </span><span>return</span> <span>$result</span><span>; }</span>同时可以在调用函数时,把数组展开为函数参数:
<span>$arr</span> = [2, 3<span>]; add(</span>1, ...<span>$arr</span><span>); </span><span>//</span><span> 结果为 6</span>
<span> namespace Name\Space { </span><span>const</span> FOO = 42<span>; </span><span>function</span> f() { <span>echo</span> <span>__FUNCTION__</span>."\n"<span>; } } namespace { </span><span>use</span> <span>const</span><span> Name\Space\FOO; </span><span>use</span> <span>function</span><span> Name\Space\f; </span><span>echo</span> FOO."\n"<span>; f(); }</span>(摘自http://www.thinkphp.cn/document/474.html) 更多详情关注官方手册:http://www.php.net/manual/zh/migration55.php