命名参数

在出现命名参数之前,都是基于位置产生进行传递参数的。出现了命名参数后,就可以不按顺序传递了

function hello($name, $age)
{
    echo "名字是{$name},年龄是{$age}";
}

// 命名参数调用函数
hello(age: 30, name: '小明');

对于类方法也是可以的

class Test
{
    public function __construct($name, $age)
    {
        echo "名字:$name,年龄$age";
    }
}

$testInstance = new Test(age: 35, name: "小明");

需要注意的是,如果有默认参数的时候,需要放在最后,不然命名方式省略默认参数的话,就会报错

// 默认参数最好还是放在最后,不然会提示Deprecated
function hello($name, $sex = '男', $age)
{
    echo "名字是{$name},年龄是{$age},性别:{$sex}";
}

// 命名参数调用函数
hello(age: 30, name: '小明');

联合类型

联合类型允许在函数参数、返回值以及属性的类型声明中指定多个可能的类型。这样一来,可以更灵活地定义变量和函数的类型约束。

function hello(int|string $type): int|string
{
    return $type;
}

echo hello(1);
echo hello('一');

需要注意的是,联合类型并不意味着参数可以同时具有多个类型,而是表示参数可以是其中任意一个类型。

不过标量类型之间,如果没有开启严格模式,如果声明是int,传递了float,也是不会报错的。

构造器属性提升

不需要声明属性,直接在构造函数的参数里声明属性。

class Test
{
    // 声明public属性
    public function __construct(public string $name, public int $age)
    {

    }
}

$test = new Test('小明',35);
echo $test->age;
echo $test->name;

match 表达式

用于简化代码,提高代码的可读。新的match类似于之前的switch和if,并具有以下功能特点:

  1. match是一个表达式,它可以储存到变量中亦可以直接返回
  2. match分支仅支持单行,它不需要一个break;语句
  3. match使用严格比较
  4. 注意:match 表达式_必须_使用分号;结尾

匹配数字和字符串

$num = '2';
$res = match ($num) {
    1 => 'one',
    2 => 'two',
    '2' => '严格比对',
    3, 4, 5 => '多个or的关系',
    default => 'other,最好要有个默认值'
};

echo $res;

更复杂的比对

传递true参数进去,这个比较表达式其实也可以用函数等

$val = -2;

// 匹配结果是否是true
$res = match (true) {
    $val < 0 => '负数',
    $val > 0 => '正数',
    default => '零'
};

echo $res;

Nullsafe 运算符

现在可以用新的nullsafe运算符链式调用,而不需要条件检查null。如果链条中的一个元素失败了,整个链条会中止并认定为Null。

echo $session?->user?->getAddress()?->country;

字符串和数字的比较更符合逻辑了

PHP8比较数字字符串(numeric string)时,都能转数值的话会按数字进行比较。否则,将数字转化为字符串,按字符串比较。

0 == 'foobar' // php7是true
0 == 'foobar' // php7是false

内部函数类型错误的一致性

现在大多数内部函数在参数验证失败时抛出Error级异常。以前php7的话,传递的参数不对的话,还会返回waring级别错误。

末尾逗号

允许参数列表中的末尾逗号,闭包use列表中的末尾逗号

function hello(
    $name,
    $age, // 允许逗号
) use ($a,$b,):void
{

}

新增的函数

看字符串里是否包含某个字符串

str_contains(string $haystack,string $needle);

字符串是否以什么开头

str_starts_with(string $haystack,string $needle);

字符串是否以什么结尾

str_ends_with(string $haystack,string $needle);

新的 fdiv () 函数的作用类似于 fmod () 和 intdiv () 函数,它们允许被 0 整除。您将得到 INF、-INF 或 NaN ,而不是错误,具体取决于大小写。

// INF
echo fdiv(1,0);

JIT即时编译

使用这个的话,可以提高执行效率。开启方法:

opcache.jit=tracing
opcache.jit_buffer_size=100M

注解

原生支持注解,可以用于替换doc,反射的时候可以用

# [name("姓名"),age("年龄")]
function hello(string $name, int $age)
{

}

枚举类型

有点像是调用静态函数一样调用。也是一种类型

enum color {
    case Red;
    case Green;
    case Blue;
}

$color = color::Red;
// enum(color::Red)
var_dump($color);
var_dump($color->name); // "Red"

可以指定值

enum Color: string
{
    case Red = '红色';
    case Green = '绿色';
    case Blue = '蓝色';

    // 可以声明方法
    public function colorName():{

    }
}

var_dump(Color::Red->value);
var_dump(Color::from('红色'));
var_dump(Color::tryFrom('红色'));

只读属性

只读属性,只能初始化赋值一次,不一定在构造函数里,赋值后就不能修改了,也不能被unset。

class Cat
{
    public readonly string $name;

    public function __construct(string $name)
    {
        // 只能初始化一次
        $this->$name = $name;
    }
}

$cat = new Cat('小花');
$cat->name = 1; // 修改报错
最后修改:2024 年 05 月 19 日
如果觉得我的文章对你有用,请随意赞赏