2024 年 PHP 日本大会

SPL 函数

目录

添加注释

用户贡献的注释 8 条注释

ville</.>witt</a>gmail</.>com
18 年前
这两个函数的输出完全相同,唯一的区别在于它们使用哪个目录迭代器。我希望有人可以用到它。
<?php
function listfilesin1 ($dir = ".", $depth=0) {
echo
"Dir: ".$dir."<br/>";
foreach(new
DirectoryIterator($dir) as $file) {
if (!
$file->isDot()) {
if (
$file->isDir()) {
$newdir = $file->getPathname();
listfilesin1($newdir, $depth+1);
} else {
echo
"($depth)".$file->getPathname() . "<br/>";
}
}
}
}
function
listfilesin2 ($dir = ".", $depth=0) {
echo
"Dir: ".$dir."<br/>";
foreach(new
RecursiveDirectoryIterator($dir) as $file) {
if (
$file->hasChildren(false)) {
$newdir = $file->key();
listfilesin2($newdir, $depth+1);
} else {
echo
"($depth)".$file->key() . "<br/>";
}
}
}
listfilesin();
?>
loaded67 at hotmail dot com
16 年前
对于某些应用程序,我需要反转一些标准迭代器。

所以我模拟了这个灵活的函数。
享受

<?php
function reverse_iterator(Iterator $iterator){
$type = get_class($iterator);
$array = array_reverse(iterator_to_array($iterator), true);
return new
$type($array);
}
?>
semperluc (at) yahoo._forgot_the_rest
17 年前
<?php
/*
如何存储 SPL 迭代器的结果(而不仅仅是输出并忘记):

迭代器库是基于对象的,因此您需要将这些小家伙转换成数组。
方法如下(两种方法)...

1. 显式类型转换:$a[] = (array)$Obj->objMethod();

2. 数组定义:$a[] = array( key => $Obj->objMethod() );

示例:DirectoryIterator()
*/

// 1. 显式将对象类型转换为数组
foreach ( new DirectoryIterator('./') as $Item )
{
$fname = (array)$Item->getFilename();
$dir_listing[] = $fname[0];
}

//
echo "<pre>";
print_r($dir_listing); unset($dir_listing);
echo
"</pre><hr />";
//

// 或

// 2. 将数组定义为 key => object->method
foreach ( new DirectoryIterator('./') as $Item )
{
$dir_listing[] = array (
"fname" => $Item->getFilename(),
"path" => $Item->getPathname(),
"size" => $Item->getSize(),
"mtime" => $Item->getMTime()
);
}

//
echo "<pre>";
print_r($dir_listing); unset($dir_listing);
echo
"</pre>";
//
?>
benny at whitewashing dot de
16 年前
我必须纠正我之前的实现。之前的示例只支持正确的读取访问,但在创建 ArrayMultiObject 后无法设置新值。我还必须纠正从我的复制粘贴更改到注释文本区域中出现的错误。

此代码段现在有望实现一个完全功能的多维数组,由 ArrayObject 表示。

<?php
class ArrayMultiObject extends ArrayObject
{
function
__construct($array, $flags = 0, $iterator_class = "ArrayIterator")
{
$objects = array();
foreach(
$array AS $key => $value) {
if(
is_array($value)) {
$objects[$key] = new ArrayMultiObject($value, $flags, $iterator_class);
} else {
$objects[$key] = $value;
}
}

parent::__construct($objects, $flags, $iterator_class);
}

public function
offsetSet($name, $value)
{
if(
is_array($value)) {
$value = new ArrayMultiObject($value);
}

return
parent::offsetSet($name, $value);
}
}
?>
helly at php dot net
19年前
有一个RecursiveFilterIterator可以使上面的代码更容易。然后还有一个ParentIterator,它已经是一个过滤器递归迭代器,只接受有子元素的元素,使用RecursiveDirectoryIterator作为内部迭代器,显然你只会得到目录。此外,它确保创建正确的子元素。总而言之,你只需要这样做

