Maison > développement back-end > tutoriel php > Les différences entre les différentes versions de php

Les différences entre les différentes versions de php

不言
Libérer: 2023-03-23 22:42:02
original
6491 Les gens l'ont consulté

Le contenu présenté dans cet article concerne les différences entre les différentes versions de PHP. Il a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

PHP5. 2 Auparavant : chargement automatique, PDO et MySQLi, contraintes de type
PHP5.2 : support JSON
PHP5.3 : fonctionnalités obsolètes, fonctions anonymes, nouvelles méthodes magiques, espaces de noms , liaison statique tardive, Heredoc et Nowdoc, const, opérateur ternaire, Phar
PHP5.4 : Short Open Tag, abréviation de tableau, Traits, serveur Web intégré, détails modifiés
PHP5.5 : rendement, list() est utilisé pour foreach, modifications détaillées
PHP5.6 : amélioration constante, paramètres de fonction variables, amélioration de l'espace de noms
PHP 7.0 .2 Alpha Utilise la nouvelle version du moteur ZendEngine, apportant de nombreuses nouvelles fonctionnalités

1. Avant PHP5.2 (avant 2006)
Au fait, permettez-moi de vous présenter les fonctionnalités qui sont déjà apparues dans PHP5.2 mais qui méritent d'être présentées.
autoload
Tout le monde connaît peut-être la fonction __autoload(). Si cette fonction est définie, alors lorsqu'une classe non définie est utilisée dans le code, la fonction sera appelée. fichier d'implémentation de classe dans cette fonction, tel que :

Le code est le suivant :

function __autoload($classname)
{
    require_once("{$classname}.php")
}
Copier après la connexion


Mais cette fonction n'est plus recommandée car il ne peut y avoir qu'une seule de ces fonctions __autoload() dans un projet car PHP n'autorise pas les fonctions avec des noms en double. Mais lorsque vous utilisez certaines bibliothèques de classes, vous aurez inévitablement besoin de plusieurs fonctions de chargement automatique, donc spl_autoload_register() le remplace :

Le code est le suivant :

spl_autoload_register(function($classname)
{
    require_once("{$classname}.php")
});
Copier après la connexion


spl_autoload_register() enregistrera une fonction dans la liste des fonctions de chargement automatique Lorsqu'une classe non définie apparaît, SPL [Note] appellera les fonctions de chargement automatique enregistrées une par une dans l'ordre inverse de l'enregistrement, ce qui signifie que vous pouvez utiliser spl_autoload_register() pour enregistrer plusieurs fonctions de chargement automatique.
Remarque : SPL : la bibliothèque PHP standard, la bibliothèque PHP standard, est conçue pour être utilisée. Pour résoudre certains problèmes classiques (comme la structure des données).

PDO et MySQLi
sont PHP Data Object, PHP data object , Il s'agit de la nouvelle interface d'accès aux bases de données de PHP.
Selon le style traditionnel, l'accès à la base de données MySQL devrait ressembler à ceci :

Le code est le suivant :

// 连接到服务器,选择数据库
$conn = mysql_connect("localhost", "user", "password");
mysql_select_db("database");
// 执行 SQL 查询
$type = $_POST['type'];
$sql = "SELECT * FROM `table` WHERE `type` = {$type}";
$result = mysql_query($sql);
// 打印结果
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
    foreach($row as $k => $v)
        print "{$k}: {$v}\n";
}
// 释放结果集,关闭连接
mysql_free_result($result);
mysql_close($conn);
Copier après la connexion


Afin de rendre le code indépendant de la base de données, c'est-à-dire qu'un morceau de code est applicable à plusieurs bases de données en même temps (par exemple, le code ci-dessus n'est applicable qu'à MySQL), PHP officiellement conçu PDO.
De plus, PDO Il fournit également plus de fonctions, telles que :

1. 🎜>2. Précompilation SQL (préparer), syntaxe d'espace réservé
3. Efficacité d'exécution plus élevée, comme recommandation officielle, avec une optimisation spéciale des performances
4. Prend en charge la plupart des bases de données SQL, pas besoin de modifier le code lors du changement de base de données.

