本节介绍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; } ?>