$it = new RecursiveDirectoryIterator($path);
$it = new ParentIterator($it);
$it = new RecursiveIteratorIteator($it);

foreach($it as $dir => $o) { ... }
phil &ampersat; flatnet.net
20年前
这是一个RecursiveDirectoryIterator类的示例实现。它打印给定目录的简单树形视图
<?php
function recurse($it) {
echo
'<ul>';
for( ;
$it->valid(); $it->next()) {
if(
$it->isDir() && !$it->isDot()) {
printf('<li class="dir">%s</li>', $it->current());
if(
$it->hasChildren()) {
$bleh = $it->getChildren();
echo
'<ul>' . recurse($bleh) . '</ul>';
}
} elseif(
$it->isFile()) {
echo
'<li class="file">'. $it->current() . ' (' . $it->getSize(). ' Bytes)</li>';
}
}
echo
'</ul>';
}

recurse(new RecursiveDirectoryIterator('D:/'));
?>
adove at booyahnetworks dot com
19年前
需要注意的是,至少对我来说,文档中并不完全清楚的一点非常重要,那就是ArrayObject类支持对一维键的get/set操作,并且只支持对*传递的*多维键/路径进行get操作(见下面的源代码)。如果您像我一样,需要支持对多维数据的数组访问重载,您需要从ArrayObject派生并覆盖ArrayAccess接口方法来“遍历”传递的数据并将嵌入式数组转换为某种类型的对象……

参考Bug 34816 @ http://bugs.php.net/bug.php?id=34816.

问题的说明

$a = array(
"test" => array(
"one" => "dunno",
"two" => array(
"peekabo" => "do you see me?",
"anyone" => array("there")
)
)
);
$oArray = new ArrayObject($a);
var_dump($oArray);

$oArray["three"] = "No problems here.";

echo "\n\\test\\one == " . $oArray["test"]["one"] . "\n\n";

// 下面的两个都不会工作!
$oArray["test"]["one"] = "Yes I do!";
$oArray["test"]["yes"] = array(
"hello" => "Goodbye!"
);

var_dump($oArray);

---
扩展作者的说明
实际上,可以使用RecursiveArrayObject和RecursiveArrayIterator来处理递归结构。但是,这并不总是能像预期的那样解决所有多维问题。
prometheus - csaba dot dobai at php-sparcle dot hu
17 年前
这段代码是一个例子。通过使用这样的类,你可以创建扩展另一个类但拥有大部分ArrayObject扩展类能力(如多重继承)的类。

<?php

class foo
{
public
$foo = 'foo';
}
// class

class foobar extends foo implements ArrayAccess,IteratorAggregate,Countable
{
public function
offsetExists($offset)
{
$array = array(1, 2, 3, 4);
return
array_key_exists($offset, $array);
}

public function
offsetGet($offset)
{
$array = array(1, 2, 3, 4);
return
$array[$offset];
}

public function
offsetSet($offset, $value)
{
// 使“数组”只读
}

public function
offsetUnset($offset)
{
// 使“数组”只读
}

function
count()
{
$array = array(1, 2, 3, 4);
return
count($array);
}
// function

function getArray()
{
return array(
1, 2, 3, 4);
}
// function

function getIterator()
{
return new
ArrayIterator(array(1, 2, 3, 4));
}
// function

function __toString()
{
return
'String test';
}
// function
} // class

$foobar = new foobar();
print
$foobar[0].'<br/>';
print
$foobar->foo.'<br/>';
print
count($foobar).'<br/>';

foreach (
$foobar as $k=>$v)
{
print
$k.'=>'.$v.'<br/>';
}
// foreach

var_dump($foobar->getArray());

print
$foobar;

/* Generated output:
1
foo
4
0=>1
1=>2
2=>3
3=>4
array
0 => int 1
1 => int 2
2 => int 3
3 => int 4
String test
*/
?>

为了正确使用,你必须定义除了getArray()之外的所有这些方法。

浏览SPL的源代码将非常有帮助。

ps.: 对不起,我的英语不好
To Top