我困惑为什么ArrayIterator
的子类永远不会调用其__construct
方法。考虑以下示例:
<?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
。为什么?
参考方案
@Leggendario是正确的说法,问题出在spl_array_object_new_ex
方法上。但是,如果不确定,我不确定。但是,这并不是真正的标准。
构造函数中的iteratorClass
变量(或通过setIteratorClass
设置)建议,只要我们从ArrayObject
中检索迭代器,该类都将实例化。但是它不会进行常规的“实例化”,因为这是不可能的。
它只会初始化迭代器(分配内存等),而不调用构造函数。不调用构造函数是有道理的,因为ArrayIterator
的构造函数带有两个参数($array
和$flags
),并且您的类可能已更改其签名,甚至可能添加了更多(强制性值)。
通常,ArrayIterator
(或RecursiveArrayIterator
)是内部类,并且具有连接到它们的内部结构(基本上像它自己的内部属性集,您不能直接从PHP用户区获取这些属性)。 spl_array_object_new_ex
将直接设置这些内部值(最著名的是ce_get_iterator
和ar_flags
)。因此,基本上,它负责ArrayIterator构造函数的工作。
因为PHP检查给定的类是否为ArrayIterator
,或者父类之一是否为一。在这种情况下,这意味着它最终可以使用这些内部值,从而直接设置它们,而无需任何构造函数。不利的一面是,您想要构建的任何东西都不会被调用。
有人可以解释为什么这在我的服务器上输出为true吗?date_default_timezone_set('Europe/Bucharest'); var_dump( strtotime('29.03.2015 03:00', time()) === strtotime('29.03.2015 04:00…
PHP-全局变量的性能和内存问题 - php假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…
php-casperjs获取内部文本 - php我正在为casperjs使用php包装器-https://github.com/alwex/php-casperjs我正在网上自动化一些重复的工作,我需要访问一个项目的innerText,但是我尚不清楚如何从casperjs浏览器访问dom。我认为在js中我会var arr = document.querySelector('label.input…
PHP getallheaders替代 - php我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…
PHP Laravel从另一个驱动器读取文件 - php我目前正在学习Laravel。我想知道是否有一种方法可以在Laravel中使用Storage::从另一个硬盘访问文件(使用Windows)。例如,我在驱动器C:上安装了带有Laravel的Xampp,但是我想访问网站目录之外的E:上的文件。我试过使用Storage::files('E:')和File::files('E:…