本节介绍php中的迭代器Iterator的具体用法。
一,最简单的迭代形式 foreach语句
1,foreach 可以用于数组, 例如:
2,foreach 也可以用于对象, 例如:
注意: 如果在对象之外用这条语句只能输出公有的属性,不能输出私有的和保护的属性。
二,下面通过几个例子,来帮助大家理解iterator的用法。
其中DirectoryIterator,RecursiveDirectoryIterator,LimitIterator都是PHP预定义的iterator类:
例1,显示/etc/目录下的所有文件(不显示子目录下的文件):
$path = new DirectoryIterator(“/etc/”);
foreach ( $path as $file ){
echo $file .’/n’;
}
?>
例2,显示/etc/目录下的嵌套的任意层的子目录中的所有文件(显示出目录路径):
$path = new RecursiveDirectoryIterator(“/etc/”);
foreach ( $path as $file ){
echo $file ->getPathname().’/n’;
}
?>
例3,显示/etc/目录下的前10个文件:
$path = new LimitIterator(DirectoryIterator(“/etc/”),0,10);
foreach ( $path as $file ){
echo $file .’/n’;
}?>
说明:在php编程中,合理应用iterator迭代,可以使代码清晰,加快编程速度。
三,下面分析下Iterator迭代器的原理
1,PHP中将实现了接口Iterator中5个方法的类都称为iterator,分别为:
key()—返回当前元素的键值,
next()—下移一个元素,
valid()—判定是否还有后续元素, 如果有, 返回true,
rewind()—移到首元素
常用的iterator有: DirectoryIterator、SimpleXMLIterator几种。
2,递归iterator是实现了接口RecursiveIterator中的hasChildren()和getChildren()方法的类,
例如以上例2中的RecursiveDirectoryIterator。
3,以上例3中显示了iterator 的链接, 即将一个iterator(可以称为源iterator)作为另一个iterator(可以称为目标iterator)的参数, 通常用于数据过滤.
常用的用于链接的iterator是FilterIterator和LimitIterator。
FilterIterator是一个抽象类, 需要实现它的accept()方法作为过滤数据的规则,
而LimitIterator是类, 用法是new LimitIterator(源iterator,起始位,个数) 用于获得指定个数的元素。
4,PHP中另提供IteratorAggregate接口, 用于将非iterator的类构造为iterator, 实际是实现该接口中的getIterator()方法.
例如:
<?php
class sample implements Iterator
{
private $_items = array(1,2,3,4,5,6,7);
public function __construct() {
;//void
}
public function rewind() { reset($this->_items); }
public function current() { return current($this->_items); }
public function key() { return key($this->_items); }
public function next() { return next($this->_items); }
public function valid() { return ( $this->current() !== false ); }
}
$sa = new sample();
foreach($sa as $key => $val){
print $key . "=>" .$val;
}
?>
php中Iterator迭代器的用法,就介绍到这里了,希望可以帮助到大家。
php本身不支持多线程,但apache和linux是支持的,有了lamp与lnmp这样的绝佳组合,再有了shell的鼎力相助,在php中实现多线程就不再那么困难了。
有如下的php代码,每次循环sleep 5秒。
文件 sleeep.php 代码:
//for循环
for ($i = 0; $i < 10; $i++)
{
echo $i;
sleep(5);
}
接下来,就要shell上场了,调用php文件:sleep.php,代码如下:
#edit by www.
for i in 1 2 3 4 5
do
/usr/bin/php -r -q /data/website/sleep.php &
done
注意:
以上代码的关键点在于,要在请求php代码的行尾加一个&符号,否则不能进行多线程的,&表示讲服务推送到后台执行。
因此,在shell的每次的循环中不必等php的代码全部执行完在请求下一个文件,而是同时进行的,即实现了多线程。
运行下shell将看到10个test.php进程在跑,可以考虑结合下linux的定时器crontab,定时请求shell脚本,即可处理一些多线程的任务,比如批量上传或下载等。
好了,有关php与shell结合实现多线程的例子,就介绍到这里了,希望对大家有所帮助。
以下代码,实现:多线程下载远程多个文件,如下:
<?php
/**
* @多线程下载远程多个文件
* @curl的具体应用实例
* @edit by www.
*/
function remote($urls, $name = '', $path = '', $dir = './images/') {
if (!is_array($urls) or count($urls) == 0) {
return false;
}
dmkdir($dir);
$curl = $text = array();
foreach($urls as $k => $v) {
if (!empty($v) && preg_match("~^http~i", $v)) {
$nurl[$k] = trim(str_replace(' ', "%20", $v));
$curl[$k] = curl_init($nurl[$k]);
curl_setopt($curl[$k], CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl[$k], CURLOPT_HEADER, 0);
curl_setopt($curl[$k], CURLOPT_CONNECTTIMEOUT, 20);
if(!isset($handle)){
$handle = curl_multi_init();
}
curl_multi_add_handle($handle, $curl[$k]);
}
continue ;
}
$active = null;
do{
$mrc = @curl_multi_exec($handle, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($handle) != -1) {
do {
$mrc = curl_multi_exec($handle, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($curl as $k => $v) {
if (curl_error($curl[$k]) == "") {
if ($k == 0) {
$fname[$k] = strtolower($name . '.' . pathinfo($urls[$k], PATHINFO_EXTENSION));
} else {
$fname[$k] = strtolower($name . '_' . $k . '.' . pathinfo($urls[$k], PATHINFO_EXTENSION));
}
$text[$k] = (string) curl_multi_getcontent($curl[$k]);
$filedir[$k] = $dir.'/' . $fname[$k];
if (file_put_contents($filedir[$k], $text[$k])) {
$filepath[$k] = $path . $fname[$k];
}
}
curl_multi_remove_handle($handle, $curl[$k]);
curl_close($curl[$k]);
}
curl_multi_close($handle);
return $filepath;
}
?>