Ce qui précède Le code implémenté à l'aide de PDO sera comme ceci :

代码如下:

// 连接到数据库
$conn = new PDO("mysql:host=localhost;dbname=database", "user", "password");
// 预编译SQL, 绑定参数
$query = $conn->prepare("SELECT * FROM `table` WHERE `type` = :type");
$query->bindParam("type", $_POST['type']);
// 执行查询并打印结果
foreach($query->execute() as $row)
{
    foreach($row as $k => $v)
        print "{$k}: {$v}\n";
}
Copier après la connexion


PDO 是官方推荐的,更为通用的数据库访问方式,如果你没有特殊需求,那么你最好学习和使用 PDO.
但如果你需要使用 MySQL 所特有的高级功能,那么你可能需要尝试一下 MySQLi, 因为 PDO 为了能够同时在多种数据库上使用,不会包含那些 MySQL 独有的功能。

MySQLi 是 MySQL 的增强接口,同时提供面向过程和面向对象接口,也是目前推荐的 MySQL 驱动,旧的C风格 MySQL 接口将会在今后被默认关闭。
MySQLi 的用法和以上两段代码相比,没有太多新概念,在此不再给出示例,可以参见 PHP 官网文档 [注]。

注:http://www.php.net/manual/en/mysqli.quickstart.php

类型约束
通过类型约束可以限制参数的类型,不过这一机制并不完善,目前仅适用于类和 callable(可执行类型) 以及 array(数组), 不适用于 string 和 int.

代码如下:

// 限制第一个参数为 MyClass, 第二个参数为可执行类型,第三个参数为数组
function MyFunction(MyClass $a, callable $b, array $c)
{
    // ...
}
Copier après la connexion



PHP5.2(2006-2011):JSON 支持

包括 json_encode(), json_decode() 等函数,JSON 算是在 Web 领域非常常用的数据交换格式,可以被 JS 直接支持,JSON 实际上是 JS 语法的一部分。
JSON 系列函数,可以将 PHP 中的数组结构与 JSON 字符串进行转换:

代码如下:

$array = ["key" => "value", "array" => [1, 2, 3, 4]];
$json = json_encode($array);echo "{$json}\n";
$object = json_decode($json);print_r($object);
Copier après la connexion



输出:

代码如下:

{"key":"value","array":[1,2,3,4]}
stdClass Object
(
    [key] => value
    [array] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
        )
)
Copier après la connexion



值得注意的是 json_decode() 默认会返回一个对象而非数组,如果需要返回数组需要将第二个参数设置为 true.

PHP5.3(2009-2012)
PHP5.3 算是一个非常大的更新,新增了大量新特征,同时也做了一些不向下兼容的修改。
【PHP5.3弃用的功能】:以下几个功能被弃用,若在配置文件中启用,则 PHP 会在运行时发出警告。

Register Globals
这是 php.ini 中的一个选项(register_globals), 开启后会将所有表单变量($_GET和$_POST)注册为全局变量.
看下面的例子:

代码如下:

if(isAuth())    
$authorized = true;if($authorized)    
include("page.php");
Copier après la connexion


这段代码在通过验证时,将 $authorized 设置为 true. 然后根据 $authorized 的值来决定是否显示页面.
但由于并没有事先把 $authorized 初始化为 false, 当 register_globals 打开时,可能访问 /auth.php?authorized=1 来定义该变量值,绕过身份验证。
该特征属于历史遗留问题,在 PHP4.2 中被默认关闭,在 PHP5.4 中被移除。

Magic Quotes

对应 php.ini 中的选项 magic_quotes_gpc, 这个特征同样属于历史遗留问题,已经在 PHP5.4 中移除。
该特征会将所有用户输入进行转义,这看上去不错,在第一章我们提到过要对用户输入进行转义。
但是 PHP 并不知道哪些输入会进入 SQL , 哪些输入会进入 Shell, 哪些输入会被显示为 HTML, 所以很多时候这种转义会引起混乱。

