关键词搜索

源码搜索 ×
×

PHP 7.2禁止类名为Object的巨坑

发布2018-01-31浏览4060次

详情内容

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;
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      服务容器和依赖注入容器

      interface ServiceContainer {
        // Set service definition
        public function set(string $id, object $service);
      
        // Retrieve service object from container
        public function get(string $id) : object;
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      捕获返回值错误

      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
          }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      继承中强制函数签名

      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 {
             ...
          }
      }
      • 14

      参数类型提示逆变

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

      返回值类型协变

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

      相关技术文章

      点击QQ咨询
      开通会员
      返回顶部
      ×
      微信扫码支付
      微信扫码支付
      确定支付下载
      请使用微信描二维码支付
      ×

      提示信息

      ×

      选择支付方式

      • 微信支付
      • 支付宝付款
      确定支付下载