我有以下文件:
<?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)可以使用文件底部的类定义进行实例化。
答案 0 :(得分:1)
任何界面都会发生相同的行为,因此并非特定于ArrayAccess
。
在PHP文档Objects and Classes -> The Basics中, new 部分中有一个非常简洁的提示(我将其以粗体显示):
要创建类的实例,必须使用new关键字。 除非对象具有构造函数,否则将始终创建对象 定义为在错误时抛出异常。应该定义类 在实例化之前(在某些情况下这是一项要求)。
在实例化之前,实现接口的类似乎属于需要定义的类别,这似乎是一个不错的选择。
您发现的不一致性肯定令人困惑,但在实例化之前您可能会遇到定义,这无论如何都是最佳做法。