• PHP5.3、PHP5.4、PHP5.5、PHP5.6的新特性


    1. PHP5.3中的新特性

    1.1 支持命名空间(namespace)

    毫无疑问,命名空间是PHP5.3所带来的最重要的新特性。

    在PHP5.3中,可以用命名空间防止代码的冲突,命名空间的分隔符为 反斜线。

    1.2 通过static关键字,实现方法的延迟静态绑定

    在PHP中,我们可以在类中通过self关键字或者CLASS来判断或调用当前类。但有一个问题,如果我们是在子类中调用,得到的结果将是父类。因为在继承父类的时候,静态成员就已经被绑定了。例如:

    <?php    
    class A {    
        public static function who() {    
            echo __CLASS__;    
        }    
        public static function test() {    
            self::who();    
        }    
    }    
    class B extends A {    
        public static function who() {    
             echo __CLASS__;    
        }    
    }    
    B::test();

    上面代码的输出结果为:A。这和我们的预期结果不同。

    PHP5.3中增加了一个static关键字来引用当前类,即实现了延迟静态绑定:

    <?php    
    class A {    
        public static function who() {    
            echo __CLASS__;    
        }    
        public static function test() {    
            static::who(); // 这里实现了延迟的静态绑定    
        }    
    }    
    class B extends A {    
        public static function who() {    
             echo __CLASS__;    
        }    
    }    
    B::test();   
    // 输出:B

      

    1.3 支持goto语句

    多数计算机程序设计语言中都支持无条件转向语句goto,当程序执行到goto语句时,即转向由goto语句中的标号指出的程序位置继续执行。尽管goto语句有可能会导致程序流程不清晰,可读性减弱,但在某些情况下具有其独特的方便之处,例如中断深度嵌套的循环和 if 语句。

    <?php
    goto test;
    echo '1';
    
    test:
    echo '2';
    ?>
    // 运行时会输出 2

      

    1.4 支持闭包

    闭包(Closure)函数和Lambda函数的概念来自于函数编程领域。例如JavaScript 是支持闭包和 lambda 函数的最常见语言之一。

    在PHP5.3中,可以使用匿名函数或Lambda函数来定义一些临时使用(即用即弃型)的函数,以作为array_map()或array_walk()等函数的回调函数。

    1.5 新增两个魔术方法__callStatic()和__invoke()

    PHP中原本有一个魔术方法__call(),当调用类中某个不存在的方法时该魔术方法会被自动调用。新增的__callStatic()方法则只用于类的静态方法。当尝试调用类中不存在的静态方法时,__callStatic()魔术方法将被自动调用。

    此外,PHP5.3中还新增了__invoke()魔术方法。当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。 如:

    <?php
    class CallableClass 
    {
        function __invoke($x) {
            var_dump($x);
        }
    }
    $obj = new CallableClass;
    $obj(5);
    var_dump(is_callable($obj));
    ?> 
    /* 输出结果:
    int(5)
    bool(true)
    */

     

    1.6 新增Nowdoc语法结构

    就象 Heredoc 结构类似于双引号字符串,Nowdoc 结构是类似于单引号字符串的。Nowdoc 结构很象 heredoc 结构,但是 nowdoc 中不进行解析操作。故非常适合于传递一段PHP代码。

    <?php
    $str = <<<'EOD'
    Example of string
    spanning multiple lines
    using nowdoc syntax.
    EOD;
    echo $str;

    1.7 const 关键字可用来在类外定义常量

    <?php
    //PHP中定义常量通常是用这种方式  
    define("CONSTANT", "Hello world.");  
    //PHP5.3中的const关键字也支持在类外定义常量
    const CONSTANT = 'Hello World';  

    1.8 三元运算符可以简写为省略中间的部分

    原本格式为 expr1 ? expr2 : expr3 。

    如果expr1结果为True,则返回expr2的结果,否则返回expr3。

    PHP5.3新增了一种书写方式,可以省略中间部分,简写为 expr1 ?: expr3 ,当 expr1 为 TRUE 时返回 expr1,否则返回 expr3。

     

    1.9 支持动态访问类的静态成员或静态方法

    <?php
    class Test{    
        public static function testgo()    
        {    
             echo "gogo!";    
        }    
    }    
    $class = 'Test';    
    $action = 'testgo';    
    $class::$action();  //输出 "gogo!" 

    1.10 支持try…catch异常捕获的嵌套

    <?php
    class MyException extends Exception { }
    class Test {
        public function testing() {
            try {
                try {
                    throw new MyException('foo!');
                } catch (MyException $e) {
                    /* rethrow it */
                    throw $e;
                }
            } catch (Exception $e) {
                return $e->getMessage();
            }
        }
    }
    $foo = new Test;
    echo $foo->testing();
    // 输出:foo!
    ?>

    此外,PHP5.3还弃用了一些老版本的功能和函数,并用新的函数进行替代,这里不做赘述。

    2. PHP5.4中的新特性

    2.1 新增traits

    Traits提供了一种灵活的代码重用机制,既不像interface一样只能定义方法但不能实现,又不像class一样只能单继承。

    <?php
    // Traits不能被单独实例化,只能被类所包含
    trait SayWorld
    {    public function sayHello()
        {
            echo 'World!';
        }
    }
    class MyHelloWorld
    {
        // 将SayWorld中的成员包含进来
        use SayWorld;
    }
    $xxoo = new MyHelloWorld();
    // sayHello() 函数是来自 SayWorld 构件的
    $xxoo->sayHello();

     

    2.2 新增短数组语法

    <?php
    // 原来的数组写法
    $arr = array("key" => "value", "key2" => "value2");
    $arr = array(1,2,3,4);
    // 简写形式
    $arr = ["key" => "value", "key2" => "value2"];
    $arr = [1,2,3,4];

    2.3 支持对函数返回数组的成员访问解析

    <?php
    function myfunc() {
        return array('jack','rose');
    }
    // 以前的写法
    $arr = myfunc();
    echo $arr[0];
    // PHP5.4中,支持这样书写
    echo myfunc()[0];

    2.4 内置了用于开发的 CLI 模式的 web server

    //启动Web服务器
    php -S localhost:8000
    //启动时指定根目录
    php -S localhost:8000 -t /home/me/public_html/foo
    //使用路由(Router)脚本
    php -S localhost:8000 index.php //所有的请求都会由index.php来处理。

    2.5 支持在实例化时访问类成员

    (new Foo)->bar();

    2.6 session提供了上传进度支持

    通过 $_SESSION[“upload_progress_name”] 就可以获得当前文件上传的进度信息,结合 Ajax 就能很容易的实现上传进度条。

    2.7 让Json更懂中文(JSON_UNESCAPED_UNICODE)

    PHP5.4中的json_encode()函数的第二个参数,新增了一个常量JSON_UNESCAPED_UNICODE,可有效防止中文字符被转成Unicode编码格式。

    
    
    <?php
    echo json_encode(array("中文"));
    // 输出:["u4e2du6587"]
    echo json_encode(array("中文"), JSON_UNESCAPED_UNICODE);
    // 输出:["中文"]
    // 如果第二个参数指定为JSON_UNESCAPED_UNICODE,就不会将中文转换为Unicode编码格式 

    2.8 default_charset从ISO-8859-1变为UTF-8

    默认发送“Content-Type: text/html; charset=utf-8”,你再也不需要在HTML里写meta 标签了,也无需为UTF-8兼容而传送额外的header了。

    2.9 新增二进制直接量

    <?php
    $bin = bindec('1101'); //之前需要这样写
    $bin = 0b1101;
    echo $bin; // 输出13

    2.10 支持声明函数的参数类型

    <?php
    function foo(array $arr) {  // 声明foo函数的参数类型必须是array
        echo json_encode($arr);
    }
    // foo(1);   // 这里会报错,foo的参数类型必须是array
    foo(array(1,2,3));  // 正确

    此外,PHP5.4 废除了register_globals、 magic_quotes、 allow_call_time_pass_reference以及安全模式等等。

    在早期版本中,你可以在函数调用时,在参数前添加&修饰符来指明参数变量按引用传递。但在 PHP 5.4 中,该用法已被移除,你只需要在函数声明时指定按引用传递即可。

    
    
    <?php
    // 早期版本中,要想给一个函数传递一个引用,是这样写的
    /* function foo($a) {
        $a = 100;
    }
    $a = 3;
    foo(&$a);
    echo $a; */
    
    // 自PHP5.4以后,不能再像上面那样用,如果还想给一个函数传递一个引用,可以在声明时就指明
    function goo(&$a) {
        $a = 100;
    }
    $a = 3;
    goo($a);
    echo $a;  // 输出:100

     

    3. PHP5.5中的新特性

    3.1 新增Generator生成器yield

    yield关键字用于当函数需要返回一个迭代器的时候,逐个返回值。

    <?php
    function number10()
    {
        for($i = 1; $i <= 10; $i += 1) {
            yield $i;
        }
    }
    $generatorObj = number10();   // 是一个对象
    // var_dump($generatorObj);
    foreach ($generatorObj as $i) {
        echo $i;
    }
    // 输出:12345678910

    3.2 try…catch 新增了finally

    这和java中的finally一样,经典的try … catch … finally 三段式异常处理。

    不论是否捕获到异常,finally中的代码都会执行。只要finally中有return语句,就以finally的返回值为准;否则,以try或者catch中的返回值为准。

    <?php
    function foo() {
        try {
            echo 'success!'.PHP_EOL;
            throw new Exception('exception!');
            echo 'failed!'.PHP_EOL;
            return 1;
        } catch (Exception $e) {
            echo $e->getMessage().PHP_EOL;
            return 2;
        } finally {
            echo "finally!".PHP_EOL;
            return 3;
        }
    }
    echo foo();
    // 输出:success! exception! finally! 3

    3.3 foreach中支持嵌套list()结构

    对二维数组进行遍历,之前可能需要使用两个foreach,现在只需要使用foreach + list了,但是需确保个数一致。

    <?php
    $arr = [   
        [1, 2, 3],
        [4, 5, 6]
    ];
    foreach ($arr as list($a, $b, $c)) {
        echo $a.$b.$c.'<br>';
    }
    /* 
    输出:
    123
    456 
    */

    3.4 empty() 支持传入表达式,而不仅是一个变量

    <?php
    function always_false() {
        return false;
    }
    if (empty(always_false())) {
        echo 'This will be printed.';
    }

    3.5 非变量array或string也能支持下标访问

    <?php
    echo array(1, 2, 3)[0];  
    echo [1, 2, 3][0];  
    echo "foobar"[0];  
    // 输出:11f

    3.6 新增密码哈希API

    缺点是缺乏互操作性,在需要和其他语言对接时会比较麻烦。

    <?php 
    $passwd = '123456';
    // 加密,将原密码生成一个hash散列值
    $hashKey = password_hash($passwd, PASSWORD_DEFAULT);  // 每次刷新,生成的hash散列值都不一样
    echo $hashKey,'<br>';
    //输出结果类似于:$2y$10$Z215AkvS1sFVi4syS9no7eGXCa9mBwiH1BviaQzy4Dh4RvL2/JtpK
    
    // 验证,利用hash散列值对原密码进行验证
    if(password_verify($passwd, $hashKey)) { 
        echo "密码正确!";
    } else {  
        echo "密码错误!";
    }

     

    3.7 新增 boolval() 函数

    PHP已经实现了strval、intval和floatval的函数来进行强制类型转换。为了达到一致性,PHP5.5新增了boolval函数。

     

    3.8 新增 array_column() 函数

    可用来返回二维数组中指定的列。

    <?php 
    $records = array(
        array('id' => 2135,'name' => 'John'),
        array('id' => 3245,'name' => 'Smith'),
        array('id' => 5342,'name' => 'Peter')
    );
    
    //从结果集中取出 name 列
    $names = array_column($records, 'name');
    print_r($names);
    
    //从结果集中取出 name 列,并用相应的 id 作为键
    $names = array_column($records, 'name', 'id');
    print_r($names);

     

    4. PHP5.6中的新特性

    4.1 增强了const 常量

    在PHP5.6之前,关键字const定义常量时,只能使用固定的值,且值的类型只能是标量。

    在PHP5.6中,对const常量进行了增强,允许常量计算,允许使用包含数字、字符串字面值和常量的表达式结果来定义const常量。常量的值也可以为一个数组,但不能是变量。

    <?php 
    const A = 2;
    const B = A + 1;
    const C = "Hello"." Wolrd!";
    const D = array(1, 2, 3);
    define('E', 100);
    var_dump(A, B, C ,D, E);
    // 输出:int(2) int(3) string(12) "Hello Wolrd!" array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } int(100) 

    4.2 支持使用 … 运算符定义变长参数函数

    现在可以不依赖 func_get_args(), 使用 … 运算符来实现变长参数函数。

    <?php
    function test(...$args)
    {
        var_dump($args);
    }
    test(1,2,3);
    // 输出:array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 

    4.3 支持使用 ** 进行幂运算

    加入右连接运算符 * 来进行幂运算。 同时还支持简写的 *= 运算符,表示进行幂运算并赋值。

    <?php
    printf(2 ** 3); // 8
    $a = 2;
    $a **= 3;
    printf($a);  // 8

    4.4 命名空间 use 操作符支持函数和常量的导入

    use 运算符可以导入外部(其他命名空间)的函数和常量,对应的结构为 use function 和 use const。

    <?php
    namespace NameSpace {  
        const FOO = 42;  
        function f() { return __FUNCTION__; }  
    }  
    
    namespace {  
        use const NameSpaceFOO;  
        use function NameSpacef;  
    
        echo '常量:'.FOO;  
        echo '<br>';
        echo '函数:'.f();  
    } 
    /*
    输出:
    常量:42
    函数:NameSpacef
    */

    4.5 新增参数解包功能

    在调用函数的时候,通过 … 操作符可以把数组或者可遍历对象解包到参数列表,这和Ruby等语言中的扩张(splat)操作符类似。

    <?php
    function add($a, $b, $c) {  
        return $a + $b + $c;  
    }  
    $arr = [2, 3];  
    echo add(1, ...$arr);  // 输出:6
    4.6 支持大文件上传
    可以上传超过2G的大文件。
    
    4.7 php://input 可以被复用
    php://input 是个可以访问请求的原始数据的只读流。 在 PHP 5.6 之前 php://input 打开的数据流只能读取一次; 数据流不支持 seek 操作。 不过,现在依赖于 SAPI 的实现,请求体数据被保存的时候, 它可以打开另一个 php://input 数据流并重新读取。 通常情况下,这种情况只是针对 POST 请求,而不是其他请求方式。
    
    
  • 相关阅读:
    深入浅出 JVM ClassLoader
    JVM 线上故障排查基本操作
    深入浅出 JVM GC(3)
    MyBatis 源码分析系列文章合集
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析系列文章导读
  • 原文地址:https://www.cnblogs.com/pengyunjing/p/8111741.html
Copyright © 2020-2023  润新知