Safe Mode
很多虚拟主机提供商使用 Safe Mode 来隔离多个用户,但 Safe Mode 存在诸多问题,例如某些扩展并不按照 Safe Mode 来进行权限控制。
PHP官方推荐使用操作系统的机制来进行权限隔离,让Web服务器以不同的用户权限来运行PHP解释器,请参见第一章中的最小权限原则.

【PHP5.3的新增、改进】

匿名函数
也叫闭包(Closures), 经常被用来临时性地创建一个无名函数,用于回调函数等用途。

代码如下:

$func = function($arg)
{
    print $arg;
};
$func("Hello World");
Copier après la connexion


以上代码定义了一个匿名函数,并赋值给了 $func.
可以看到定义匿名函数依旧使用 function 关键字,只不过省略了函数名,直接是参数列表。
然后我们又调用了 $func 所储存的匿名函数。
匿名函数还可以用 use 关键字来捕捉外部变量:

代码如下:

function arrayPlus($array, $num)
{
    array_walk($array, function(&$v) use($num){
        $v += $num;
    });
}
Copier après la connexion


上面的代码定义了一个 arrayPlus() 函数(这不是匿名函数), 它会将一个数组($array)中的每一项,加上一个指定的数字($num).
在 arrayPlus() 的实现中,我们使用了 array_walk() 函数,它会为一个数组的每一项执行一个回调函数,即我们定义的匿名函数。
在匿名函数的参数列表后,我们用 use 关键字将匿名函数外的 $num 捕捉到了函数内,以便知道到底应该加上多少。

魔术方法:__invoke(), __callStatic()
PHP 的面向对象体系中,提供了若干“魔术方法”,用于实现类似其他语言中的“重载”,如在访问不存在的属性、方法时触发某个魔术方法。
随着匿名函数的加入,PHP 引入了一个新的魔术方法 __invoke().
该魔术方法会在将一个对象作为函数调用时被调用:

代码如下:

class A
{
    public function __invoke($str)
    {
        print "A::__invoke(): {$str}";
    }
}
$a = new A;
$a("Hello World");
Copier après la connexion

输出毫无疑问是:

代码如下:

A::__invoke(): Hello World

__callStatic() 则会在调用一个不存在的静态方法时被调用。
Copier après la connexion

命名空间
PHP的命名空间有着前无古人后无来者的无比蛋疼的语法:

代码如下:

<?php
// 命名空间的分隔符是反斜杠,该声明语句必须在文件第一行。
// 命名空间中可以包含任意代码,但只有 **类, 函数, 常量** 受命名空间影响。
namespace XXOO\Test;
// 该类的完整限定名是 \XXOO\Test\A , 其中第一个反斜杠表示全局命名空间。
class A{}
// 你还可以在已经文件中定义第二个命名空间,接下来的代码将都位于 \Other\Test2 .
namespace Other\Test2;
// 实例化来自其他命名空间的对象:
$a = new \XXOO\Test\A;
class B{}
// 你还可以用花括号定义第三个命名空间
namespace Other {
    // 实例化来自子命名空间的对象:
    $b = new Test2\B;
    // 导入来自其他命名空间的名称,并重命名,
    // 注意只能导入类,不能用于函数和常量。
    use \XXOO\Test\A as ClassA
}
Copier après la connexion


更多有关命名空间的语法介绍请参见官网 [注].
命名空间时常和 autoload 一同使用,用于自动加载类实现文件:

spl_autoload_register(
    function ($class) {
        spl_autoload(str_replace("\\", "/", $class));
    }
);
Copier après la connexion

当你实例化一个类 \XXOO\Test\A 的时候,这个类的完整限定名会被传递给 autoload 函数,autoload 函数将类名中的命名空间分隔符(反斜杠)替换为斜杠,并包含对应文件。
这样可以实现类定义文件分级储存,按需自动加载。
注:http://www.php.net/manual/zh/language.namespaces.php

后期静态绑定
PHP 的 OPP 机制,具有继承和类似虚函数的功能,例如如下的代码:

代码如下:

