久久亚洲精品国产精品_羞羞漫画在线版免费阅读网页漫画_国产精品久久久久久久久久久久_午夜dj免费观看在线视频_希崎杰西卡番号

運(yùn)行啟動(dòng)項(xiàng)(開(kāi)機(jī)啟動(dòng)項(xiàng)命令是什么)

前沿拓展:

運(yùn)行啟動(dòng)項(xiàng)

一、聲卡控制面板設(shè)置(部分聲卡都會(huì)有這方便的問(wèn)題,如:Realtek、via) 打開(kāi)音頻管理器——點(diǎn)擊右側(cè)接點(diǎn)擊安裝。


作者 | Deepak Vohra

譯者 | 劉雅夢(mèng)

策劃 | 丁曉昀

本文屬于專(zhuān)題文章《深入淺出 PHP 8》。 根據(jù)w3tech的數(shù)據(jù),PHP 仍然是 Web 上使用最廣泛的腳本語(yǔ)言之一,77.3%的網(wǎng)站使用 PHP 進(jìn)行服務(wù)器端編程。PHP 8 帶來(lái)了許多新特性和其他改進(jìn),我們將在本系列文章中進(jìn)行探討。PHP 8.0 添加了對(duì)多個(gè)函數(shù)和方法相關(guān)特性的支持,其中一些是對(duì)現(xiàn)有特性的改進(jìn),而另一些則是全新的特性。PHP 8.1 中增強(qiáng)的可調(diào)用語(yǔ)法可用于通過(guò)可調(diào)用對(duì)象創(chuàng)建匿名函數(shù)。命名函數(shù)參數(shù)可以與位置參數(shù)一起使用,另外還有一個(gè)好處,即命名參數(shù)沒(méi)有順序,可以通過(guò)它們的名稱(chēng)來(lái)傳達(dá)含義。纖程(Fiber)是可中斷的函數(shù),增加了對(duì)多任務(wù)的支持。

重新定義了私有方法上的繼承

對(duì)象繼承是大多數(shù)面向?qū)ο笳Z(yǔ)言(包括 PHP)所使用的編程范式。它可以從任何擴(kuò)展類(lèi)中重寫(xiě)公共和受保護(hù)的方法,以及在類(lèi)中定義的類(lèi)屬性和常量。在 PHP 中,公共方法不能通過(guò)更嚴(yán)格的訪(fǎng)問(wèn)來(lái)重新實(shí)現(xiàn),例如將 public 方法設(shè)為 private 。為了演示這一點(diǎn),考慮一個(gè)擴(kuò)展了類(lèi) A 的類(lèi) B,它重新實(shí)現(xiàn)了類(lèi) A 中一個(gè)公共方法。

<?php
class A{
public function sortArray():string{
return "Class A method";
}
}

class B extends A{
private function sortArray():string{
return "Class B method";
}
}
$b=new B();
echo $b->sortArray();

運(yùn)行時(shí),腳本會(huì)生成如下的一條錯(cuò)誤信息:

致命錯(cuò)誤:B::sortArray()的訪(fǎng)問(wèn)級(jí)別必須是公共的(與類(lèi)A一樣)
公共方法不能重新實(shí)現(xiàn)。

相反,在類(lèi)中定義的私有方法不是繼承的,可以在擴(kuò)展它的類(lèi)中重新實(shí)現(xiàn)。例如,類(lèi) B 在下面的腳本中擴(kuò)展了類(lèi) A,并重新實(shí)現(xiàn)了類(lèi) A 中一個(gè)私有方法。

<?php
class A{
private function sortArray():string{
return "Class A method";
}
}

class B extends A{
private function sortArray(int $a):string{
return "Class B method";
}
}

在 PHP 8.0 之前,對(duì)擴(kuò)展類(lèi)中私有方法的重新聲明應(yīng)用了兩個(gè)限制:不允許更改 finalstatic 修飾符。如果 private 方法被聲明為 final ,則不允許擴(kuò)展類(lèi)重新聲明該方法。如果私有方法被聲明為靜態(tài)的,那么它將在擴(kuò)展類(lèi)中保持靜態(tài)。而且,如果私有方法沒(méi)有static 修飾符,則不允許擴(kuò)展類(lèi)添加static 修飾符。在 PHP 8 中,這兩個(gè)限制都被取消了。以下腳本在 PHP 8 中能正常運(yùn)行。

<?php
class A {
private final static function sortArray():string{
return "Class A method";
}
}

class B extends A {
private function sortArray(int $a):string{
return "Class B method";
}
}

PHP 8 中唯一的私有方法限制是強(qiáng)制使用 private final 構(gòu)造函數(shù),當(dāng)使用靜態(tài)工廠(chǎng)方法作為替代時(shí),有時(shí)會(huì)使用private final來(lái)禁用構(gòu)造函數(shù)。

<?php
class A {
private final function __construct(){

}
}

class B extends A {
private final function __construct(){

}
}

該腳本生成如下的錯(cuò)誤信息:

致命錯(cuò)誤:不能重寫(xiě)最終方法A::__construct()

可變參數(shù)可以替換任意數(shù)量的函數(shù)參數(shù)

