PHP8.4 新特性,快来看看有你想要的吗?

359 阅读1分钟

image.png

PHP 8.4 将于2024年11月21日发布。它将包括属性钩子HTML 5支持、不对称可见性array_find等等新特性,快来看一看吧!

属性钩子

现代PHP最大的变化之一:能够定义属性钩子,无需大量的样板代码getter()setter()。极大提升了代码编写效率。

class BookViewModel
{
    public function __construct(
        private array $authors,
    ) {}

    public string $credits {
        get {
            return implode(', ', array_map(
                fn (Author $author) => $author->name, 
                $this->authors,
            ));
        }
    }
    
    public Author $mainAuthor {
        set (Author $mainAuthor) {
            $this->authors[] = $mainAuthor;
            $this->mainAuthor = $mainAuthor;
        }
        
        get => $this->mainAuthor;
    }
}

属性钩子的目的是删除大量的gettersetter,不需要为属性的读写单独定义方法,这点改动是值得称赞的。属性钩子也可以运用到interfaceabstract class

interface HasAuthors
{
    public string $credits { get; }
    public Author $mainAuthor { get; set; }
}

abstract class Finder  
{  
    protected abstract string $path {  
        set;  
    }  
}

new without parentheses

new不需要括号也同样可以节省大量的样板代码,提升编码效率,允许使用构造函数的括号来调用一切。

< 8.4

$name = (new ReflectionClass($objectOrClass))->getShortName();

>=8.4

$name = new ReflectionClass($objectOrClass)->getShortName();  # nice

class MyClass extends ArrayObject
{
    const CONSTANT = 'constant';
    public static $staticProperty = 'staticProperty';
    public static function staticMethod(): string { return 'staticMethod'; }
    public $property = 'property';
    public function method(): string { return 'method'; }
    public function __invoke(): string { return '__invoke'; }
}

var_dump(
    new MyClass()::CONSTANT,        // string(8)  "constant"
    new MyClass()::$staticProperty, // string(14) "staticProperty"
    new MyClass()::staticMethod(),  // string(12) "staticMethod"
    new MyClass()->property,        // string(8)  "property"
    new MyClass()->method(),        // string(6)  "method"
    new MyClass()(),                // string(8)  "__invoke"
    new MyClass(['value'])[0],      // string(5)  "value"
);

我不知道你喜不喜欢这个新特性,反正我很喜欢,TypeScript不需要额外的括号,回来写PHP时又要加上括号,极其繁琐。

非对称可见性

在8.4之前,有publicprotectedprivate 属性的读写是根据可见性来确定的,PHP8.4可以单独为写操作单独定义可见性,更细化了属性的管理。

class Book  
{  
    public private( set ) string $name = 'name';  
}

$book = new Book();  
echo $book->name;       // name

// Cannot modify 'private(set)' property outside of 'set' visibility scope
$book->name = 'modify'; 

// 还可以 
class Book  
{  
    public protected( set ) string $name = 'name';  
}

辅助函数

array_find

$firstMatch = array_find(
    $posts, 
    function (Post $post) {
        return strlen($post->title) > 5; 
    }
);

还有几个类似的函数:array_find_key()array_any() 和 array_all()

HTML5支持

PHP 8.4添加了一个\Dom\HTMLDocument类,它能够正确解析HTML5标签。旧的 \DOMDocument类仍然可用于向后兼容。

$doc = \Dom\HTMLDocument::createFromString($contents);

JIT

以前需要将opcache.jit_buffer_size设置为0才能禁用jit,但现在您可以像这样禁用它

opcache.jit=disable
opcache.jit_buffer_size=64m

延迟对象

$initializer = static function (MyClass $proxy): MyClass {
    return new MyClass(123);
};
 
$reflector = new ReflectionClass(MyClass::class);

$object = $reflector->newLazyProxy($initializer);

exit和die

在PHP中,exit(及其别名die)是一种奇怪的东西:它们可以用作关键字,如: exit; 但也可以用作函数:exit(0); 函数变体虽然不是真正的函数,但它的行为有点像函数,但不完全是。

  • 它不支持命名参数
  • 它不能作为可调用对象传递
  • 它忽略了strict_types

但在PHP8.4中,exitdie被视为函数,并且上述所有内容都已修复。但不带括号的关键字仍然可以正常工作,可能在后续版本中会废弃。

#[Deprecated]

之前用于标记弃用的方法使用 /** @deprecated */但是PHP本身并没有用它做任何事情。虽然静态分析器和IDE能够解释这些文档块。

现在可以使用内置的#[Deprecated]标记废弃的函数,还可以添加原数据

#[Deprecated("use newFunction() instead", since: "1.1")]
function oldFunction() {
    // …
}

弃用

默认值为null的参数会自动变为可空,如:

function save(Book $book = null) {}

此行为现已弃用,并将在PHP 9中删除。解决方案是使Book显式为空:

function save(?Book $book = null) {}

觉得喜欢的话,还请分享,点赞,关注。万分感谢!