盘点总结Php8.0开发中常用的一些特性
联合类型(Union types)
PHP 中的联合类型允许您指定变量或函数参数可以接受多种类型。此功能是在 PHP 8.0 中引入的,目的是在类型声明中提供更大的灵活性。联合类型使用|来联合数据类型
下面是一个演示 PHP 中联合类型用法的示例:
function processValue(int|float|string $value): void { if (is_int($value)) { echo "Processing an integer: $value\n"; } elseif (is_float($value)) { echo "Processing a float: $value\n"; } elseif (is_string($value)) { echo "Processing a string: $value\n"; } else { echo "Invalid value!\n"; } } $value1 = 42; $value2 = 3.14; $value3 = "Hello"; processValue($value1); processValue($value2); processValue($value3);
在此示例中, processValue 函数接受类型 int 、 float 或 string 的参数 $value 。这是使用联合类型声明 int|float|string 指定的。在函数内部,我们可以使用条件语句(6, elseif )和类型检查函数( is_int() , is_float() , is_string() )来适当地处理不同的类型。
调用 processValue 函数时,我们可以传递任何指定类型( int 、 float 或 string )的变量。该函数将根据参数的实际类型处理每种情况。
联合类型允许您在类型声明中更具表现力,并在使用可接受多种类型的变量或函数参数时提供更大的灵活性。它有助于提高类型安全性并防止运行时与类型相关的错误。
可空类型(Nullable types)
可为 null 的类型允许您指示变量或函数参数可以接受特定类型或为 null 。PHP 7.1 中引入了可为空的类型,作为增强类型安全性和表示变量或参数为 null 的可能性的一种方式。
若要声明可为 null 的类型,可以在类型名称前使用问号 ( ? )。下面是一个示例:
function processValue(?string $value): void { if ($value !== null) { echo "Processing string: $value\n"; } else { echo "Value is null\n"; } } $value1 = "Hello"; $value2 = null; processValue($value1); // Output: Processing string: Hello processValue($value2); // Output: Value is null
在本示例中, processValue 函数接受可以是 string 或 null 的参数 $value 。 ?string 类型声明指示参数可以接受字符串值或为 null 。
在函数内部,我们在处理之前使用 !== 运算符检查该值是否不为 null。这样,我们可以处理值为 null 的情况,而不是处理有效字符串的情况。
使用 nullable 类型有助于使代码更明确地说明 null 值的可能性,这可以防止与 null 相关的错误并提高代码清晰度。
值得注意的是,从 PHP 7.1 开始,可为空的类型只能用于基本类型和自定义类。
数组解构
在之前php7版本中,我们都用list来解构索引数组。解构允许您以方便的方式将数组中的值分配给各个变量。下面是使用 list() 进行数组解构的示例:
$array = ['Apple', 'Banana', 'Cherry']; list($fruit1, $fruit2, $fruit3) = $array; echo $fruit1; // Output: Apple echo $fruit2; // Output: Banana echo $fruit3; // Output: Cherry
在此示例中,list() 函数用于解构索引数组 $array 。变量 $fruit1 、 $fruit2 和 $fruit3 被分配了数组中的相应值。
但在php8之后,我们直接使用方括号语法进行数组解构:
$array = ['Apple', 'Banana', 'Cherry']; [$fruit1, $fruit2, $fruit3] = $array; echo $fruit1; // Output: Apple echo $fruit2; // Output: Banana echo $fruit3; // Output: Cherry
在这种情况下,方括号用于将数组 $array 分解为单独的变量 $fruit1 、 $fruit2 和 $fruit3 。
需要注意的是,左侧的变量数(在 list() 或方括号语法中)必须与数组中的元素数匹配。否则,您可能会遇到“未定义的偏移量”或“未定义的变量”错误。
您也可以通过在左侧保留空插槽来仅解构数组的一部分:
$array = ['Apple', 'Banana', 'Cherry', 'Durian']; [, $fruit2, $fruit3] = $array; echo $fruit2; // Output: Banana echo $fruit3; // Output: Cherry
使用赋值左侧的空插槽 ( , ) 跳过数组的第一个元素。数组解构提供了一种从索引数组中提取值并将其分配给各个变量以供进一步处理的便捷方法。
我们还可以使用方括号语法来解构关联数组(key非数字索引)。
$array = ['name' => 'John', 'age' => 30, 'city' => 'New York']; ['name' => $name, 'age' => $age, 'city' => $city] = $array; echo $name; // Output: John echo $age; // Output: 30 echo $city; // Output: New York
在此示例中,方括号用于解构关联数组 $array 。变量 $name 、 $age 和 $city 根据其键从数组中分配相应的值。
请务必注意,左侧指定的键必须与关联数组中的键匹配。否则,将不会为变量分配正确的值。
您也可以仅解构关联数组的一部分,类似于索引数组:
$array = ['name' => 'John', 'age' => 30, 'city' => 'New York']; ['name' => $name, 'city' => $city] = $array; echo $name; // Output: John echo $city; // Output: New York
空合并运算符
空合并运算符 (??) 是 PHP 7 中引入的一项功能,它提供了一种简洁的方式来处理空值。它允许您为变量分配默认值(如果它为 null)。空合并运算符的语法如下:
$variable = $value ?? $default;
它的工作原理如下:
• 如果 $value 不为 null,则将值 $value 赋值为 $variable 。
• 如果 $value 为 null,则将值 $default 赋给 $variable 。
下面是一个示例来说明其用法:
$name = $_POST['name'] ?? 'Anonymous';
在此示例中,如果设置了 $_POST['name'] 变量而不是 null,则其值将赋值为 $name 。但是,如果未设置 $_POST['name'] 或为 null,则字符串 'Anonymous' 将分配给 $name 。
还可以链接空合并运算符以处理多个级别的空值。下面是一个示例:
$result = $value1 ?? $value2 ?? $value3 ?? 'Default';
在这种情况下,如果 $value1 不为 null,则其值将赋值为 $result 。如果 $value1 为 null,则进程继续到 $value2 。如果 $value2 也为 null,则进程继续到 $value3 。如果所有值都为 null,则字符串 'Default' 将分配给 $result 。
null 合并运算符在处理可选或可为 null 的变量时很有用,它提供了一种在不使用条件语句或三元运算符的情况下分配默认值的便捷方法。
这里需要和?:做一个区别对比,看下面示例:
<?php $value1 = 0; $value2 = null; $value3 = false; $result1 = $value1 ?? $value2 ?? $value3 ?? 'Default'; $result2 = $value1 ?: $value2 ?: $value3 ?: 'Default'; echo $result1; //echo 0 echo $result2; // echo 'default'
?:除了接收null,0,‘’,false等标量也加入判断
生成器函数
生成器函数提供了一种定义迭代器的替代方法。您可以使用 Generator 函数创建动态生成值的迭代器,而不是创建实现迭代器接口的迭代器类。
生成器函数是使用 function 关键字定义的,但它包含 yield 关键字以指定要生成的值。当函数中遇到 yield 语句时,它会暂时暂停函数的执行并返回生成的值。然后,当迭代器请求下一个值时,可以从中断的位置恢复该函数。
下面是生成数字序列的简单生成器函数的示例:
function numberGenerator($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { yield $i; } } // Create a generator object $generator = numberGenerator(1, 10, 2); // Iterate over the generator values foreach ($generator as $number) { echo $number . ' '; }
在上面的示例中, numberGenerator() 函数被定义为生成器函数。它需要三个参数: $start 、 $end 和一个可选的 $step 参数。该函数使用 for 循环生成从 $start 到 $end 的数字,并指定 $step 。 yield 语句用于生成每个生成的数字。
要使用 Generator 函数,我们通过像常规函数一样调用函数来创建生成器对象。然后,我们可以使用 foreach 循环遍历生成器对象。循环的每次迭代都将检索函数生成的下一个值,并将其分配给 $number 变量。
当在生成器函数中遇到 yield 语句时,函数的执行将暂停,并返回生成的值。将保存函数状态,允许在请求下一个值时从中断的位置恢复函数状态。
生成器函数提供了一种节省内存的方式来迭代大型数据集或动态生成值,而无需一次将所有值存储在内存中。在需要处理不需要完全加载到内存中的大量数据的情况下,它们特别有用。
Traits
Traits是一种机制,它允许在类中重用代码,而无需使用传统的类继承。特征提供了一种在不同类之间水平共享方法和属性的方法。Traits不需要多做介绍了,其在现代php开发中随处可见
特征是使用 trait 关键字后跟特征名称定义的。在特征中,可以定义可由包含特征的类使用的方法和属性。下面是一个特征的示例:
trait Loggable { public function log($message) { echo "Logging: " . $message . "\n"; } }
在上面的示例中, Loggable 特征定义了一个名为 log() 的单个方法。此特征可以包含在其他类中,以使 log() 方法可用于这些类。
要在类中使用特征,请使用 use 关键字,后跟特征名称。下面是包含 Loggable 特征的类的示例:
class MyClass { use Loggable; public function doSomething() { $this->log("Doing something..."); } }
在此示例中, MyClass 包括使用 use 关键字的 Loggable 特征。结果,特征中定义的 log() 方法在 MyClass .然后, MyClass 中的 doSomething() 方法可以调用 log() 方法,就好像它是直接在 MyClass 中定义的一样。
特征允许您使用可重用的功能组合类,从而提供了一种跨不同类混合和匹配行为的方法,而不受单一继承的限制。您可以通过在 use 语句中用逗号分隔多个特征来在一个类中包含多个特征。
请务必注意,特征不能直接实例化,也没有自己的状态。它们旨在用作在类之间共享代码的一种方式。
特征可以成为代码重用和组织的强大工具,但应明智地使用它们以保持代码清晰度并避免过于复杂。
匿名类
匿名类提供了一种动态创建类的方法,而无需显式定义命名类。匿名类是使用 new class 语法后跟类定义的。
下面是创建匿名类的示例:
$object = new class { public function doSomething() { echo "Doing something...\n"; } }; $object->doSomething(); // Output: Doing something...
在上面的示例中,使用 new class 语法创建了一个匿名类。类定义括在大括号 {} 中。在类定义中,可以定义方法、属性并执行其他与类相关的操作。
匿名类在需要为特定目的创建小型自包含类而无需命名类的情况下非常有用。它们通常用于实现接口、扩展抽象类或创建一次性使用对象。
下面是使用匿名类实现接口的示例:
interface Logger { public function log($message); } $logger = new class implements Logger { public function log($message) { echo "Logging: " . $message . "\n"; } }; $logger->log("Hello, world!"); // Output: Logging: Hello, world!
在此示例中,将创建一个实现 Logger 接口的匿名类。类定义包括在接口中定义的 log() 方法。
匿名类还可以扩展其他类或用作闭包,从而在创建动态对象时具有更大的灵活性。
请务必注意,匿名类的实例化和使用方式与任何其他对象相同。但是,由于它们没有名称,因此无法在代码中的其他位置引用它们。匿名类的每个实例都是唯一的,并且与其他实例没有共享状态。
匿名类是 PHP 中的一项强大功能,它支持动态类创建和代码组织。在需要动态创建小型专用类或对象的情况下,它们特别有用。
空安全运算符
空安全运算符(PHP Nullsafe) 是 PHP 8.0 中引入的一项新功能。它提供了一种访问对象上的属性和方法的便捷方法,而无需显式检查 null 值。
在 PHP 8.0 之前,如果要访问对象上的属性或调用方法,通常必须在执行此操作之前检查对象是否为 null,以避免“null 指针”错误。例如:
if ($object !== null) { $object->doSomething(); }
使用 Nullsafe 运算符,可以更简洁的方式执行相同的操作。null safe 运算符由问号后跟箭头 (->) 运算符表示,如下所示:
$object?->doSomething();
如果 $object 为 null,则表达式将正常返回 null,而不是引发错误。此运算符实质上是使表达式短路,如果任何中间属性或方法为 null,则停止计算表达式。
还可以使用 null-safe 运算符将多个属性和方法链接在一起:
$value = $object?->getProperty()?->doSomething();
在此示例中,如果 $object 或 getProperty() 方法返回 null,则将为 $value 变量分配 null,并且不会调用后续的 doSomething() 方法。
Nullsafe 运算符是 PHP 的一个方便的补充,因为它简化了空值处理并减少了对显式空检查的需求。但是,重要的是要明智地使用它,并确保它不会导致代码更难理解或调试。
可变参数
在 PHP 中,可变参数(也称为可变长度参数列表)允许函数接受任意数量的参数。此功能从 PHP 5.6 开始可用。
若要定义可变参数,请在函数声明中的参数名称前使用三个点 ( ... )。例如:
function sum(...$numbers) { $total = 0; foreach ($numbers as $number) { $total += $number; } return $total; }
在此示例中, sum() 函数接受任意数量的参数。可变参数 $numbers 充当包含所有传递参数的数组。然后,您可以迭代 $numbers 并执行所需的操作
下面介绍如何将 sum() 函数与不同数量的参数一起使用:
echo sum(1, 2, 3); // Output: 6 echo sum(4, 5, 6, 7, 8); // Output: 30 echo sum(10); // Output: 10 echo sum(); // Output: 0
您还可以在函数声明中将可变参数与常规参数组合在一起。但是,可变参数必须是函数签名中的最后一个参数。
function concatenate($separator, ...$strings) { return implode($separator, $strings); }
在此示例中, concatenate() 函数将分隔符作为第一个参数,然后是任意数量的字符串。可变参数 $strings 捕获所有其他参数。
echo concatenate("-", "Hello", "world"); // Output: Hello-world echo concatenate(",", "apple", "banana", "orange"); // Output: apple,banana,orange
当您想要处理函数中不同数量的参数时,可变参数提供了灵活性。当您事先不知道将向函数传递多少参数时,它们特别有用。
参数解包
参数解包,也称为 splat 运算符或可变参数函数,是 PHP 中的一项功能,允许您将数组或可迭代作为单个参数传递给函数或方法。它是在 PHP 5.6 中引入的。
若要使用参数解包,请在数组或可迭代变量前面加上三个点 (...)。当函数或方法被调用时,PHP 将自动解压缩数组或可迭代对象的元素,并将它们作为单独的参数传递。
下面是一个示例来说明参数解包的工作原理:
function addNumbers($a, $b, $c) { return $a + $b + $c; } $numbers = [2, 4, 6]; $result = addNumbers(...$numbers); echo $result; // Output: 12
在上面的示例中, addNumbers 函数需要三个单独的参数。但是,我们不是单独传递参数,而是使用参数解包传递 $numbers 数组。PHP 将解压缩数组的元素( 2 , 4 , 6 ),并将它们作为单独的参数传递给函数。结果为 2 + 4 + 6 = 12 。
您还可以将参数解包与可变参数函数一起使用,可变参数函数是接受可变数量参数的函数。在这种情况下,您可以将解压缩与其他参数结合使用。下面是一个示例:
function concatenateStrings($separator, ...$strings) { return implode($separator, $strings); } $result = concatenateStrings(', ', 'apple', 'banana', 'orange'); echo $result; // Output: apple, banana, orange
在此示例中, concatenateStrings 函数接受分隔符作为第一个参数,接受任意数量的字符串作为后续参数。 ...$strings 语法允许您传递多个参数,这些参数将被打包到一个数组中。在这种情况下,该函数使用 implode 将字符串与指定的分隔符连接起来。
当您在数组或可迭代对象中有数据并希望将其作为单独的参数传递给函数或方法时,参数解包是一项有用的功能。
命名参数
命名参数是 PHP 8.0 中引入的一项功能,参考了python,它允许您通过指定参数名称及其相应的值来传递函数或方法参数。此功能在调用具有大量参数的函数或想要跳过可选参数时提供了更大的灵活性和清晰度。
下面是在 PHP 中使用命名参数的示例:
function greet($name, $age, $city) { echo "Hello, $name! You are $age years old and live in $city."; } // Calling the function with named arguments greet(name: "John", age: 30, city: "New York");
在上面的例子中,我们使用命名参数调用 greet() 函数。我们不是依赖于参数的位置顺序,而是显式提及参数名称,后跟相应的值。这使得代码更具可读性和不言自明。
命名参数还允许您跳过可选参数或按任意顺序指定它们。下面是一个示例:
function generateGreeting($name, $age = 25, $city = "Unknown") { echo "Hello, $name! You are $age years old and live in $city."; } // Calling the function with skipped and unordered named arguments generateGreeting(city: "London", name: "Alice");
在这种情况下,我们调用 generateGreeting() 函数并仅提供 name 和 city 参数,跳过 age 参数。将自动使用 age 的默认值,并且可以按任意顺序指定参数。
PHP 中的命名参数有助于提高代码的可读性和可维护性,并使使用具有许多参数或可选参数的函数变得更加容易。
命名变量
命名可变参数,也称为带有命名参数的可变参数函数,是 PHP 8 中引入的一项功能。命名可变参数允许您将可变数量的参数传递给函数,其中每个参数都与特定的参数名称相关联。此功能通过提供一种基于参数名称指定参数的便捷方法,增强了可变参数函数的灵活性和可读性。
下面是在 PHP 中使用命名可变参数的示例:
function processItems(...$items) { foreach ($items as $item) { // Process each item echo "Processing item: $item" . PHP_EOL; } } function processItemsWithNames(...$items) { foreach ($items as $name => $item) { // Process each item with its associated name echo "Processing item '$name': $item" . PHP_EOL; } } // Example usage processItems('Apple', 'Banana', 'Orange'); /* Output: Processing item: Apple Processing item: Banana Processing item: Orange */ processItemsWithNames('fruit' => 'Apple', 'snack' => 'Banana', 'citrus' => 'Orange'); /* Output: Processing item 'fruit': Apple Processing item 'snack': Banana Processing item 'citrus': Orange */
在第一个示例中, processItems() 函数使用 ...$items 语法接受可变数量的参数。它遍历 $items 数组并处理每个项目。
在第二个示例中, processItemsWithNames() 函数还采用可变数量的参数,但每个参数都与特定的参数名称相关联。该函数使用 foreach 循环遍历 $items 数组,其中键表示参数名称,值表示相应的参数。
命名可变参数提供了一种更具表现力的方式来传递和处理变量参数,尤其是当参数在函数中具有不同的含义或角色时。它通过将每个参数与参数名称显式关联来提高代码的可读性,使代码更具自我文档化且更易于理解。
箭头函数
箭头函数是 PHP 7.4 中引入的一项功能,它为定义匿名函数提供了更简洁的语法。箭头函数使代码更具可读性,并减少传统匿名函数语法的冗长程度。
下面是一个示例来说明 PHP 中箭头函数的用法:
// Traditional anonymous function $addition = function ($a, $b) { return $a + $b; }; // Short closure (arrow function) $addition = fn($a, $b) => $a + $b; // Example usage echo $addition(2, 3); // Output: 5
在上面的示例中,传统的匿名函数 $addition 采用两个参数 $a 和 $b ,并返回它们的总和。等效的短闭合版本是 fn($a, $b) => $a + $b 。箭头 ( => ) 将参数与执行和返回的表达式或语句分开。
箭头函数具有以下特点:
• 简洁语法:与传统匿名函数中使用的 function 关键字相比,短闭包使用紧凑的语法 (0)。这会产生更清晰、更易读的代码。
• 隐式返回:如果短闭包由单个表达式组成,PHP 会自动返回该表达式的结果。在该示例中,直接返回表达式 $a + $b ,而无需 return 关键字。
• 继承的作用域:短闭包从周围的作用域继承变量,类似于传统的匿名函数。这意味着它们可以访问在闭包外部定义的变量,而无需将它们显式作为参数传递。
• 仅限于表达式:短闭包仅限于单个表达式。它们不能包含多个语句或复杂的逻辑。如果需要更复杂的功能,则应使用传统的匿名函数。
箭头函数在需要将小而简单的表达式封装为回调或用于函数式编程结构(如数组函数( array_map 、 array_filter 等)或高阶函数)的情况下特别有用。
匹配表达式
match 表达式,也称为 match 语句或 match 表达式,是 PHP 8.0 中引入的一项功能。它提供了一种简洁而富有表现力的方式来针对值执行模式匹配,并根据匹配的模式执行不同的代码块。match 表达式类似于 switch 语句,但提供了更大的灵活性和可读性。
下面是一个示例来演示 PHP 中匹配表达式的用法:
$value = 2; $result = match ($value) { 1 => 'One', 2 => 'Two', 3, 4 => 'Three or Four', default => 'Other' }; echo $result; // Output: Two
在上面的示例中,match 表达式用于将变量 $value 的值与不同的模式进行匹配。右箭头 ( => ) 将模式与相应的代码块分开。如果模式匹配,则执行相应的代码块。如果没有模式匹配,则执行与 default 关键字关联的代码块。
匹配表达式具有以下特征:
• 基于值的匹配:匹配表达式将匹配的值与模式进行比较。它允许简单的值匹配,以及范围、列表和模式组合。
• 单一匹配:匹配表达式在找到第一个匹配模式后立即停止执行。与 switch 语句不同,它不会落入后续模式。
• 穷举性检查:匹配表达式要求涵盖所有可能的情况。如果值与提供的任何模式都不匹配,并且没有 default 大小写,则将抛出 UnhandledMatchError 。
• 表达式结果:match 表达式返回匹配代码块的结果,允许您将其分配给变量或直接在代码中使用它。
在处理复杂的条件逻辑或需要根据变量的值执行不同的操作时,match 表达式特别有用。它为多个 if-else 语句或 switch 语句提供了一种更具可读性和简洁性的替代方案。
需要注意的是,匹配表达式是在 PHP 8.0 中引入的。如果您使用的是早期版本的 PHP,则匹配表达式可能不可用。
Stringable接口
PHP 中的 0 接口是 PHP 8.0 中引入的一项新功能。它是一个内置接口,允许对象在字符串上下文中使用时自动转换为字符串,例如当它们与其他字符串连接或将它们传递给需要字符串参数的函数时。
Stringable 接口定义如下:
interface Stringable { public function __toString(): string; }
若要使对象实现 Stringable 接口,需要在返回对象的字符串表示形式的类中定义一个 __toString() 方法。此方法不应没有参数,并且必须返回字符串。
下面是实现 Stringable 接口的类的示例:
class MyClass implements Stringable { private $name; public function __construct($name) { $this->name = $name; } public function __toString(): string { return "Hello, " . $this->name; } } $obj = new MyClass("John"); echo $obj; // Output: Hello, John
在上面的示例中, MyClass 通过定义 __toString() 方法实现 Stringable 接口。当 $obj 实例在字符串上下文中使用时(例如,当它被回显时),PHP 会自动调用 __toString() 方法来获取对象的字符串表示形式。
使用 Stringable 接口可以简化代码,允许在必要时将对象视为字符串,而无需显式调用方法来转换它们。
PHP8.0
PHP开发
后端开发
阅读排行
-
1. 几行代码就能实现Html大转盘抽奖
大转盘抽奖是网络互动营销的一种常见形式,其通过简单易懂的界面设计,让用户在游戏中体验到乐趣,同时也能增加商家与用户之间的互动。本文将详细介绍如何使用HTML,CSS和JavaScript来实现大转盘抽奖的功能。
查看详情 -
2. 微信支付商户申请接入流程
微信支付,是微信向有出售物品/提供服务需求的商家提供推广销售、支付收款、经营分析的整套解决方案,包括多种支付方式,如JSAPI支付、小程序支付、APP支付H5支付等支付方式接入。
查看详情 -
3. 浙江省同区域公司地址变更详细流程
提前准备好所有需要的资料,包含:房屋租赁合同、房产证、营业执照正副本、代理人身份证正反面、承诺书(由于我们公司其中一区域已有注册另外一公司,所以必须需要承诺书)
查看详情 -
4. 阿里云域名ICP网络备案流程
根据《互联网信息服务管理办法》以及《非经营性互联网信息服务备案管理办法》,国家对非经营性互联网信息服务实行备案制度,对经营性互联网信息服务实行许可制度。
查看详情 -
5. 微信小程序申请注册流程
微信小程序注册流程与微信公众号较为相似,同时微信小程序支持通过已认证的微信公众号进行注册申请,无需进行单独认证即可使用,同一个已认证微信公众号可同时绑定注册多个小程序。
查看详情