在 PHP 8 中,單個(gè)可變參數(shù)可以替換任意數(shù)量的函數(shù)參數(shù)。考慮下面的腳本,其中類(lèi) B 擴(kuò)展了類(lèi) A,并用一個(gè)可變參數(shù)替換函數(shù) sortArray 的三個(gè)參數(shù)。

<?php
class A {
public function sortArray(array $arrayToSort, string $sortType, int $arraySize) {
if ($sortType == "asc") {
sort($arrayToSort);
foreach ($arrayToSort as $key => $val) {
echo "$key = $val ";
}
} elseif ($sortType == "desc") {
rsort($arrayToSort);
foreach ($arrayToSort as $key => $val) {
echo "$key = $val ";
}
}
}
}
class B extends A {
public function sortArray(…$multiple) {
$arrayToSort= $multiple[0];
$sortType=$multiple[1];

if ($sortType == "asc") {
sort($arrayToSort);
foreach ($arrayToSort as $key => $val) {
echo "$key = $val ";
}
} elseif ($sortType == "desc") {
rsort($arrayToSort);
foreach ($arrayToSort as $key => $val) {
echo "$key = $val ";
}
}
}
}

可以使用多個(gè)參數(shù)調(diào)用類(lèi) B 中的 sortArray 函數(shù)。

$sortType="asc";
$arrayToSort=array("B", "A", "f", "C");
$arraySize=4;

$b=new B();
$b->sortArray($arrayToSort,$sortType,$arraySize)

輸出結(jié)果如下所示:

0 = A 1 = B 2 = C 3 = f

簡(jiǎn)化了可調(diào)用語(yǔ)法

可調(diào)用(callable)是可以被調(diào)用的 PHP 表達(dá)式,例如實(shí)例方法、靜態(tài)方法或可調(diào)用對(duì)象。例如,可調(diào)用可用于為方法調(diào)用創(chuàng)建簡(jiǎn)短的表達(dá)式。在 PHP 8.1 中,可以用新的可調(diào)用語(yǔ)法:

AVariableCallableExpression(…)

AVariableCallableExpression 表示一個(gè)變量可調(diào)用表達(dá)式。省略號(hào)…包含在語(yǔ)法中。

為什么要使用新的可調(diào)用語(yǔ)法呢?讓我們通過(guò)一些示例來(lái)回顧一下傳統(tǒng)的可調(diào)用語(yǔ)法是什么樣子的:

$f1 = 'strlen'(…);
$f2 = [$someobj, 'somemethod'](…);
$f3 = [SomeClass::class, 'somestaticmethod'](…);

這有兩個(gè)問(wèn)題:

語(yǔ)法涉及字符串和數(shù)組在創(chuàng)建可調(diào)用時(shí),作用域不會(huì)被維護(hù)。為了演示這一點(diǎn),請(qǐng)考慮如下用于對(duì)數(shù)組進(jìn)行排序的腳本,其中 getSortArrayMethod() 方法返回 sortArray() 方法的可調(diào)用項(xiàng),[$this,'sortArray']<?php

class Sort {
private array $arrayToSort;
private string $sortType;
public function __construct($arrayToSort,$sortType)
{
$this->arrayToSort = $arrayToSort;
$this->sortType = $sortType;
}
public function getSortArrayMethod() {
return [$this, 'sortArray'];

}
private function sortArray() {
if ($this->sortType == "Asc") {
sort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} elseif ($this->sortType == "Desc") {
rsort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} else {

shuffle($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
}
}
}
$sortType="Asc";
$arrayToSort=array("B", "A", "f", "C");
$sort = new Sort($arrayToSort,$sortType);
$c = $sort->getSortArrayMethod();
$c();

該腳本會(huì)生成如下的錯(cuò)誤信息:

致命錯(cuò)誤:未捕獲錯(cuò)誤:調(diào)用私有方法Sort::sortArray()來(lái)自全局作用域

使用 Closure::fromCallable([$this, 'sortArray']) 而不是 [$this, 'sortArray'] 可以解決作用域問(wèn)題,但使用 Closure::fromCallable 方**使調(diào)用變得冗長(zhǎng)。新的可調(diào)用語(yǔ)法解決了作用域和語(yǔ)法冗長(zhǎng)的問(wèn)題。使用新的可調(diào)用語(yǔ)法,函數(shù)變?yōu)椋?/span>

public function getSortArrayMethod() {
return $this->sortArray(…);
}

數(shù)組根據(jù)輸出進(jìn)行排序:

0 = A 1 = B 2 = C 3 = f

新語(yǔ)法可以與涉及字符串和數(shù)組的傳統(tǒng)語(yǔ)法結(jié)合使用,以解決作用域問(wèn)題。創(chuàng)建可調(diào)用的作用域?qū)⒈3植蛔儭?/span>

public function getSortArrayMethod() {
return [$this, 'sortArray'](…);

}

新的可調(diào)用語(yǔ)法也可以與靜態(tài)方法一起使用,如下面的腳本所示,該腳本包含一個(gè)靜態(tài)函數(shù)。

