foreach遍历字段是很常见的,foreach也可以遍历对象
进行以下测试:
经典的 { public$a='a'; 受保护的$b='b'; 私人 $c='c'; private$data=array('幻想','windows','linux'); //内部foreach遍历类 functiontraversable() { foreach($thisas$key=>$val) { echo $key.'=>'; print_r($val); 回声'
'; $m=newmy(); } } } $m=newmy(); //外部foreach遍历类 foreach($mas$key=>$val) { echo $key.'=>'; print_r($val); 回声'
'; } 回声'------------------------
'; //内部foreach遍历类 $m->traversable();
输出如下:
一个=>一个
--------------------------
一个=>一个
b=>b
c=>c
可以看到,对于外部的foreach遍历,没有权限访问protectedprivate的两个修饰属性,但是在类内部,有权限访问php遍历对象,foreach可以遍历所有属性。
今天写PDO的时候发现可以这样写:
foreach($db->query('SELECT*FROMtab')as$row) { print_r($row); }
这样很快就得到了所有的查询结果,但是奇怪的是$this->query()返回的是对象类型PDOStatement,而var_dump()打印的结果如下:
对象(PDOStatement)#2(1){ [“queryString”] => string(18)“SELECT * FROMuser”}
PDOStatement 上有一个公共属性 queryString,而 foreach 没有该值。 在这种情况下,并不是简单的属性遍历,而是类继承了iterator迭代器。 当foreach会执行类上的迭代方法时,遍历迭代器指定的数据
请参阅以下迭代器示例:
classtestimplementsIterator { public$a='a'; private$data=array('苹果','banlance','当前'); 私人$点=0; publicfunction__construct() { $this->point=0; } } publicfunctioncurrent( ) { return $this->data[$this->point]; } } publicfunctionkey() { return $this->point; } } publicfunctionnext() { ++$this->point; } publicfunctionrewind() { $this-> point=0; } publicfunctionvalid() { returnisset($this->data[$this->point]); $t=newtest(); foreach($tas$val) { print_r($val); 回声'
'; }
输出如下:
苹果
班兰斯
测试类实现了迭代器套接字,该迭代器套接字在调用 foreach 时使用。 调用流程大致如下:
//迭代过程伪代码 while(valid) { current/key next } rewind
所以,类之前的foreach过程是一个默认方法。 如果通过foreach遍历继承iterator的类php遍历对象,则是之前的方法
在这种情况下,应用PDO的写法仍然不可行,因为如果我们的var_dump前面的测试类结果是这样的:
testObject ( [a]=>a [data:test:private]=>Array ( [0]=>apple [1]=>banlance [2]=>current ) [point:test:private]=>0 )
但是当我们从var_dump$db->query返回对象时,并没有看到point的迭代器socket中定义的属性以及遍历到的数据$data;
由此我们可以推测PDOStatement继承了一个迭代套接字并且不是迭代器
查看指南以了解:
PDO语句实现可遍历
查看Traversable的介绍如下图:
由此我了解到PDOStatement的迭代实现都是内部的,继承iterator就是php脚本的实现方法。
总之:
foreach可以遍历链表,也可以遍历对象。 对象只能列出公共属性。 如果想让foreach列出受保护的属性,可以让类继承迭代器并实现方法。 这样,foreach遍历一个类时,就根据类内部实现的迭代器进行处理。
-------------------------------------------------- ------------
PDO 的问题:
PDO::query() 返回对象 PDOStatement(继承的 Traversable 空套接字必须由 IteratororiteratorAggregate 套接字实现)。
PDOStatement 实现了 Iterator 接口,其实现对存储查询结果集的非公共修改属性进行操作。
至此,foreach($db->query('sql..')as$row)的执行流程就清楚了
发表评论