如果未定义,则实现ArrayAccess的类将引发致命错误

时间:2018-01-03 06:42:32

标签: php oop

我有以下文件:

<?php

$inc = new includer;

?>

<!-- ... snip lots of HTML ... -->

<?php

class includer {

    protected $obj;

    public function __construct() {
        $this->obj = new obj;
    }

}

// obj taken from PHP ArrayAccess page as example, contents not important
class obj implements ArrayAccess {
    private $container = array();

    public function __construct() {
        $this->container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

includer类的实例化位于文件的底部(类定义位于文件顶部)时,一切都很有效。如图所示,在文件顶部的类实例化中,我收到以下错误:

Fatal error: Uncaught Error: Class 'obj' not found in \test\classes.php on line 16

如果我从implements ArrayAccess类中删除obj部分,无论includer实例化的位置如何,一切正常。

该文件是单页PHP / HTML / JS文件,底部包含我的所有PHP类和函数定义。因此,我真的希望避免将这些类放在顶部,因为ArrayAccess部分。我也不需要任何关于意大利面条代码等的讲座。这是一种有意识的决定。

我也试过使用和不使用函数调用parens($inc = new includer; vs $inc = new includer();),并且两个类实例化调用都没有任何区别。

我也尝试过使用和不使用命名空间(\ArrayAccess vs ArrayAccess),也没有运气。

我可以做些什么来阻止PHP在实例化之前对这个未被定义的类感到愤怒?其他类(不实现ArrayAccess)可以使用文件底部的类定义进行实例化。

1 个答案:

答案 0 :(得分:1)

任何界面都会发生相同的行为,因此并非特定于ArrayAccess

在PHP文档Objects and Classes -> The Basics中, new 部分中有一个非常简洁的提示(我将其以粗体显示):

  

要创建类的实例,必须使用new关键字。   除非对象具有构造函数,否则将始终创建对象   定义为在错误时抛出异常。应该定义类   在实例化之前(在某些情况下这是一项要求)

在实例化之前,实现接口的类似乎属于需要定义的类别,这似乎是一个不错的选择。

您发现的不一致性肯定令人困惑,但在实例化之前您可能会遇到定义,这无论如何都是最佳做法。