<?php
class Sort {
private array $arrayToSort;
private string $sortType;
public function __construct($arrayToSort,$sortType)
{
$this->arrayToSort = $arrayToSort;
$this->sortType = $sortType;
}
public function getStaticMethod() {

return Sort::aStaticFunction(…);

}

private static function aStaticFunction() {
}
}
$sortType="Asc";
$arrayToSort=array("B", "A", "f", "C");
$sort = new Sort($arrayToSort,$sortType);
$cStatic=$sort->getStaticMethod();
$cStatic();

輸出結(jié)果與之前的相同:

0 = A 1 = B 2 = C 3 =

以下是調(diào)用方法的等效方法:

return $this->sortArray(…);
return Closure::fromCallable([$this, 'sortArray']);
return [$this, 'sortArray'](…);

以下是調(diào)用靜態(tài)方法的等效方法:

return Sort::aStaticFunction(…);
return [Sort::class, 'aStaticFunction'](…);
return Closure::fromCallable([Sort::class, 'aStaticFunction']);

即使函數(shù)聲明了形參,也可以使用新的可調(diào)用語(yǔ)法。

<?php
class Sort {
private array $arrayToSort;
private string $sortType;
public function __construct($arrayToSort,$sortType)
{
$this->arrayToSort = $arrayToSort;
$this->sortType = $sortType;
}
public function getSortArrayMethod() {
return $this->sortArray(…);
}
private function sortArray(int $a,string $b) {
if ($this->sortType == "Asc") {
sort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} elseif ($this->sortType == "Desc") {
rsort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} else {

shuffle($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
}
}
}

如果一個(gè)方法聲明了任意參數(shù),則必須使用它的參數(shù)來(lái)調(diào)用可調(diào)用對(duì)象。

$sortType="Asc";
$arrayToSort=array("B", "A", "f", "C");
$sort = new Sort($arrayToSort,$sortType);
$c = $sort->getSortArrayMethod();
$c(1,"A");

簡(jiǎn)化語(yǔ)法可用于任意的 PHP Callable 表達(dá)式

簡(jiǎn)化的可調(diào)用語(yǔ)法可以用于任意的 PHP 可調(diào)用表達(dá)式。用于對(duì)象創(chuàng)建的 new 運(yùn)算符不支持可調(diào)用語(yǔ)法,因?yàn)榭烧{(diào)用語(yǔ)法 AVariableCallableExpression(…) 沒(méi)有指定構(gòu)造函數(shù)參數(shù)的規(guī)定,這可能是必需的。以下是不支持的示例:

$sort = new Sort(…);

生成的錯(cuò)誤信息為:

致命錯(cuò)誤:不能為new表達(dá)式創(chuàng)建閉包

以下的腳本演示了受支持的所有可調(diào)用表達(dá)式。

<?php
class Sort {
private array $arrayToSort;
private string $sortType;
public function __construct($arrayToSort,$sortType)
{
$this->arrayToSort = $arrayToSort;
$this->sortType = $sortType;
}
public function getSortArrayMethod() {
return $this->sortArray(…);
}
public function getStaticMethod() {

return Sort::aStaticFunction(…);

}

public static function aStaticFunction() {
}

public function sortArray(int $a,string $b) {
if ($this->sortType == "Asc") {
sort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} elseif ($this->sortType == "Desc") {
rsort($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
} else {

shuffle($this->arrayToSort);
foreach ($this->arrayToSort as $key => $val) {
echo "$key = $val ";
}
}
}
public function __invoke() {}
}
$sortType="Asc";
$arrayToSort=array("B", "A", "f", "C");

$classStr = 'Sort';
$staticmethodStr = 'aStaticFunction';
$c1 = $classStr::$staticmethodStr(…);
$methodStr = 'sortArray';
$sort = new Sort($arrayToSort,$sortType);
$c2 = strlen(…);
$c3 = $sort(…); // 可調(diào)用對(duì)象
$c4 = $sort->sortArray(…);
$c5 = $sort->$methodStr(…);
$c6 = Sort::aStaticFunction(…);
$c7 = $classStr::$staticmethodStr(…);
// 傳統(tǒng)的可調(diào)用使用字符串,數(shù)組
$c8 = 'strlen'(…);
$c9 = [$sort, 'sortArray'](…);
$c10 = [Sort::class, 'aStaticFunction'](…);
$c11 = $sort->getSortArrayMethod();
$c11(1,"A");
$cStatic=$sort->getStaticMethod();
$cStatic();

尾逗號(hào)和可選/必選的參數(shù)順序

PHP 8.0 的另一個(gè)新特性是支持在函數(shù)的參數(shù)列表末尾添加一個(gè)尾逗號(hào),以提高可讀性。任何尾逗號(hào)都將被忽略。尾逗號(hào)可能并不總是有用的,但如果參數(shù)列表很長(zhǎng),或者參數(shù)名稱(chēng)很長(zhǎng),則可能會(huì)有用,因此可以垂直列出它們。閉包使用列表也支持尾逗號(hào)。

PHP 8.0 不支持在必選參數(shù)之前聲明可選參數(shù)。在必選參數(shù)之前聲明的可選參數(shù)都是隱式的必選參數(shù)。

下面的腳本演示了必選參數(shù)的隱式順序,以及尾逗號(hào)的使用。

<?php
function trailing_comma_example(
$the_very_first_arg_of_this_function,
$the_second_arg_of_this_function,
$the_third_arg_of_this_function = 1,
$the_fourth_arg_of_this_function,
$the_last_arg_of_this_function,
){ echo $the_third_arg_of_this_function; }

trailing_comma_example(1,2,null,3,4)

?>

輸出如下所示:

已棄用(不推薦):在必選參數(shù)$the_last_arg_of_this_function之前聲明的可選參數(shù)
$the_third_arg_of_tis_function將被隱式地視為必選參數(shù)

可空參數(shù)不會(huì)被視為可選參數(shù),可以使用 $param=null 形式或顯式可空類(lèi)型在必選參數(shù)之前聲明,腳本如下所示:

<?php
class A {}
function fn1(A $a = null, $b) {}
function fn2(?A $a, $b) {}
fn1(new A,1);
fn2(null,1);
?>

命名函數(shù)形參和實(shí)參

PHP 8.0 除了已經(jīng)支持的位置形參和實(shí)參之外,還增加了對(duì)命名函數(shù)形參和實(shí)參的支持。命名參數(shù)在函數(shù)調(diào)用中的傳遞語(yǔ)法如下所示:

參數(shù)名稱(chēng):參數(shù)值

命名參數(shù)的一些好處如下所示:

可以為函數(shù)參數(shù)指定一個(gè)有意義的名稱(chēng),使它們能夠自我記錄按名稱(chēng)傳遞時(shí),參數(shù)與順序無(wú)關(guān)可以任意跳過(guò)默認(rèn)值。在下面的腳本中, array_hashtable 函數(shù)聲明了命名參數(shù)。 該函數(shù)傳遞的實(shí)參值可以帶參數(shù)名,也可以不帶參數(shù)名。當(dāng)傳遞位置實(shí)參時(shí),使用函數(shù)形參聲明順序。但傳遞命名實(shí)參時(shí),可以使用任意順序。

<?php
function array_hashtable($key1,$key2,$key3,$key4,$key5){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// 使用位置實(shí)參:
array_hashtable(0, 10, 50, 20, 25);
// 使用命名實(shí)參:
array_hashtable(key2: 0, key5: 25, key1: 10, key4: 50, key3: 20);
?>

輸出結(jié)果為:

0 10 50 20 25

命名實(shí)參和位置實(shí)參可以在同一函數(shù)調(diào)用中使用。對(duì)相同的示例函數(shù) array_hashtable 一起使用混合參數(shù)調(diào)用。

<?php
function array_hashtable($key1,$key2,$key3,$key4,$key5){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// 使用混合參數(shù):
array_hashtable(0, 10, 50, key5: 25, key4: 20);

?>

輸出結(jié)果為:

0 10 50 20 25

請(qǐng)注意,命名參數(shù)只能用于位置參數(shù)之后。下面的腳本顛倒了順序,在命名參數(shù)之后使用位置參數(shù):

<?php
function array_hashtable($key1,$key2,$key3,$key4,$key5){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// Using mixed arguments:
array_hashtable(0, 10, key3: 25, 50, key5: 20);

?>

該腳本生成的錯(cuò)誤信息為:

致命錯(cuò)誤:不能在命名參數(shù)后使用位置參數(shù)

即使使用命名參數(shù),也不推薦在必選參數(shù)之前聲明可選參數(shù),腳本如下所示:

<?php
function array_hashtable($key1=0,$key2=10,$key3=20,$key4,$key5){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// 使用混合參數(shù):
array_hashtable(1,2,key3: 25, key4: 1,key5: 20);

?>

輸出將包括已棄用(不推薦)信息:

已棄用(不推薦):在必選參數(shù)$key5之前聲明的可選參數(shù)$key1被隱式視為必選參數(shù)
已棄用(不推薦):在必選參數(shù)$key5之前聲明的可選參數(shù)$key2被隱式視為必選參數(shù)
已棄用(不推薦):在必選參數(shù)$key5之前聲明的可選參數(shù)$key3被隱式視為必選參數(shù)

當(dāng)在必選命名形參之后使用可選命名形參時(shí),命名實(shí)參可用于跳過(guò)函數(shù)調(diào)用中的一個(gè)或多個(gè)可選形參,腳本如下所示:

<?php
function array_hashtable($key1,$key2,$key3=20,$key4=50,$key5=10){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// 使用混合參數(shù):
array_hashtable(key1:1, key2:2,key4: 25);

?>

輸出結(jié)果為:

1 2 20 25 10

你可以只使用可選參數(shù)的子集來(lái)調(diào)用函數(shù),而不用考慮它們的順序。

<?php
function array_hashtable($key1=0,$key2=10,$key3=20,$key4=50,$key5=10){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// 使用混合參數(shù):
array_hashtable(1,2,key4: 25);

?>

輸出結(jié)果如下所示:

1 2 20 25 10

即使使用可選參數(shù)的子集調(diào)用函數(shù),也不能在命名參數(shù)之后使用位置參數(shù),腳本如下所示:

<?php
function array_hashtable($key1=0,$key2=10,$key3=20,$key4=50,$key5=10){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
// Using mixed arguments:
array_hashtable(1,2,key4: 25,5);

?>

生成的錯(cuò)誤信息以下所示:

致命錯(cuò)誤:不能在命名參數(shù)后使用位置參數(shù)

PHP 8.1 改進(jìn)了命名實(shí)參特性,在解包實(shí)參后支持命名實(shí)參,腳本如下所示:

<?php
function array_hashtable($key1,$key2,$key3=30,$key4=40,$key5=50){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
echo array_hashtable(…[10, 20], key5: 40);
echo array_hashtable(…['key2' => 2, 'key1' => 2], key4: 50);

?>

輸出如下所示:

10 20 30 40 40
2 2 30 50 50

但是,命名的參數(shù)不能蓋前面的參數(shù),腳本如下所示:

<?php
function array_hashtable($key1,$key2,$key3=30,$key4=40,$key5=50){
echo $key1.' '.$key2.' '.$key3.' '.$key4.' '.$key5;
echo "<br>";
}
echo array_hashtable(…[10, 20], key2: 40);
?>

輸出如下所示:

致命錯(cuò)誤:未捕獲錯(cuò)誤:命名參數(shù)$key2覆蓋上一個(gè)參數(shù)。

非靜態(tài)方法不能被靜態(tài)調(diào)用

在 PHP 8.0 之前,如果在靜態(tài)上下文中調(diào)用非靜態(tài)方法,或者靜態(tài)調(diào)用,則只會(huì)收到一條已棄用(不推薦)的信息。使用 8.0,你現(xiàn)在會(huì)收到一條錯(cuò)誤信息。此外, $this 在靜態(tài)上下文中是未定義的。為了演示這一點(diǎn),請(qǐng)考慮如下的腳本,其中使用靜態(tài)語(yǔ)法 A::aNonStaticMethod() 調(diào)用了非靜態(tài)方法 aNonStaticMethod()

<?php
class A
{
function aNonStaticMethod()
{
}
}

A::aNonStaticMethod();

如果你運(yùn)行這個(gè)腳本,將會(huì)得到如下的錯(cuò)誤信息:

未捕獲錯(cuò)誤:非靜態(tài)方法A::aNonStaticMethod()不能被靜態(tài)調(diào)用

纖程

PHP 8.1 添加了對(duì)纖程(Fiber)多任務(wù)的支持。纖程是一個(gè)可中斷的函數(shù),它具有自己的堆棧。纖程可以從調(diào)用堆棧中的任何位置掛起,第二再恢復(fù)。新的 Fiber 類(lèi)是一個(gè) final 類(lèi),它支持以下的公共方法:

方法

描述

__construct(callable $callback) <br>

創(chuàng)建新Fiber實(shí)例的構(gòu)造函數(shù)。 該參數(shù)是啟動(dòng)纖程時(shí)要調(diào)用的可調(diào)用對(duì)象。 提供給Fiber::start()的參數(shù)將作為給定可調(diào)用對(duì)象的參數(shù)提供。 可調(diào)用對(duì)象根本不需要調(diào)用Fiber::suspend(),或者即使調(diào)用也不需要直接調(diào)用。對(duì)Fiber::suspend()的調(diào)用可能在調(diào)用堆棧中嵌套很深。

start(mixed …$args): mixed

啟動(dòng)纖程。該方法在纖程掛起或終止時(shí)返回。在構(gòu)造纖程時(shí),為所使用的可調(diào)用函數(shù)提供了可變的參數(shù)列表。如果纖程返回,則從第一個(gè)掛起點(diǎn)返回混合值或返回NULL。如果調(diào)用該方法時(shí)纖程已經(jīng)啟動(dòng),則會(huì)拋出FiberError錯(cuò)誤。

resume(mixed $value = null): mixed

恢復(fù)纖程,從Fiber::suspend()返回給定的混合值。 當(dāng)纖程掛起或終止時(shí)返回。 返回的混合值實(shí)際上是從下一個(gè)掛起點(diǎn)返回的,如果纖程返回,則返回NULL。 如果纖程尚未啟動(dòng)、正在運(yùn)行或已終止,則拋出FiberError錯(cuò)誤。

throw(Throwable $exception): mixed

將給定的異常從Fiber::suspend()拋出到纖程中。 當(dāng)纖程掛起或終止時(shí)返回。 參數(shù)是Throwable $exception。 返回的混合值實(shí)際上是從下一個(gè)掛起點(diǎn)返回的,如果纖程返回,則返回NULL。 如果纖程尚未啟動(dòng)、正在運(yùn)行或已終止,則拋出FiberError錯(cuò)誤。

getReturn(): mixed

獲取纖程回調(diào)的混合返回值。 如果纖程沒(méi)有返回語(yǔ)句,則返回NULL。 如果纖程未終止或纖程拋出異常,則拋出FiberError錯(cuò)誤。

isStarted(): bool

如果纖程已經(jīng)啟動(dòng),則返回布爾值True。

isSuspended(): bool

如果纖程已掛起,則返回布爾值True。

isRunning(): bool

如果纖程正在運(yùn)行,則返回布爾值True。

isTerminated(): bool

如果纖程已終止,則返回布爾值True。

static suspend(mixed $value = null): mixed

掛起纖程。 返回對(duì)Fiber->start()、Fiber->resume() 或 Fiber->throw() 的調(diào)用執(zhí)行。可以使用Fiber::resume()或Fiber::throw()恢復(fù)纖程。不能從纖程外的主線(xiàn)程調(diào)用。 參數(shù)是從Fiber::resume()或 Fiber::throw()返回的混合值$value。返回的混合值提供給Fiber::resume()。<br>如果不在纖程內(nèi)(即,如果從主線(xiàn)程調(diào)用),則拋出FiberError錯(cuò)誤。

static getCurrent(): ?Fiber

返回當(dāng)前正在執(zhí)行的纖程實(shí)例,如果在主線(xiàn)程中則返回NULL。

纖程只能啟動(dòng)一次,但可以?huà)炱鸩⒒謴?fù)多次。下面的腳本通過(guò)使用纖程在數(shù)組上執(zhí)行不同類(lèi)型的排序來(lái)演示多任務(wù)處理。纖程在每次排序后都會(huì)掛起,第二再恢復(fù)執(zhí)行不同類(lèi)型的排序。

<?php

$fiber = new Fiber(function (array $arr): void {
sort($arr);
foreach ($arr as $key => $val) {
echo "$key = $val ";
}
echo "<br/>";
Fiber::suspend();
rsort($arr);
foreach ($arr as $key => $val) {
echo "$key = $val ";
}
echo "<br/>";
Fiber::suspend();
shuffle($arr);
foreach ($arr as $key => $val) {
echo "$key = $val ";
}
});

$arrayToSort=array("B", "A", "f", "C");
$value = $fiber->start($arrayToSort);

$fiber->resume();
$fiber->resume();
?>

輸出如下所示:

0 = A 1 = B 2 = C 3 = f
0 = f 1 = C 2 = B 3 = A
0 = C 1 = f 2 = A 3 = B

如果纖程在第一次掛起后沒(méi)有再恢復(fù),則只進(jìn)行一種類(lèi)型的排序,這可以通過(guò)注釋掉對(duì) resume() 的兩次調(diào)用來(lái)實(shí)現(xiàn)。

//$fiber->resume();

//$fiber->resume();

輸出的是第一次排序的結(jié)果:

0 = A 1 = B 2 = C 3 = f

Stringable 接口和 __toString()

PHP 8.0 引入了一個(gè)名為 Stringable 的新接口,它只提供一個(gè)方法 __toString()__toString() 方法如果在類(lèi)中提供,將隱式實(shí)現(xiàn) Stringable 接口。考慮提供 __toString() 方法的類(lèi) A。

<?php

class A {

public function __toString(): string {
return " ";
}
}

echo (new A() instanceof Stringable);

該腳本從 Stringable 的類(lèi)型檢查中返回 1。

然而,反之則不然。如果類(lèi)實(shí)現(xiàn)了 Stringable 接口,則必須顯式提供 __toString() 方法,因?yàn)樵摲椒ú粫?huì)自動(dòng)添加,比如:

<?php

class A implements Stringable {
public function __toString(): string { }

}

新的標(biāo)準(zhǔn)庫(kù)函數(shù)

PHP 8 引入了許多屬于其標(biāo)準(zhǔn)庫(kù)的新函數(shù)。

str_contains 函數(shù)返回一個(gè) bool 值,用于指示作為第一個(gè)參數(shù)的字符串是否包含作為第二個(gè)參數(shù)的字符串。以下腳本將返回 false

<?php

if (str_contains('haystack', 'needle')) {
echo true;
} else {
echo false;
}

下面的腳本返回 1,或 true:

<?php
if (str_contains('haystack', 'hay')) {
echo true;
}else {
echo "false";
}

str_starts_with 函數(shù)返回一個(gè)bool 值 ,指示作為第一個(gè)參數(shù)的字符串是否以作為第二個(gè)參數(shù)的字符串開(kāi)頭。以下腳本將返回 false

<?php

if (str_contains('haystack', 'hay')) {
echo true;
}else {
echo "false";
}

下面的腳本將返回 1,或 true。

<?php

if (str_starts_with('haystack', 'needle')) {
echo true;
} else {
echo false;
}

str_ends_with 函數(shù)返回一個(gè)bool 值 ,指示作為第一個(gè)參數(shù)的字符串是否以作為第二個(gè)參數(shù)的字符串結(jié)尾。以下腳本將返回 false

<?php

if (str_starts_with('haystack', 'needle')) {
echo true;
} else {
echo false;
}

下面的腳本將返回 1,或 true。

<?php

if (str_starts_with('haystack', 'hay')) {
echo true;
} else {
echo false;
}

fdiv 函數(shù)將兩個(gè)數(shù)字相除并返回一個(gè) float 值,腳本如下所示:

<?php

var_dump(fdiv(1.5, 1.3));
var_dump(fdiv(10, 2));
var_dump(fdiv(5.0, 0.0));
var_dump(fdiv(-2.0, 0.0));
var_dump(fdiv(0.0, 0.0));

var_dump(fdiv(5.0, 1.0));
var_dump(fdiv(10.0, 2));

輸出為:

float(1.1538461538461537)
float(5)
float(INF)
float(-INF)
float(NAN)
float(5)
float(5)

fdatasync 函數(shù)在 Windows 上的別名為 fsync ,用于將數(shù)據(jù)同步到文件上的流中。為了演示它的用法,在包含要運(yùn)行的 PHP 腳本的腳本目錄中創(chuàng)建一個(gè)空文件 test.txt 。運(yùn)行腳本:

<?php

$file = 'test.txt';

$stream = fopen($file, 'w');
fwrite($stream, 'first line of data');
fwrite($stream, "\r\n");
fwrite($stream, 'second line of data');
fwrite($stream, 'third line of data');

fdatasync($stream);
fclose($stream);

隨后,打開(kāi) test.txt 文件會(huì)發(fā)現(xiàn)包含如下的文本:

first line of data
second line of data
third line of data

array_is_list 函數(shù)返回布爾值,用于指示給定的數(shù)組是否為列表。數(shù)組必須從 0 開(kāi)始,鍵必須是連續(xù)的整數(shù),并且順序正確。下面的腳本演示了 array_is_list 函數(shù):

<?php

echo array_is_list([]);
echo array_is_list(['1', 2, 3]);
echo array_is_list([0 => 'a', 'b']);

echo array_is_list([1 => 'a', 'b']); // false
echo array_is_list([1 => 'a', 0 => 'b']); // false
echo array_is_list([0 => 'a', 'b' => 'b']); // false
echo array_is_list([0 => 'a', 2 => 'b']); // false

輸出為:

1
1
1

魔術(shù)方法必須要有正確的簽名

魔術(shù)方法是 PHP 中用于覆蓋默認(rèn)**作的特殊方法。它們包括如下的方法,其中構(gòu)造函數(shù) __construct() 可能是大家最熟悉的:

__construct(),
__destruct(),
__call(),
__callStatic(),
__get(),
__set(),
__isset(),
__unset(),
__sleep(),
__wakeup(),
__serialize(),
__unserialize(),
__toString(),
__invoke(),
__set_state(),
__clone(),
__debugInfo()

從 PHP 8.0 開(kāi)始,魔術(shù)方法定義的簽名必須要是正確的,這意味著如果在方法參數(shù)或返回類(lèi)型中使用類(lèi)型聲明,則它們必須與文檔中的聲明相同。新的 __toString() 方法的返回類(lèi)型必須要聲明為 string 。下面的演示將返回類(lèi)型聲明為 int

<?php

class A {

public function __toString(): int {
}
}

將生成如下的錯(cuò)誤信息:

致命錯(cuò)誤:A::__toString():返回類(lèi)型在聲明時(shí)必須是字符串

但是,未通過(guò)定義聲明返回類(lèi)型的函數(shù)(如構(gòu)造函數(shù))不能聲明返回類(lèi)型,即使是 void 返回類(lèi)型也不行。示例如下腳本所示:

<?php

class A {
public function __construct():void
{

}
}

該腳本將返回如下的錯(cuò)誤信息:

致命錯(cuò)誤:方法A::__construct()不能聲明返回類(lèi)型

所有魔術(shù)方法,除了少數(shù)例外(例如 __construct() )外,都必須聲明為具有公共可見(jiàn)性。為了演示這一點(diǎn),聲明了一個(gè)帶有 private 可見(jiàn)性的 __callStatic

<?php

class A {

private static function __callStatic(string $name, array $arguments) {}

}

輸出的警告信息為:

警告:魔術(shù)方法A::__callStatic()必須要具有公共可見(jiàn)性

盡管可以省略混合返回類(lèi)型,但方法簽名也必須相同。例如,在下面的腳本中,類(lèi) A 聲明了 __callStatic 而沒(méi)有指定其返回類(lèi)型,而類(lèi) B 將其第一個(gè)參數(shù)定義為int

<?php

class A {

public static function __callStatic(string $name, array $arguments) {}

class B {

public static function __callStatic(int $name, array $arguments) {}

}

輸出的錯(cuò)誤信息如下所示:

致命錯(cuò)誤:B::__callStatic():參數(shù) #1 ($name) 在聲明時(shí)必須為字符串類(lèi)型

返回類(lèi)型與內(nèi)部類(lèi)的兼容性

在 PHP 8.1 中,大多數(shù)內(nèi)部方法,即內(nèi)部類(lèi)中的方法,都已經(jīng)“試探性地”開(kāi)始聲明返回類(lèi)型。試探性地暗示,雖然在 8.1 中只會(huì)引發(fā)不推薦(Deprecation)通知,但在 9.0 版中,則會(huì)輸出錯(cuò)誤條件信息。因此,任何擴(kuò)展類(lèi)都必須聲明與內(nèi)部類(lèi)相兼容的返回類(lèi)型,否則將會(huì)引發(fā)已棄用(不推薦)通知。為了演示這一點(diǎn),擴(kuò)展內(nèi)部類(lèi) Directory 并重新聲明沒(méi)有返回類(lèi)型的函數(shù) read()

<?php

class A extends Directory {
public function read() { }
}

該腳本將生成已棄用(不推薦)通知:

<?php

class A extends Directory {
public function read():string { return ""; }
}

但是,以下腳本是可以的:

<?php

class A extends Directory {
public function read():string { return ""; }
}

添加 #[\ReturnTypeWillChange] 屬性能抑制已棄用(不推薦)通知:

<?php
class A extends Directory {
#[\ReturnTypeWillChange]
public function read() { }
}

\SensitiveParameter 屬性

雖然包含有關(guān)方法參數(shù)的詳細(xì)信息的異常堆棧跟蹤對(duì)調(diào)試非常有用,但你可能不希望輸出某些敏感參數(shù)的參數(shù)值,例如與密碼和憑據(jù)關(guān)聯(lián)的參數(shù)值。PHP 8.2 引入了一個(gè)名為 \SensitiveParameter 的新屬性,這樣,如果使用 \SensitivyParameter 屬性注解方法的參數(shù),則該參數(shù)的值不會(huì)在異常堆棧跟蹤中輸出。

為了演示這一點(diǎn),考慮下面的腳本,其中函數(shù) f1 具有與 \SensitiveParameter 屬性關(guān)聯(lián)的參數(shù) $password

<?php

function f1(
$param1 = 1,
#[\SensitiveParameter] $password = “s@5f_u7”,
$param3 = null
) {
throw new \Exception('Error');
}

為了演示 \SensitiveParameter 特性,該函數(shù)只是拋出一個(gè)異常。調(diào)用函數(shù):

f1(param3: 'a');

請(qǐng)注意,異常堆棧跟蹤不包含 $password 參數(shù)的值,而是列出了 Object(SensitiveParameterValue)

Stack trace: #0 : f1(1, Object(SensitiveParameterValue), 'a') #1 {main}

內(nèi)置函數(shù)棄用/增強(qiáng)

內(nèi)置函數(shù) utf8_encode()utf8_decode() 經(jīng)常被誤解,因?yàn)樗鼈兊拿Q(chēng)意味著對(duì)任何字符串進(jìn)行編碼/解碼。實(shí)際上,這些函數(shù)僅用于編碼/解碼 ISO8859-1,即“Latin-1”字符串。此外,它們生成的錯(cuò)誤信息對(duì)于調(diào)試來(lái)說(shuō)描述性不夠。PHP 8.2 已經(jīng)棄用了這些函數(shù)。下面的腳本使用了它們:

<?php

$string_to_encode = "\x7A\x6A\xdB";
$utf8_string = utf8_encode($string_to_encode);
echo bin2hex($utf8_string), "\n";
$utf8_string = "\x6A\x6B\xD3\xCB";
$decoded_string = utf8_decode($utf8_string);
echo bin2hex($decoded_string), "\n";

對(duì)于 PHP 8.2,會(huì)輸出已棄用(不推薦)通知:

已棄用(不推薦):函數(shù)utf8_encode()已棄用
已棄用(不推薦):函數(shù)utf8_decode()已棄用

在 PHP 8.2 中,函數(shù) iterator_countiterator_to_array 接受所有可迭代的對(duì)象。 iterator_to_array() 函數(shù)將迭代器的元素**到數(shù)組中。 iterator_count() 函數(shù)對(duì)數(shù)組的元素進(jìn)行計(jì)數(shù)。這些函數(shù)接受一個(gè) $iterator 作為第一個(gè)參數(shù)。在 PHP 8.2 中,$iterator 參數(shù)的類(lèi)型已從 Traversable 擴(kuò)展為 Traversable|array ,以便接受任意的可迭代值。

下面的腳本演示了它們?cè)?arraysTraversables 中的使用。

<?php

$a=array('1'=>'one', 'two', 'three', 'four');
$iterator = new ArrayIterator($a);
var_dump(iterator_to_array($iterator, true));
var_dump(iterator_to_array($a, true));

var_dump(iterator_count($iterator));
var_dump(iterator_count($a));

輸出如下所示:

array(4) { [1]=> string(3) "one" [2]=> string(3) "two" [3]=> string(5) "three" [4]=> string(4) "four" }
array(4) { [1]=> string(3) "one" [2]=> string(3) "two" [3]=> string(5) "three" [4]=> string(4) "four" }
int(4)
int(4)

小編綜合來(lái)說(shuō)

在這篇 PHP 8 系列文章中,我們討論了與函數(shù)和方法相關(guān)的新特性,其中最突出的是命名函數(shù)的形參/實(shí)參、簡(jiǎn)化的可調(diào)用語(yǔ)法和被稱(chēng)為纖程(Fiber)的可中斷函數(shù)。

在本系列的下一篇文章中,我們將介紹 PHP 類(lèi)型系統(tǒng)的新特性。

PHP 8:注解、match 表達(dá)式及其他改進(jìn)

PHP 8:類(lèi)和枚

拓展知識(shí):

原創(chuàng)文章,作者:九賢生活小編,如若轉(zhuǎn)載,請(qǐng)注明出處:http://www.cddhlm.com/4643.html