这篇文章仅仅是我在思考如何更改PHP以使其更好。这是一个非常主观的清单,绝不是对核心团队正在完成的出色工作的批评。

默认为Final

关于OO编程的一个常见误解是,它全都与继承有关。继承和多态性都有它们的位置,但是OO远不止于此。

因为声称程序员编写“ OO”代码的程序员经常滥用这些原则,所以我认为该语言应有助于防止我们犯这些错误。

这就是为什么我将所有类默认设置为final:

final class Foo
{
}
class Bar extends Foo
{
}

此外:类仅允许从抽象类扩展或实现接口。这样我们可以防止具体类的深层继承链。

默认Void

在所有编程语言中,Void都是一种奇怪的野兽:它是“类型”,表示缺少类型。

为什么不采用明显的方式:没有返回类型,则意味着什么也不会返回。

class Foo
{
    public function bar(): void
    {
        // …
    }
}
class Foo
{
    public function bar()
    {
        return false;
    }
}

现在您可能在想:如果一个函数要返回两种类型,那是下一步。

没有mixed类型

mixed类型的基本含义是:“您不知道此功能需要什么或将要返回,请自行解决”。

这种松散类型的系统可能是许多错误的根源。如果您需要在同一函数中使用两种不同的类型,则应该执行两种实现-这就是多态性所在的位置;或者您应该编程一个接口。

无论哪种方式,有一个更好的解决方案,然后再依靠mixed。在我的PHP版本中,该语言将确保我们始终选择更好的解决方案。

所有参数必须声明类型

我们已经确定我的PHP版本将需要返回类型。函数参数也是如此也就不足为奇了。

public function handle($bar)
{
}
public function handle(Bar $bar)
{
}

类属性必须声明类型

相同的规则适用于类属性。对我们来说幸运的是,PHP 7.4将引入类型化属性。我会要求他们。

class Foo
{
    public $bar;
}
class Foo
{
    public Bar $bar;
}

可见性修饰符是必需的

显式消除了混淆的空间。这就是为什么所有方法和类变量都必须具有可见性修饰符的原因。

class Foo
{
    function bar()
    {
        // …
    }
} 
class Foo
{
    public function bar()
    {
        // …
    }
} 

Final变量

我说要删除final关键字(即类和方法上的关键字)来开始此列表。 final是将类变量标记为“只读”的有效关键字。

final变量可以在构造函数上设置,以后不能更改。

class Foo
{
    public final Bar $bar;
    
    public __construct(Bar $bar)
    {
        $this->bar = $bar;
    }
}
$foo = new Foo($bar);

$foo->bar = new Bar();

没有更多的未初始化状态

构造后,PHP 7.4中的类型化属性可以保留为未初始化。

class Foo
{
    public string $bar;
    
    public function __construct() {
        // Don't initialize bar
    }
}

$foo = new Foo();

$foo->bar = 'abc';

仅在初始化属性之前访问该属性时,PHP才会引发错误。

$foo = new Foo();

echo $foo->bar; // Error

我想摆脱这种行为。如果在构造对象之后未初始化类型化的属性,则会收到错误消息。

命名参数

让我们允许将命名参数传递给函数:

function foo(Bar $bar, string $string, ?int $optional = null)
{
    // …
}

foo(
    $optional = 1,
    $baz = new Baz(),
    $bar = new Bar(),
    $string = 'abc', 
);

多行短闭包

这个不需要太多解释。

fn($a, $b) => {
    $c = $a + $b;

    return $a + $b;
}

标量类型也是对象

我认为我们都同意的几件事之一:当前的PHP函数名称和定义不一致,有点让人讨厌。

让我们将所有标量类型都视为对象,让它们包含否则将是独立函数的对象。

public function handle(): String
{
    return "a, b, c";
}

$this->handle()->explode(',');

改善方差

您可能已经注意到上述变化的趋势。它们大多数与PHP的类型系统有关。如果全部添加了,我们还需要使当前的类型系统更加灵活。

再次幸运的是,PHP 7.4已经引入了有关类型差异的改进

class Bar extends Foo { /* … */ }
interface A
{
    public function handle(Bar $bar): Foo;
}

class B implements A
{
    public function handle(Foo $bar): Bar
    {
        // …
    }
}

始终严格的类型检查

默认情况下,是严格类型检查的,您永远都不需要声明declare(strict_types=1);

泛型

在对类型系统进行一些改进之后,我将添加一些实际使用它的改进方法。

首先,可能是大多数PHP世界都在等待的功能:泛型。

class List<T>
{
    public function current(): T
    {
        // …
    }
}

枚举

下一步:内置枚举。根据几种 用户态 实现 ,很明显,社区将从内置的枚举类型中受益。

enum Status 
{
    DRAFT, STATUS, PUBLISHED;
}
class Bar
{
    public Status $status;
}
$bar->status = Status::DRAFT;

结构体

结束此列表:结构体。我一直使用的自己的软件包之一是数据传输对象软件包。它允许我们定义强类型的对象。本质上,它们是结构体要解决的用户级实现。

struct Point {
    Int $x;
    Int $y;
}
$point = Point {1, 2}

这是Java!

在提议改进类型系统时,我经常听到PHP程序员常说的话。请记住,编程语言不仅是语法,还包括:整个框架和软件包的生态系统,使像PHP这样的语言具有真正的价值。

via https://stitcher.io/blog/php-reimagined

最后更新于 2020年3月28日

重新构想PHP
标签: