PHP 7.2禁止类名为Object的巨坑

PHP 7.2禁止类名为Object的巨坑

2018年1月4日PHP 7.2.1发布,很多之前处于观望的小伙伴开始打算升级PHP了,不过要注意到2017年11月30日发布的PHP 7.2.0开始禁止类名为Object,这将导致很多包出错。特别是很多包的兼容性只写了最低版本,没有写最高版本,使用PHP 7.2的时候composer并不会提示兼容性错误,而PHPautoload的延迟加载特性,又会导致仅在涉及的时候才会提示错误。例如这样的场景:
程序使用框架F,使用第三方模块M,而模块M中在特定参数的情况会调用模块N,模块N中包含一个类名为Object的类。在开发的时候,模块N并不会涉及到,因此在PHP 7.2中开发很久也不会遇到这个问题。可是给客户部署的时候,出现了使用模块N的情况。

这时候,如果降级到PHP 7.1,那么程序中已经大量使用的PHP 7.2的特性就都需要修改,特别是禁止类名使用Object的特性的根源——Object类型提示,就全部要修改,而且需要增加相应的程序判断。

如果不降级,那么就需要修改模块N中所有涉及到Object的地方,程序员都知道修改别人的代码多么痛苦。

最后说说这个坑。

PHP 7.2.0 Released 中包含 Object typehint 对象类型提示 ,其中提到 Backward Incompatible Changes 向后兼容变更

Although ‘object’ is already a soft reserved word, this RFC adds object as fully reserved classname.

从这里可以看出,object一直是一个软soft保留字,程序中本来就不应该使用,这次只不过变成了完全保留字而已。

例如 yii2 也做了修改 https://github.com/yiisoft/yii2/blob/master/framework/base/Object.php

尽管这么大的坑,不过好处也多多,官方给出的例子如下:

参数类型

function acceptsObject(object $obj) {
    ...
}

// This code can be statically analyzed to be correct
acceptsObject(json_decode('{}'));

// This code can be statically analyzed to be correct
acceptsObject(new \MyObject());

// This can be statically analysed to contain an error.
// and would throw an TypeError at runtime.
acceptsObject("Ceci n'est pas une object.");

返回类型

// This function can be statically analysed to conform to the
// return type
function correctFunction() : object {
    $obj = json_decode('{}');

    return $obj;
}

// This function can be statically analysed to contain an error
// and will also fail at runtime.
function errorFunction() : object {
    return [];
}

转换器和数据解析器

interface Hydration {
  // Hydrate an object by populating data
  public function hydrate(array $data, object $object) : object;
}

interface Extraction {
  // Extract values from an object
  public function extract(object $object) : array;
}

服务容器和依赖注入容器

interface ServiceContainer {
  // Set service definition
  public function set(string $id, object $service);

  // Retrieve service object from container
  public function get(string $id) : object;
}

捕获返回值错误

function unserialize($data) : object {

    $type = $data['type'];

    switch ($type) {
        case 'foo': { return new Foo(); }
        case 'bar': { return new Bar(); }
        case 'zot': { new zot(); }  // Ooops, this is an error
    }
}

继承中强制函数签名

class WidgetFactory {
    function create() : object {
        return new Widget();
    }
}

class CustomWidgetFactory extends WidgetFactory {
    // This class would not compile, as the signature of the metod in
    // the child class is not compatible with the method signature in 
    // the parent class.
    function create() : bool {
       ...
    }
}

参数类型提示逆变

class Foo {
}

class Bar {
    public function foo(Foo $object) : object {
        return $object;
    }
}

class Baz extends Bar {
    public function foo(object $object) : object {
        return $object;    
    }
}

返回值类型协变

class Foo {
}

class Bar {
    public function foo(object $object) : object {
        return $object;
    }
}

class Baz extends Bar {
    public function foo(object $object) : Foo {
        return $object;    
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值