object (xxx ){
protected '_data' =>
array (size=6 ){
0 =>
1 =>
2 =>
3 =>
4 =>
5 =>
}
}
对象大概就长得这样,里面有一个唯一的受保护属性_data
,属性里存着一个数组array
。然后我尝试foreach
这个数组,神奇的事情发生了,_data
里面的array
数组被遍历出来了。
1
timsims 2015-08-31 17:18:13 +08:00
```
class Object { protected $_data = [1,2,3]; } $object = new Object; foreach ($object->_data as $v ) { echo $v; } ``` 然而并不能 FatalErrorException Cannot access protected property Object::$_data 我猜这个对象是不是实现了 ArrayAccess 接口或者用了魔术方法? |
2
haiyang416 2015-08-31 17:23:42 +08:00
如果你在类方法里 foreach 这个数组,当然可以。
如果是将该对象作为 foreach 的遍历参数,那是因为这个对象实现了 iterator 接口。 |
3
leeyuzhe OP @timsims 我这里真能,我快疯了,不知道为啥。整个对象没有方法只有这么一个 protected 属性。
你直接 foreach $object 别 foreach ($object->_data )试试 |
4
leeyuzhe OP @haiyang416 对我就是是将该对象作为 foreach 的遍历参数。 iterator 接口如何实现的?整个对象就这么一个属性,没有任何方法,
|
5
jswh 2015-08-31 17:36:52 +08:00
父类实现了 iterator 接口?
|
6
haiyang416 2015-08-31 17:39:13 +08:00
|
7
freefcw 2015-08-31 17:39:13 +08:00
麻烦请把上下文代码打出来,以及相关的 php 版本等,如此丢出一个问题实在是不负责任的调戏大家
|
8
lijinma 2015-08-31 17:41:12 +08:00
代码贴出来,赶紧的,这像话吗?
|
9
solupro 2015-08-31 17:44:00 +08:00
|
10
leeyuzhe OP @haiyang416 @freefcw @lijinma @solupro
首先是返回这个对象的方法。 ``` /** * Fetches all rows. * * @param string|array $where OPTIONAL An SQL WHERE clause * @param string|array $order OPTIONAL An SQL ORDER clause. * @param int $count OPTIONAL An SQL LIMIT count. * @param int $offset OPTIONAL An SQL LIMIT offset. * @return APP_Db_Table_Rowset_Abstract object */ public function fetchAll ($where = null, $order = null, $count = null, $offset = null ) { $table = $this->_schema . '.' . $this->_db->quoteIdentifier ($this->_name ); $select = "SELECT * FROM $table"; // if ($where !== null ) if ($where !== null && !empty ($where )) { $select .= ' WHERE ' . $this->_where ($where ); } if ($order !== null && !empty ($order )) { $select .= ' ORDER BY ' . $this->_order ($order ); } if ($count !== null || $offset !== null ) { $select = $select . $this->_db->limit ($count, $offset ); // $select = $this->_db->limit ($select, $count, $offset ); } $data = $this->_fetch ($select ); require_once 'APP/Loader.php'; APP_Loader::loadClass ($this->_rowsetClass ); return new $this->_rowsetClass ($data ); } ``` 然后是包含进来的 APP/Loader.php ``` <?php /** * @category APP * @package APP_Loader * @version $Id: Loader.php v1.0 2009-2-25 0:08:04 tomsui $ */ class APP_Loader { /** * Load a class * * Load a APP class file. If the class already exists in memory, return * directly. * * @static * @param string $class String name of the class to load. * @param array $config OPTIONAL; an array with adapter parameters. * @return void * @throws APP_Exception */ public static function loadClass ($class ) { if (class_exists ($class, false ) || interface_exists ($class, false )) { return; } $file = str_replace ('_', DIRECTORY_SEPARATOR, $class ) . '.php'; self::_securityCheck ($file ); require ($file ) ; } /** * Autoload switch * * if switch opens, APP class can be used without loading previously * * @static * @param boolean $use to set wheather Autoload switcher in use or not. * @return void */ public static function Autoload ($use = true ) { if ($use ){ spl_autoload_register (array ('APP_Loader', 'loadClass')); }else{ spl_autoload_unregister (array ('APP_Loader', 'loadClass')); } } /** * Security Check * * File name of APP classs can just contain alpha,digits,backslash (/), * slash (\),underline (_),period (.) and dash (-). If contains other irregular * charactor, an APP_Exception is thrown. * * @static * @param boolean $filename the filename string to be check. * @return void * @throws APP_Exception */ protected static function _securityCheck ($filename ) { if (preg_match ('/[^a-z0-9\\/\\\\_.-]/i', $filename )) { require_once 'APP/Exception.php'; throw new APP_Exception ('Security check: Illegal character in filename'); } } } ``` |
11
haiyang416 2015-08-31 17:56:03 +08:00
@leeyuzhe 文档上不是写了么, APP_Db_Table_Rowset_Abstract ,你去看它的代码。
|
12
realpg 2015-08-31 18:07:46 +08:00
原文:
对象大概就长得这样,里面有一个唯一的受保护属性_data ,属性里存着一个数组 array 。然后我尝试 foreach 这个数组,神奇的事情发生了,_data 里面的 array 数组被遍历出来了。 foreach 这个数组还是 foreach 这个类的实例? 你说的 foreach 这个数组,那就是直接对这个类的成员进行 foreach ,见 1 楼 @timsims 的测试 如果遍历的是这个对象,那么测试如下: 图一 代码: 图二 执行: --------------- 综上,明显你这个类不是你自己建的,逐级检查你自己的类的的基类去吧,肯定能找到哪个里面定义了迭代 |
13
invite 2015-08-31 19:21:55 +08:00
高级的版本, 没用到过.
|
14
timsims 2015-08-31 19:28:51 +08:00
APP_Db_Table_Rowset_Abstract.. 这名字好像 ZF1 的 Zend_Db_Table_Rowset_Abstract
|