ホームページ  >  記事  >  バックエンド開発  >  PHP7.X の各バージョンの新機能をすぐに理解する

PHP7.X の各バージョンの新機能をすぐに理解する

青灯夜游
青灯夜游転載
2022-07-27 14:54:532851ブラウズ

この記事では、PHP7 の各バージョンの新機能について説明します。

PHP7.X の各バージョンの新機能をすぐに理解する

ご存知のとおり、PHP は常に更新と拡張が行われており、バージョンごとにパフォーマンスが向上しています。次に、PHP7 の機能について説明します。 。各バージョンの特徴に合わせて説明していきます。

  1. PHP7.0 の新機能
  2. PHP7.1 の新機能
  3. 新機能PHP7.2 の機能
  4. PHP7.3 の新機能
  5. PHP7.4 の新機能

PHP7 .0 の新機能

1. スカラー型の宣言

スカラー型の宣言には、必須モード (デフォルト) と厳密モードの 2 つのモードがあります。次の型パラメータを (強制モードまたは厳密モードのいずれかで) 使用できるようになりました: String (<span class="type">string</span>)、Integer (<em>int</em>)、Float (float) 、およびブール値 (bool)。これらは、PHP5 で導入された他の型 (クラス名、インターフェイス、配列 および コールバック型 ) を拡張します。

PHP スカラーには、文字列 (<span class="type">string</span>)、整数 (<em>int</em>)、浮動小数点数 (##) が含まれます。 #float<span class="type"></span>)、およびブール値 (bool<em></em>)。

たとえば、以下では仮パラメータが整数であるパラメータを定義します。 (正しいものは次のとおりです)

<?php
//Enter your code here, enjoy!
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}
 