class A
{
    public function callFuncXXOO()
    {
        print $this->funcXXOO();
    }
    public function funcXXOO()
    {
        return "A::funcXXOO()";
    }
}
class B extends A
{
    public function funcXXOO()
    {
        return "B::funcXXOO";
    }
}
$b = new B;
$b->callFuncXXOO();
Copier après la connexion

输出是:

代码如下:

B::funcXXOO
Copier après la connexion
Copier après la connexion



可以看到,当在 A 中使用 $this->funcXXOO() 时,体现了“虚函数”的机制,实际调用的是 B::funcXXOO().
然而如果将所有函数都改为静态函数:

代码如下:

class A
{
    static public function callFuncXXOO()
    {
        print self::funcXXOO();
    }
    static public function funcXXOO()
    {
        return "A::funcXXOO()";
    }
}
class B extends A
{
    static public function funcXXOO()
    {
        return "B::funcXXOO";
    }
}
$b = new B;
$b->callFuncXXOO();
Copier après la connexion

情况就没这么乐观了,输出是:

代码如下:

A::funcXXOO()
Copier après la connexion



这是因为 self 的语义本来就是“当前类”,所以 PHP5.3 给 static 关键字赋予了一个新功能:后期静态绑定:

代码如下:

class A
{
    static public function callFuncXXOO()
    {
        print static::funcXXOO();
    }
    // ...
}
// ...
Copier après la connexion

这样就会像预期一样输出了:

代码如下:

B::funcXXOO
Copier après la connexion
Copier après la connexion


Heredoc 和 Nowdoc

PHP5.3 对 Heredoc 以及 Nowdoc 进行了一些改进,它们都用于在 PHP 代码中嵌入大段字符串。
Heredoc 的行为类似于一个双引号字符串:

代码如下:

$name = "MyName";
echo <<< TEXT
My name is "{$name}".
TEXT;
Copier après la connexion


Heredoc 以三个左尖括号开始,后面跟一个标识符(TEXT), 直到一个同样的顶格的标识符(不能缩进)结束。
就像双引号字符串一样,其中可以嵌入变量。

Heredoc 还可以用于函数参数,以及类成员初始化:

代码如下:

var_dump(<<<EOD
Hello World
EOD
);
class A
{
    const xx = <<< EOD
Hello World
EOD;
    public $oo = <<< EOD
Hello World
EOD;
}
Copier après la connexion


Nowdoc 的行为像一个单引号字符串,不能在其中嵌入变量,和 Heredoc 唯一的区别就是,三个左尖括号后的标识符要以单引号括起来:

代码如下:

$name = "MyName";
echo <<< &#39;TEXT&#39;
My name is "{$name}".
TEXT;
Copier après la connexion

输出:

代码如下:

My name is "{$name}".
Copier après la connexion


用 const 定义常量

PHP5.3 起同时支持在全局命名空间和类中使用 const 定义常量。
旧式风格:

代码如下:

define("XOOO", "Value");
Copier après la connexion



新式风格:
const XXOO = "Value";
const 形式仅适用于常量,不适用于运行时才能求值的表达式:

代码如下:

// 正确
const XXOO = 1234;
// 错误
const XXOO = 2 * 617;
Copier après la connexion


三元运算符简写形式
旧式风格:

代码如下:

echo $a ? $a : "No Value";
Copier après la connexion



可简写成:

代码如下:

echo $a ?: "No Value";
Copier après la connexion



即如果省略三元运算符的第二个部分,会默认用第一个部分代替。

Phar

Phar即PHP Archive, 起初只是Pear中的一个库而已,后来在PHP5.3被重新编写成C扩展并内置到 PHP 中。
Phar用来将多个 .php 脚本打包(也可以打包其他文件)成一个 .phar 的压缩文件(通常是ZIP格式)。
目的在于模仿 Java 的 .jar, 不对,目的是为了让发布PHP应用程序更加方便。同时还提供了数字签名验证等功能。
.phar 文件可以像 .php 文件一样,被PHP引擎解释执行,同时你还可以写出这样的代码来包含(require) .phar 中的代码:

代码如下:

