我从 MAMP开始使用PHP 5.3.6.

我有一个用例,最好使用PHP的Iterator接口方法,next(),current()和valid()来迭代集合.在我的特定情况下,foreach循环对我不起作用.简化的while循环可能看起来像

<?PHP
while ($iter->valid()) {
  // do something with $iter->current()
  $iter->next();
}

当$iter实现PHP的Iterator接口时,上述代码是否始终有效? PHP的foreach关键字如何处理迭代器?

我问的原因是我写的代码可能会被赋予ArrayIterator或MongoCursor.两者都实现了PHP的Iterator接口,但它们的行为方式不同.我想知道PHP或PHP的Mongo扩展中是否存在错误.

ArrayIterator :: valid()在任何对next()的调用之前返回true – 在创建ArrayIterator之后立即返回true.

MongoCursor :: valid()仅在第一次调用next()后返回true.因此,上面的while循环永远不会执行.

有可能是冗长的,下面的代码演示了这些断言:

<?PHP

// Set up array iterator
$arr = array("first");
$iter = new \ArrayIterator($arr);

// Test array iterator
echo(($iter->valid() ? "true" : "false")."\n"); // Echoes true
var_dump($iter->current()."\n");                // "first"
$iter->next();
echo(($iter->valid() ? "true" : "false")."\n"); // Echoes false


// Set up mongo iterator
$m = new \Mongo();
$collection = $m->selectDB("iterTest")->selectCollection("mystuff");
$collection->drop(); // Ensure collection is empty
$collection->insert(array('a' => 'b'));
$miter = $collection->find(); // should find one object

// Test mongo iterator
echo(($miter->valid() ? "true" : "false")."\n"); // Echoes false

$miter->next();

echo(($miter->valid() ? "true" : "false")."\n"); // Echoes true
var_dump($miter->current());                     // Array(...)

哪种实现是正确的?我发现很少有文档可以支持这两种行为,官方的PHP文档要么模糊不清,要么我读错了. doc for Iterator :: valid()表示:

This method is called after Iterator::rewind() and Iterator::next() to check if the current position is valid.

这表明我的while循环应首先调用next().

然而PHP documentation for Iterator :: next说:

This method is called after each foreach loop.

这表明我的while循环是正确的.

总结一下 – PHP迭代器应该如何表现?

这是个有趣的问题.我不确定为什么foreach不适合你,但我有一些想法.

看看the Iterator interface reference page上给出的示例.它显示了PHP的内部实现foreach调用Iterator方法的顺序.特别要注意的是,首次设置foreach时,第一个调用是rewind().这个例子虽然没有很好地注释,但却是我答案的基础.

我不确定为什么MongoCursor在调用next()之前不会为valid()返回true,但是你应该能够通过在循环之前调用rewind()来重置任何类型的对象.所以你会:

// $iter may be either MongoCursor or ArrayIterator

$iter->rewind();
while( $iter->valid() ){
    // do something with $iter->current()
    $iter->next();
}

我相信这对你有用.如果没有,Mongo类可能会有错误.

编辑:Mike Purcell的答案正确地指出ArrayIterator和Iterator是不一样的.但是,ArrayIterator实现了Iterator,因此您应该能够使用rewind(),就像我在其中任何一个上面所示.

PHP的Iterator方法如何有效(),current()和next()表现如何?的更多相关文章

  1. 从iOS应用程序发送帖子到PHP脚本不工作…简单的解决方案就像

    我之前已经做了好几次了但是由于某些原因我无法通过这个帖子…我尝试了设置为_POST且没有的变量的PHP脚本……当它们未设置为发布时它工作精细.这是我的iOS代码:这里是PHP的一大块,POST变量不在正确的位置?我想这对于更有经验的开发人员来说是一个相当简单的答案,感谢您的帮助!解决方法$_POST是一个数组,而不是一个函数.您需要使用方括号来访问数组索引:

  2. Swift-ReactiveCocoa3.0二SignalProducer 2

    lift运算符|>内部也是调用了lift方法,作用是把原producer的结果transform完返回新的类型/值,再封装成新的producer返回。只有在第一个producer销毁后才会响应第二个producer。之后,每当其中一个再sendNext,都会在next回调zipwith压缩两个信号,每当两个都sendNext一次才回在next回调一次。例子:sampleOn采样,当sampleOn的信号sendNext一次,就取一次producer1的最新一次sendNext的值进行next回调takeu

  3. swift学习2 元组 tuples

    swift中出现了一种新的数据结构,非常牛掰的元组tuples如果懂PHP的猿,会发现这个元组和PHP的数组非常类似,同样是可以默认不指定key,也可以指定key目前的学习疑问是,如何进行元组的遍历?

  4. 如何在Swift中调用C函数

    “,选择Yes,创建SwiftCallC-Bridging-Header.h文件给工程建立一个C语言文件。跟上述步骤3类似,只不过这里选择的是C文件,这里的文件取名为CFile.c,同时自动生成CFile.h文件开始编写代码。在SwiftCallC-Bridging-Header.h文件中声明C函数,这里是voidcallCDemo()在CFile.c中定义这个函数在main.swift中调用这个C函数编译运行

  5. Swift--UINavigationController

    代码目录AppDelegate.swiftViewController.swiftNext.swift效果图

  6. Swift如何取得View所属的ViewController

    从VC取得View很容易,但有些情况下我们需要从View反向获取VC.不过在一些特殊的场合,Cocoa库帮我们想的很周到,比如在自定义view过渡动画的时候:系统在回调我们的animateTransition方法时,会传入一个context参数,从它我们可以轻松取得参与动画的toView,fromView以及它们对应的VC:但不是所有情况系统都会帮你考虑的这么周到,所以有时候还得需要自己从View

  7. 创建 Swift 自定义集合类

    在本文,你将学习用Swift的collection协议创建自定义集合类型。当文本结束,你会拥有一个强大的自定义集合类型,拥有Swift内置集合的所有功能。小于次的版本无法编译,因为Swift标准库发生了剧烈改变。在一个Set集合中,重复对象会被忽略。Swift提供了让Bag符合传统集合的所有工具。你需要先了解一下在Swift中,让一个对象变成集合需要做些什么。要理解什么是Swift集合,首先需要它继承的协议层次:Sequence协议表示类型支持排序、以迭代的方式访问其元素。

  8. RxSwift使用教程大全 韩俊强的博客

    记录大多数ReactiveX的概念和操作符。我们还需要使用KVO来检测变量的值改变。Rx就是为解决这些问题而生的。Observable理解RxSwift的关键是理解Observable的概念。使用variable的好处是variable将不会显式的发送Error或者Completed。

  9. 尝试使用swift mailer,gmail smtp,php发送邮件

    这里是我的代码:在运行时出现此错误…

  10. swift – 全局函数序列(state:next :)和类型推断

    3,让seq2=4…

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部