我很困惑为什么一个ArrayIterator
的子类永远不会调用它的__construct
方法。考虑下面的例子:为什么ArrayIterator子类的构造函数从未被调用过?
<?php
class ConstructorException extends Exception {}
class Foo extends ArrayObject {
function __construct($arr = array(), $flags = 0, $iterator = 'ArrayIterator') {
$iterator = 'FooIterator';
parent::__construct($arr, $flags, $iterator);
}
}
class FooIterator extends ArrayIterator {
function __construct($array = array(), $flags = 0) {
throw new ConstructorException('HELLO WORLD'); // I AM NEVER CALLED.
parent::__construct($array, $flags);
}
}
try {
$f = new Foo(array(1, 2, 3));
$it = $f->getIterator();
if (get_class($it) !== 'FooIterator') {
throw new Exception('Expected iterator to be FooIterator.');
}
die("FAIL\n");
} catch (ConstructorException $e) {
die("PASS\n");
} catch (\Exception $e) {
die(sprintf("ERROR: %s\n", $e->getMessage()));
}
在这两种PHP 5.4 5.5的,其结果是FAIL
。为什么?
约翰:无异常http://3v4l.org/HnFQm
上一页的代码,但示出了迭代器的工作以及用()在类Foo方法getIterator的变化(由索引和取消加入) Blackbourn指出它可以在HHVM中工作:http://3v4l.org/e9qF9/通过https://twitter.com/johnbillion/status/601900452293300224 –
这似乎是一个内部问题在PHP中。 [spl_array_object_new_ex](https://github.com/php/php-src/blob/master/ext/spl/spl_array.c#L143)不要调用父项的构造函数。应该报告吗? – Federkun
内建对象上的构造函数有点时髦 - 例如注意[SimpleXMLElement声明其构造函数是'final'](http://php.net/manual/en/simplexmlelement.construct。PHP),因此子类必须通过正确的工厂过程。不过'ArrayIterator'并非如此,所以也许这只是一个错误。 – IMSoP