曾经遇到过这么多次,我不知道为什么这让我好奇。有些课程在宣布之前就开始工作,有些则没有;类扩展或接口如何工作?
实施例1
$test = new TestClass(); // top of class
class TestClass {
function __construct() {
var_dump(__METHOD__);
}
}
输出
string 'TestClass::__construct' (length=22)
实施例2
当一个类继承另一个类或实现任何接口
$test = new TestClass(); // top of class
class TestClass implements JsonSerializable {
function __construct() {
var_dump(__METHOD__);
}
public function jsonSerialize() {
return json_encode(rand(1, 10));
}
}
输出
Fatal error: Class 'TestClass' not found
实施例3
让我们尝试上述相同的类,但改变位置
class TestClass implements JsonSerializable {
function __construct() {
var_dump(__METHOD__);
}
public function jsonSerialize() {
return json_encode(rand(1, 10));
}
}
$test = new TestClass(); // move this from top to bottom
输出
string 'TestClass::__construct' (length=22)
实施例4只要它实现JsonSerializable
(I也与class_exists测试)
var_dump(class_exists("TestClass")); //true
class TestClass {
function __construct() {
var_dump(__METHOD__);
}
public function jsonSerialize() {
return null;
}
}
var_dump(class_exists("TestClass")); //true
(或任何其他)
var_dump(class_exists("TestClass")); //false
class TestClass implements JsonSerializable {
function __construct() {
var_dump(__METHOD__);
}
public function jsonSerialize() {
return null;
}
}
var_dump(class_exists("TestClass")); //true
还检查操作码without
JsonSerializable
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > SEND_VAL 'TestClass'
1 DO_FCALL 1 $0 'class_exists'
2 SEND_VAR_NO_REF 6 $0
3 DO_FCALL 1 'var_dump'
4 4 NOP
14 5 > RETURN 1
也Chec糟透了操作码with
JsonSerializable
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > SEND_VAL 'TestClass'
1 DO_FCALL 1 $0 'class_exists'
2 SEND_VAR_NO_REF 6 $0
3 DO_FCALL 1 'var_dump'
4 4 ZEND_DECLARE_CLASS $2 '%00testclass%2Fin%2FaDRGC0x7f563932f041', 'testclass'
5 ZEND_ADD_INTERFACE $2, 'JsonSerializable'
13 6 ZEND_VERIFY_ABSTRACT_CLASS $2
14 7 > RETURN 1
问题
- 我知道
Example 3
工作是因为类是宣布启动之前,但为什么会在第一时间Example 1
工作? - 这个扩展或接口在PHP中工作的整个过程如何使一个有效和另一个无效?
- 例4中究竟发生了什么?
Opcodes
本来应该让事情变得清楚,但它使它更加复杂,因为class_exists
在TestClass
之前被调用,但事实恰恰相反。
我还想知道在过去,我从'Iterator'和朋友都知道这一点。 – hakre
如果实现的类也存在于同一个文件中,这是不同的吗?也许这与php找到引用类的方式有关。 (在文件中查找,甚至访问一个_autoload(),最后寻找在类的本地代码) –
它即使包括一类同样的问题... – Baba