require("xxoo.phar");
require("phar://xxoo.phar/xo/ox.php");
Copier après la connexion


更多信息请参见官网 [注].
注:http://www.php.net/manual/zh/phar.using.intro.php

PHP5.4(2012-2013)

Short Open Tag
Short Open Tag 自 PHP5.4 起总是可用。
在这里集中讲一下有关 PHP 起止标签的问题。即:

代码如下:

<?php
// Code...
?>
Copier après la connexion



通常就是上面的形式,除此之外还有一种简写形式:

代码如下:


还可以把

代码如下:

<?php echo $xxoo;?>
Copier après la connexion


简写成:

代码如下:

<?= $xxoo;?>
Copier après la connexion



这种简写形式被称为 Short Open Tag, 在 PHP5.3 起被默认开启,在 PHP5.4 起总是可用。
使用这种简写形式在 HTML 中嵌入 PHP 变量将会非常方便。

对于纯 PHP 文件(如类实现文件), PHP 官方建议顶格写起始标记,同时 省略 结束标记。
这样可以确保整个 PHP 文件都是 PHP 代码,没有任何输出,否则当你包含该文件后,设置 Header 和 Cookie 时会遇到一些麻烦 [注].

注:Header 和 Cookie 必须在输出任何内容之前被发送。

数组简写形式
这是非常方便的一项特征!

代码如下:

// 原来的数组写法
$arr = array("key" => "value", "key2" => "value2");
// 简写形式
$arr = ["key" => "value", "key2" => "value2"];
Copier après la connexion


Traits
所谓Traits就是“构件”,是用来替代继承的一种机制。PHP中无法进行多重继承,但一个类可以包含多个Traits.

代码如下:

// Traits不能被单独实例化,只能被类所包含
trait SayWorld
{
    public function sayHello()
    {
        echo &#39;World!&#39;;
    }
}
class MyHelloWorld
{
    // 将SayWorld中的成员包含进来
    use SayWorld;
}
$xxoo = new MyHelloWorld();
// sayHello() 函数是来自 SayWorld 构件的
$xxoo->sayHello();
Copier après la connexion


Traits还有很多神奇的功能,比如包含多个Traits, 解决冲突,修改访问权限,为函数设置别名等等。
Traits中也同样可以包含Traits. 篇幅有限不能逐个举例,详情参见官网 [注].
注:http://www.php.net/manual/zh/language.oop5.traits.php

内置 Web 服务器
PHP从5.4开始内置一个轻量级的Web服务器,不支持并发,定位是用于开发和调试环境。
在开发环境使用它的确非常方便。

代码如下:

php -S localhost:8000
Copier après la connexion


这样就在当前目录建立起了一个Web服务器,你可以通过 http://localhost:8000/ 来访问。
其中localhost是监听的ip,8000是监听的端口,可以自行修改。

很多应用中,都会进行URL重写,所以PHP提供了一个设置路由脚本的功能:

代码如下:

php -S localhost:8000 index.php
Copier après la connexion



这样一来,所有的请求都会由index.php来处理。
你还可以使用 XDebug 来进行断点调试。

细节修改
PHP5.4 新增了动态访问静态方法的方式:

代码如下:

$func = "funcXXOO";
A::{$func}();
Copier après la connexion


新增在实例化时访问类成员的特征:

代码如下:

(new MyClass)->xxoo();
Copier après la connexion


新增支持对函数返回数组的成员访问解析(这种写法在之前版本是会报错的):

代码如下:

print func()[0];

PHP5.5(2013起)

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

代码如下:

function number10()
{
    for($i = 1; $i <= 10; $i += 1)
        yield $i;
}
Copier après la connexion



该函数的返回值是一个数组:

代码如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copier après la connexion


list() 用于 foreach
可以用 list() 在 foreach 中解析嵌套的数组:

代码如下:

$array = [
    [1, 2, 3],
    [4, 5, 6],
];
foreach ($array as list($a, $b, $c))
    echo "{$a} {$b} {$c}\n";
Copier après la connexion

结果:

代码如下:

1 2 3
4 5 6
Copier après la connexion



