PHP Conference Japan 2024

SPL 函式

目錄

新增註解

使用者貢獻的註解 8 則註解

ville</.>witt</a>gmail</.>com
18 年前
這兩個函式的輸出完全相同,唯一的區別在於它們使用的目錄迭代器。我希望有人能用得上它。
<?php
function listfilesin1 ($dir = ".", $depth=0) {
echo
"目錄: ".$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."<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
函式 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 迭代器結果(而不是僅僅 echo 後就丟棄):

迭代器庫是以物件為基礎的,因此您需要將這些小傢伙轉換成陣列。
以下是方法(兩種方式)...

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@php.net
19 年前
有個 `RecursiveFilterIterator` 可以讓上面的程式碼簡潔許多。然後還有 `ParentIterator`,它本身是一個過濾遞迴迭代器,只接受具有子元素的元素,以 `RecursiveDirectoryIterator` 作為內部迭代器,顯然只會取得目錄。此外,它還能確保建立正確的子元素。總之,你只需要這樣做:

$it = new RecursiveDirectoryIterator($path);
$it = new ParentIterator($it);
$it = new RecursiveIteratorIterator($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 類別支援對單維鍵的讀取/設定,以及*僅*對*傳入*的多維鍵/路徑進行讀取(請參考下方程式碼)。如果您像我一樣需要支援多維資料的陣列存取多載,您就需要繼承 ArrayObject 並覆寫 ArrayAccess 介面的方法,以「走訪」傳入的資料,並將嵌入的陣列轉換為某種物件...

參考錯誤回報 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)
{
// Makes "array" to readonly
}

public function
offsetUnset($offset)
{
// Makes "array" to readonly
}

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