PHP 7.4中的类型属性(Typed Properties)-PHP7

资源魔 44 0
正在PHP 7.4中增加了类型属性,并对PHP的类型零碎进行了严重改良。这些更改是齐全可选的,而且没有毁坏之前的版本。

正在这篇文章中,咱们将深化理解这个特点,但起首让咱们总结最首要的几点:

● 它们自PHP 7.4起可用

● 它们只正在类中可用,而且需求拜访润饰符:public、protected或private;或var.

● 除了了void以及callable以外,一切类型都是容许的

他们的实际状况是这样的:

class Foo
{
    public int $a;
    public ?string $b = 'foo';
    private Foo $prop;
    protected static string $static = 'default';
}

#未初始化

正在查看风趣的内容以前,起首要探讨类型属性的一个首要方面。

不论你第一眼看到的是甚么,上面的代码是无效的:

class Foo
{
    public int $bar;
}
$foo = new Foo;

即便$bar的值没有是一个整数后,使一个工具Foo, PHP只会抛出一个谬误时,$bar被拜访:

var_dump($foo->bar);
Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization

从谬误音讯中能够看到,有一种新的“变量状态”:未初始化。

假如$bar不类型,则其值将为null。然而类型能够为空,因而无奈确定能否设置了类型为空的属性,或许只是将其遗记了。这就是为何增加了“uninitialized(未初始化)”的缘由。

对于未初始化,要记住四件事:

● 无奈读取未初始化的属性,这样做将招致致命谬误。

● 由于正在拜访属性时会反省未初始化状态,以是能够应用未初始化的属性创立工具,即便其类型不成为空。

● 您能够先写入未初始化的属性,而后再读取它。

● 正在类型属性上应用unset将使其未初始化,而勾销对非类型化属性的设置将使其为null。

特地要留意,上面的代码是无效的,此中正在结构工具之后设置了非初始化的、不成空的属性

class Foo
{
    public int $a;
}
$foo = new Foo;
$foo->a = 1;

尽管仅正在读取属性值时才反省未初始化状态,但正在写入属性值时进行类型验证。这象征着您能够确保任何有效类型都没有会以属性值的方式完结。

#默许值以及结构函数

让咱们细心看看若何初始化键入的值。关于标量类型,能够提供一个默许值:

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}

留意,假如类型其实是空的,则只能应用null作为默许值。这仿佛是不言而喻的,然而有些旧的行为带有参数默许值,此中容许如下操作:

function passNull(int $i = null)
{ /* … */ }
passNull(null);

侥幸的是,类型属性没有容许这类使人困惑的行为。

另请留意,工具或类类型不成能有默许值。您应该应用结构函数来设置它们的默许值。

初始化类型化值的显著中央当然是结构函数:

class Foo{
    private int $a;
    public function __construct(int $a)
    {
        $this->a = $a;
    }
}

但也请记住我后面提到的:正在结构函数内部写入未初始化的属性是无效的。只需不隶属性中读取任何内容,就没有会执行未初始化反省。

#类型的类型

那末终究甚么能够输出,若何输出呢?我曾经提到类型化属性只正在类中无效(今朝),它们需求一个拜访润饰符或var要害字正在它们后面。

关于可用类型,除了了void以及callable以外,简直一切类型均可以应用。

由于void象征着不值,以是不克不及将其用于键入值是无意义的。 callable略微有点差异。

可见,PHP中的“ callable” 能够这样写:

但也请记住我后面提到的:正在结构函数内部写入未初始化的属性是无效的。只需不隶属性中读取任何内容,就没有会执行未初始化反省。

看,一个“callable”正在PHP能够这样写:

$callable = [$this, 'method'];

假定您有如下(有效)代码:

class Foo
{
    public callable $callable;
    
    public function __construct(callable $callable)
    { /* … */ }
}
class Bar
{
    public Foo $foo;
    
    public function __construct()
    {
        $this->foo = new Foo([$this, 'method'])
    }
    
    private function method()
    { /* … */ }
}
$bar = new Bar;
($bar->foo->callable)();

正在本例中,$callable援用公有Bar::办法,然而正在Foo的上下文中被挪用。因为这个成绩,决议没有增加callable的支持。

不外,这没甚么年夜没有了的,由于Closure是一个无效类型,它将记住结构它的$this上下文。

趁便说一句,这是一切可用类型的列表:

● bool

● int

● float

● string

● array

● iterable

● object

● ? (nullable)

● self & parent

● Classes & interfaces

#强迫类型以及严格类型

PHP是咱们喜爱以及厌恶的一种静态言语,它将尽可能地强迫转换类型。假定您正在希冀整数之处通报了一个字符串,PHP将测验考试主动转换该字符串:

function coerce(int $i)
{ /* … */ }
coerce('1'); // 1

一样的准则也实用于类型属性。

上面的代码是无效的,并将“1”转换为1。

class Bar
{
    public int $i;
}
$bar = new Bar;
$bar->i = '1'; // 1

假如您没有喜爱这类行为,能够经过申明严格类型来禁用它:

declare(strict_types=1);
$bar = new Bar;
$bar->i = '1'; // 1
Fatal error: Uncaught TypeError: 
Typed property Bar::$i must be int, string used

#类型差别以及承继

即便PHP 7.4引入了改良的类型差别,但类型属性依然没有变。

这象征着如下内容有效:

class A {}
class B extends A {}
class Foo
{
    public A $prop;
}
class Bar extends Foo
{
    public B $prop;
}
Fatal error: Type of Bar::$prop must be A (as in class Foo)

假如下面的示例仿佛其实不首要,则应查看如下内容:

class Foo
{
    public self $prop;
}
class Bar extends Foo
{
    public self $prop;
}

正在运转代码以前,PHP将正在幕后用它援用的详细类交换self。

这象征着正在本例中会抛出相反的谬误。解决它的惟一办法,是执行如下操作:

class Foo
{
    public Foo $prop;
}
class Bar extends Foo
{
    public Foo $prop;
}

说到承继,您可能会发现很难找到任何好的用例来笼罩承继属性的类型。

尽管我赞同这类观念,但值患上留意的是,能够更改承继属性的类型,但条件是拜访润饰符也从private更改成protected或public。

如下代码无效:

class Foo{
    private int $prop;
}
class Bar extends Foo
{
    public string $prop;
}

然而,没有容许将类型从可为空的类型更改成不成为空或反向的类型。

class Foo
{
    public int $a;
    public ?int $b;
}
class Bar extends Foo
{
    public ?int $a;
    public int $b;
}
Fatal error: Type of Bar::$a must be int (as in class Foo)

翻译:https://stitcher.io/blog/typed-properties-in-php-74

以上就是PHP 7.4中的类型属性(Typed Properties)的具体内容,更多请存眷资源魔其它相干文章!

标签: php7开发教程 php7开发资料 php7开发自学 Php 7.4

抱歉,评论功能暂时关闭!