var_dump(sumOfInts(2, &#39;3&#39;, 4.1));

出力:

int(9)

たとえば、以下では仮パラメータが整数であるパラメータを定義します。 (エラー内容は以下の通り)

<?php
//Enter your code here, enjoy!
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}
 
var_dump(sumOfInts(2, &#39;error&#39;, 4.1));//参数里面有字符串,我们声明的是整数

出力エラーメッセージ:

<br />
<b>Fatal error</b>:  Uncaught TypeError: Argument 2 passed to sumOfInts() must be of the type integer, string given, called in [...][...] on line 8 and defined in [...][...]:3
Stack trace:
#0 [...][...](8): sumOfInts(2, &#39;error&#39;, 4.1)
#1 {main}
  thrown in <b>[...][...]</b> on line <b>3</b><br />

2.戻り値の型宣言

PHP 7では戻り値の型宣言が追加されています。サポート。パラメーターの型宣言と同様に、戻り値の型宣言では関数の戻り値の型を指定します。使用可能な型は、パラメータ宣言で使用できる型と同じです。

たとえば、以下では戻り値が配列である関数を定義します。

<?php
 
function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}
 
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

出力:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

3.null合体演算子

毎日、三項式とisset()が同時に大量に使用されるため、 use この例では、null 合体演算子 (??) の糖衣構文を追加しました。変数が存在し、NULL でない場合はそれ自体の値を返し、それ以外の場合は 2 番目のオペランドを返します。

<?php
// 如果$_GET[&#39;user&#39;]不存在就执行nobody赋值给$username
$username = $_GET[&#39;user&#39;] ?? &#39;nobody&#39;;
// 上面的语句相当于下面的语句
$username = isset($_GET[&#39;user&#39;]) ? $_GET[&#39;user&#39;] : &#39;nobody&#39;;
 
// Coalesces can be chained: this will return the first
// defined value out of $_GET[&#39;user&#39;], $_POST[&#39;user&#39;], and
// &#39;nobody&#39;.
$username = $_GET[&#39;user&#39;] ?? $_POST[&#39;user&#39;] ?? &#39;nobody&#39;;
?>

4. Spaceship 演算子 (結合比較演算子)

spaceship 演算子は、2 つの式を比較するために使用されます。 $a が $b より小さい場合、等しい場合、または $b より大きい場合は、それぞれ -1、0、または 1 を返します。比較の原則は、PHP の通常の比較ルールに従います。

<?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
?>

5.define() を使用して定数配列を定義する

配列型の定数を、define() を使用して定義できるようになりました。 PHP5.6 では const 経由でのみ定義できます。

<?php
define(&#39;ANIMALS&#39;, [
    &#39;dog&#39;,
    &#39;cat&#39;,
    &#39;bird&#39;
]);
 
echo ANIMALS[1]; // 输出 "cat"
?>

6. 匿名クラス

は、

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;
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});
 
var_dump($app->getLogger());
?>

上記のルーチンは出力します:

object(class@anonymous)#2 (0) {
}

7.Unicode コードポイント変換構文

これは、Unicode コードポイントを 16 進形式で受け入れ、出力します。二重引用符で囲まれた UTF-8 エンコード文字列またはヒアドキュメント。有効なコードポイントはどれでも受け入れられ、先頭の 0 は省略できます。

echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

上記のルーチンは出力します:

ª
ª (same as before but with optional leading 0&#39;s)
香

8.Closure::call()

Closure::call () のパフォーマンスが向上し、メソッドをオブジェクトのクロージャに一時的にバインドして呼び出すための短く簡潔な方法になりました。

<?php
class A {private $x = 1;}
 
// PHP 7 之前版本的代码
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, &#39;A&#39;); // 中间层闭包
echo $getX();
 
// PHP 7+ 及更高版本的代码
$getX = function() {return $this->x;};
echo $getX->call(new A);

上記のルーチンは出力します:

1
1

9.unserialize() はフィルタリングを提供します

この機能は、より安全に解凍する方法を提供するように設計されています。信頼性の低いデータ。ホワイトリストによりコードインジェクションの可能性を防ぎます。

// 将所有的对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => false]);
 
// 将除 MyClass 和 MyClass2 之外的所有对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
 
// 默认情况下所有的类都是可接受的,等同于省略第二个参数
$data = unserialize($foo, ["allowed_classes" => true]);

10.IntlChar

新しく追加された IntlChar クラスは、より多くの ICU 関数を公開するように設計されています。このクラス自体は、複数の文字セットの Unicode 文字を操作するための多くの静的メソッドを定義します。

<?php
 
printf(&#39;%x&#39;, IntlChar::CODEPOINT_MAX);
echo IntlChar::charName(&#39;@&#39;);
var_dump(IntlChar::ispunct(&#39;!&#39;));

上記のルーチンは出力します:

10ffff
COMMERCIAL AT
bool(true)

若要使用此类,请先安装Intl扩展

11.预期 

预期是向后兼用并增强之前的 assert() 的方法。 它使得在生产环境中启用断言为零成本,并且提供当断言失败时抛出特定异常的能力。

老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的 string或一个待测试的boolean。

<?php
ini_set(&#39;assert.exception&#39;, 1);
 
class CustomError extends AssertionError {}
 
assert(false, new CustomError(&#39;Some error message&#39;));
?>

以上例程会输出:

Fatal error: Uncaught CustomError: Some error message

关于这个特性的完整说明,包括如何在开发和生产环境中配置它,可以在assert()的 expectations section章节找到。

12.Group use declarations

从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。

<?php
 
// PHP 7 之前的代码
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 some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>

13.生成器可以返回表达式

此特性基于 PHP 5.5 版本中引入的生成器特性构建的。 它允许在生成器函数中通过使用 return 语法来返回一个表达式 (但是不允许返回引用值), 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值, 但是这个方法只能在生成器完成产生工作以后调用一次。

<?php
 
$gen = (function() {
    yield 1;
    yield 2;
 
    return 3;
})();
 
foreach ($gen as $val) {
    echo $val, PHP_EOL;
}
 
echo $gen->getReturn(), PHP_EOL;

以上例程会输出:

1
2
3

在生成器中能够返回最终的值是一个非常便利的特性, 因为它使得调用生成器的客户端代码可以直接得到生成器(或者其他协同计算)的返回值, 相对于之前版本中客户端代码必须先检查生成器是否产生了最终的值然后再进行响应处理 来得方便多了。

14.Generator delegation

现在,只需在最外层生成其中使用 yield from, 就可以把一个生成器自动委派给其他的生成器, Traversable 对象或者 array。

<?php
 
function gen()
{
    yield 1;
    yield 2;
 
    yield from gen2();
}
 
function gen2()
{
    yield 3;
    yield 4;
}
 
foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}
 
?>

以上例程会输出:

1
2
3
4

15.整数除法函数 intdiv()

新加的函数 intdiv() 用来进行 整数的除法运算。

<?php
 
var_dump(intdiv(10, 3));
?>

以上例程会输出:

int(3)

16.会话选项

session_start() 可以接受一个 array 作为参数, 用来覆盖 php.ini 文件中设置的 会话配置选项。

在调用 session_start() 的时候, 传入的选项参数中也支持 session.lazy_write 行为, 默认情况下这个配置项是打开的。它的作用是控制 PHP 只有在会话中的数据发生变化的时候才 写入会话存储文件,如果会话中的数据没有发生改变,那么 PHP 会在读取完会话数据之后, 立即关闭会话存储文件,不做任何修改,可以通过设置 read_and_close 来实现。

例如,下列代码设置 session.cache_limiter 为 private,并且在读取完毕会话数据之后马上关闭会话存储文件。

<?php
session_start([
    &#39;cache_limiter&#39; => &#39;private&#39;,
    &#39;read_and_close&#39; => true,
]);
?>

17.preg_replace_callback_array()

在 PHP 7 之前,当使用 preg_replace_callback() 函数的时候, 由于针对每个正则表达式都要执行回调函数,可能导致过多的分支代码。 而使用新加的 preg_replace_callback_array() 函数, 可以使得代码更加简洁。

现在,可以使用一个关联数组来对每个正则表达式注册回调函数, 正则表达式本身作为关联数组的键, 而对应的回调函数就是关联数组的值。

18.CSPRNG Functions

新加入两个跨平台的函数: random_bytes() 和 random_int() 用来产生高安全级别的随机字符串和随机整数。

可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象 ¶

在之前版本中,list() 函数不能保证 正确的展开实现了 ArrayAccess 接口的对象, 现在这个问题已经被修复。

19.其他特性

允许在克隆表达式上访问对象成员,例如: (clone $foo)->bar()。

PHP7.1新特性 

1.可为空(Nullable)类型

参数以及返回值的类型现在可以通过在类型前加上一个问号使之允许为空。 当启用这个特性时,传入的参数或者函数返回的结果要么是给定的类型,要么是 null 。

<?php
 
function testReturn(): ?string
{
    return &#39;elePHPant&#39;;
}
 
var_dump(testReturn());
 
function testReturn(): ?string
{
    return null;
}
 
var_dump(testReturn());
 
function test(?string $name)
{
    var_dump($name);
}
 
test(&#39;elePHPant&#39;);
test(null);
test();

以上例程会输出:

string(10) "elePHPant"
NULL
string(10) "elePHPant"
NULL
Uncaught Error: Too few arguments to function test(), 0 passed in...

2.Void 函数

一个新的返回值类型void被引入。 返回值声明为 void 类型的方法要么干脆省去 return 语句,要么使用一个空的 return 语句。 对于 void 函数来说,NULL 不是一个合法的返回值。

<?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)

试图去获取一个 void 方法的返回值会得到 NULL ,并且不会产生任何警告。这么做的原因是不想影响更高层次的方法。

3.类常量可见性

<?php
class Sky8g
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

4.iterable伪类

现在引入了一个新的被称为iterable的伪类 (与callable类似)。 这可以被用在参数或者返回值类型中,它代表接受数组或者实现了Traversable接口的对象。 至于子类,当用作参数时,子类可以收紧父类的iterable类型到array 或一个实现了Traversable的对象。对于返回值,子类可以拓宽父类的 array或对象返回值类型到iterable

<?php
function iterator(iterable $iter)
{
    foreach ($iter as $val) {
        //
    }
}

5.多异常捕获处理

一个catch语句块现在可以通过管道字符(|)来实现多个异常的捕获。 这对于需要同时处理来自不同类的不同异常时很有用。

<?php
try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}

6.list()现在支持键名

现在list()和它的新的[]语法支持在它内部去指定键名。这意味着它可以将任意类型的数组 都赋值给一些变量(与短数组语法类似)

<?php
$data = [
    ["id" => 1, "name" => &#39;Tom&#39;],
    ["id" => 2, "name" => &#39;Fred&#39;],
];
 
// list() style
list("id" => $id1, "name" => $name1) = $data[0];
 
// [] style
["id" => $id1, "name" => $name1] = $data[0];
 
// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
    // logic here with $id and $name
}
 
// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
    // logic here with $id and $name
}

7.支持为负的字符串偏移量

现在所有支持偏移量的字符串操作函数 都支持接受负数作为偏移量,包括通过[]{}操作字符串下标。在这种情况下,一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。

<?php
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));

以上例程会输出:

string (1) "e"
int(3)

PHP7.2新特性

1.新的对象类型

这种新的对象类型<span class="type">object</span>, 引进了可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型。

<?php
 
function test(object $obj) : object
{
    return new SplQueue();
}
 
test(new StdClass());

2.通过名称加载扩展

扩展文件不再需要通过文件加载 (Unix下以<em>.so</em>为文件扩展名,在Windows下以 <em>.dll</em> 为文件扩展名) 进行指定。可以在php.ini配置文件进行启用, 也可以使用 <span class="function">dl()</span> 函数进行启用。

3.允许重写抽象方法(Abstract method) 

当一个抽象类继承于另外一个抽象类的时候,继承后的抽象类可以重写被继承的抽象类的抽象方法。

<?php
 
abstract class A
{
    abstract function test(string $s);
}
abstract class B extends A
{
    // overridden - still maintaining contravariance for parameters and covariance for return
    abstract function test($s) : int;
}

4.使用Argon2算法生成密码散列

Argon2 已经被加入到密码散列(password hashing) API (这些函数以 password_ 开头), 以下是暴露出来的常量:

  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

5.新增 ext/PDO(PDO扩展) 字符串扩展类型

当你准备支持多语言字符集,PDO的字符串类型已经扩展支持国际化的字符集。以下是扩展的常量:

  • PDO::PARAM_STR_NATL
  • PDO::PARAM_STR_CHAR
  • PDO::ATTR_DEFAULT_STR_PARAM

这些常量通过PDO::PARAM_STR利用位运算OR进行计算:

<?php
 
$db->quote(&#39;über&#39;, PDO::PARAM_STR | PDO::PARAM_STR_NATL);

6.为 ext/PDO新增额外的模拟调试信息

<span class="function">PDOStatement::debugDumpParams()</span>方法已经更新,当发送SQL到数据库的时候,在一致性、行查询(包括替换绑定占位符)将会显示调试信息。这一特性已经加入到模拟调试中(在模拟调试打开时可用)。

7.ext/LDAP(LDAP扩展) 支持新的操作方式

LDAP 扩展已经新增了EXOP支持. 扩展暴露以下函数和常量:

  • <span class="simpara"><span class="function">ldap_parse_exop()</span></span>
  • <span class="simpara"><span class="function">ldap_exop()</span></span>
  • <span class="simpara"><span class="function">ldap_exop_passwd()</span></span>
  • <span class="simpara"><span class="function">ldap_exop_whoami()</span></span>
  • LDAP_EXOP_START_TLS
  • LDAP_EXOP_MODIFY_PASSWD
  • LDAP_EXOP_REFRESH
  • LDAP_EXOP_WHO_AM_I
  • LDAP_EXOP_TURN

8.ext/sockets(sockets扩展)添加了地址信息

sockets扩展现在具有查找地址信息的能力,且可以连接到这个地址,或者进行绑定和解析。为此添加了以下一些函数:

  • socket_addrinfo_lookup()
  • socket_addrinfo_connect()
  • socket_addrinfo_bind()
  • socket_addrinfo_explain()

9.扩展了参数类型

重写方法和接口实现的参数类型现在可以省略了。不过这仍然是符合LSP,因为现在这种参数类型是逆变的。

<?php
 
interface A
{
    public function Test(array $input);
}
 
class B implements A
{
    public function Test($input){} // type omitted for $input
}

10.允许分组命名空间的尾部逗号

命名空间可以在PHP 7中使用尾随逗号进行分组引入。

<?php
 
use Foo\Bar\{
    Foo,
    Bar,
    Baz,
};

PHP7.3新特性

1.Unicode 11支持

多字节字符串数据表已更新为Unicode 11。

2.长字符串的支持

多字节字符串函数现在正确支持大于2GB的字符串。

3.性能改进

多字节字符串扩展的性能得到了全面的显著改善。最大的改进是大小写转换功能。

4.自定义命名了支持

mb_ereg_*函数现在支持命名捕捉。像mb_ereg()这样的匹配函数现在将使用它们的组号和名称返回指定的捕获,类似于PCRE:

<?php
mb_ereg(&#39;(?<word>\w+)&#39;, &#39;国&#39;, $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
?>

另外,mb_ereg_replace()现在支持\ka8093152e673feb7aba1828c43532094和\k "符号来引用替换字符串中的指定捕获:

<?php
mb_ereg_replace(&#39;\s*(?<word>\w+)\s*&#39;, "_\k<word>_\k&#39;word&#39;_", &#39; foo &#39;);
// => "_foo_foo_"
?>

\ka8093152e673feb7aba1828c43532094和\k "也可用于编号引用,也可用于大于9的组号。

PHP7.4新特性

1.类型属性

类属性现在支持类型声明。

<?php
class User {
    public int $id;
    public string $name;
}
?>

上面的示例将强制执行$user->id只能赋给整数值,而$user->name只能赋给字符串值。

2.箭头函数 

箭头函数为使用隐式按值范围绑定定义函数提供了一种简写语法。

<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>

3.限制返回类型和参数型逆变

<?php
class A {}
class B extends A {}
 
class Producer {
    public function method(): A {}
}
class ChildProducer extends Producer {
    public function method(): B {}
}
?>

只有在使用自动加载时,才可以使用全方差支持。在单个文件中,只有非循环类型引用是可能的,因为所有类在被引用之前都必须是可用的。

4.Null 合并赋值运算符

<?php
$array[&#39;key&#39;] ??= computeDefault();
// is roughly equivalent to
if (!isset($array[&#39;key&#39;])) {
    $array[&#39;key&#39;] = computeDefault();
}
?>

5.合并数组新方式

<?php
$parts = [&#39;apple&#39;, &#39;pear&#39;];
$fruits = [&#39;banana&#39;, &#39;orange&#39;, ...$parts, &#39;watermelon&#39;];
// [&#39;banana&#39;, &#39;orange&#39;, &#39;apple&#39;, &#39;pear&#39;, &#39;watermelon&#39;];
?>

6.数值文字分隔符

<?php
6.674_083e-11; // float
299_792_458;   // decimal
0xCAFE_F00D;   // hexadecimal
0b0101_1111;   // binary
?>

7.弱引用

弱引用允许程序员保留对对象的引用,而不阻止对象被销毁。

如果有不懂的地方请留言,SKY8G网站编辑者专注于研究IT源代码研究与开发。希望你下次光临,你的认可和留言是对我们最大的支持,谢谢!

推荐学习:《PHP视频教程

以上がPHP7.X の各バージョンの新機能をすぐに理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsky8gで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。