细节修改
不推荐使用 mysql 函数,推荐使用 PDO 或 MySQLi, 参见前文。
不再支持Windows XP.
可用 MyClass::class 取到一个类的完整限定名(包括命名空间)。
empty() 支持表达式作为参数。
try-catch 结构新增 finally 块。

PHP5.6

更好的常量
定义常量时允许使用之前定义的常量进行计算:

代码如下:

const A = 2;
const B = A + 1;
class C
{
    const STR = "hello";
    const STR2 = self::STR + ", world";
}
Copier après la connexion


允许常量作为函数参数默认值:

代码如下:

function func($arg = C::STR2)
Copier après la connexion


更好的可变函数参数
用于代替 func_get_args()

代码如下:

function add(...$args)
{
    $result = 0;
    foreach($args as $arg)
        $result += $arg;
    return $result;
}
Copier après la connexion



同时可以在调用函数时,把数组展开为函数参数:

代码如下:

$arr = [2, 3];
add(1, ...$arr);
Copier après la connexion



// 结果为 6
命名空间
命名空间支持常量和函数:

代码如下:

namespace Name\Space {
    const FOO = 42;
    function f() { echo __FUNCTION__."\n"; }
}
namespace {
    use const Name\Space\FOO;
    use function Name\Space\f;
    echo FOO."\n";
    f();
}
Copier après la connexion

php7的一些特性
性能提升:PHP7比PHP5.6性能提升了两倍。 Improved performance: PHP 7 is up to twice as fast as PHP 5.6
全面一致的64位支持。 Consistent 64-bit support
以前的许多致命错误,现在改成抛出异常。Many fatal errors are now Exceptions
移除了一些老的不在支持的SAPI(服务器端应用编程端口)和扩展。Removal of old and unsupported SAPIs and extensions
新增了空接合操作符。The null coalescing operator (??)
新增加了结合比较运算符。Combined comparison Operator (<=>)
新增加了函数的返回类型声明。Return Type Declarations
新增加了标量类型声明。Scalar Type Declarations
新增加匿名类。Anonymous Classes
打破一切

PHP7要打破一切。 PHP开发人员应该接受打破版本之间向下兼容的定律。只要不允许大量的向后兼容,PHP7将是一个高度尊重的语言。
  1、创建一个具体的核心语言 删除所有库方法,并保持在对象集中的核心方法。 您应该能够编写无需任何外部库或扩展PHP7和对基本输入/输出,字符串处理和数学一个很好的完整的语言。库以外的任何应该通过批准扩展。
  2、 一切都当作一个对象 以从Ruby,Smalltalk和(主要)的Java对象,并把它一切当作对象。 整数是对象,字符串是对象,他们每个人都可以操作的方法, 我不相信PHP需要的Ruby和Smalltalk在对象之间传递彼此讯息的观念,而调用对象的方法才是最好的。
  3、一致的命名方法和类 由于PHP的最大的抱怨之一是不断要检查,(needle,haystack) 或(haystack, needle),或some_function(),或function_some(),或someFunction(),一个一致的格式需要制定。
  4、让事情严格尝试传递到一个方法浮动字符串? 这是一个警告。
  5、 一切是Unicode 在PHP6中的所有字符串都是Unicode,这很好,我主张PHP7也应该保持。
  6、中央启动点 创建一个主类或初始化,所有代码执行源于此。
  7、清理C代码我不是一个C的专家,但如果你比较了解Ruby的C代码到PHP的C代码,可以很容易地了解了PHP与Ruby的内部。 我非常熟悉PHP,所以我自己的写扩展更容易。
  8、摆脱eval() eval()是邪恶的。 如果你正在使用它,那么这是一个错的主意:这将打破PHPUnit,抛弃它从现在开始。
  9、支持操作符重载 因为一切都是对象,开发者只需掌握操作对象的方法即可。

  10、允许的方法签名


原文转至:https://blog.csdn.net/chenmoimg_/article/details/61195197

相关推荐:

php版本切换的详细过程和线上Linux环境下常见php-fpm常见问题


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal