International PHP Conference Berlin 2025

SPL 関数

目次

  • class_implements — 与えられたクラスあるいはインターフェイスが実装しているインターフェイスを返す
  • class_parents — 与えられたクラスの親クラスを返す
  • class_uses — 指定したクラスが使っているトレイトを返す
  • iterator_apply — ユーザー関数をイテレータのすべての要素でコールする
  • iterator_count — イテレータにある要素をカウントする
  • iterator_to_array — イテレータを配列にコピーする
  • spl_autoload — __autoload() のデフォルト実装
  • spl_autoload_call — 要求されたクラスを読み込むために、すべての登録済みの __autoload() 関数を試す
  • spl_autoload_extensions — spl_autoload 用のデフォルトの拡張子を登録し、それを返す
  • spl_autoload_functions — すべての登録済み __autoload() 関数を返す
  • spl_autoload_register — 指定した関数を __autoload() の実装として登録する
  • spl_autoload_unregister — 指定した関数の、__autoload() の実装としての登録を解除する
  • spl_classes — 利用可能な SPL クラスを返す
  • spl_object_hash — 指定したオブジェクトのハッシュ ID を返す
  • spl_object_id — 与えられたオブジェクトを扱う数値オブジェクトを返す
add a note

User Contributed Notes 8 notes

up
8
ville</.>witt</a>gmail</.>com
18 years ago
These to funtions has excatly the same output, the only diff. is in which directory iterator they use. I hope someone out there can use it:
<?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();
?>
up
5
loaded67 at hotmail dot com
16 years ago
For some application I needed to reverse some standard iterators.

So I mocked up this flexible function.
Enjoy

<?php
function reverse_iterator(Iterator $iterator){
$type = get_class($iterator);
$array = array_reverse(iterator_to_array($iterator), true);
return new
$type($array);
}
?>
up
3
semperluc (at) yahoo._forgot_the_rest
17 years ago
<?php
/*
How to store SPL Iterator results (rather than just echo-and-forget):

The library of Iterators are object based, so you need to trick the little rascals into an array.
Here's how (two ways) ...

1. Explicit typecasts: $a[] = (array)$Obj->objMethod();

2. Array definition: $a[] = array( key => $Obj->objMethod() );

Examples: DirectoryIterator()
*/

// 1. explicity typecast object as array
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 />";
//

// or

// 2. define array as 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>";
//
?>
up
2
benny at whitewashing dot de
16 years ago
I have to correct my implementation from before. The example before only supported correct read-access but failed on setting new values after creation of the ArrayMultiObject. Also i had to correct a bug that occured from my CopyPasteChange into the comment textarea.

This snippet now hopefully implements a fully functional multidimensional array, represented by an 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);
}
}
?>
up
2
helly at php dot net
19 years ago
There is a RecursiveFilterIterator that makes the above code much easier. And then ther is ParentIterator thta is already a filtering recursive iterator that only accepts elements that have children, with a RecursiveDirectoryIterator as inner iterator you would obviously get only the directories. Further more it ensures that it creates the correct children. All in all you simply need to do this:

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

foreach($it as $dir => $o) { ... }
up
2
phil &ampersat; flatnet.net
20 years ago
Here's a sample implementation of the RecursiveDirectoryIterator class. It prints a simple treeview of a given directory:
<?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:/'));
?>
up
2
adove at booyahnetworks dot com
19 years ago
Something to note that, at least to me, seems pretty important and is not entirely clear in the documentation is the fact that the ArrayObject class supports get/set on uni-dimensional keys and get ONLY on *passed* multi-dimensional keys/paths (see source below). If you, like me, need to support array accesss overloading for multi-dimensional data, you will need to derive from ArrayObject and overide the ArrayAccess interface methods to "walk" passed data and convert embedded arrays to objects of some kind...

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

Illustration of the issue:

$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";

// NEITHER of the two below will work!
$oArray["test"]["one"] = "Yes I do!";
$oArray["test"]["yes"] = array(
"hello" => "Goodbye!"
);

var_dump($oArray);

---
Note from the extension author:
Actually there is RecursiveArrayObject and RecursiveArrayIterator to deal with recursive structures. However this does not always solve all multidimensional issues as expected.
up
1
prometheus - csaba dot dobai at php-sparcle dot hu
17 years ago
This code is an example. By using classes like this, you gives a chance to create classes which extends another class but have most of the ability what a class extends ArrayObject (like multiple inheritance):

<?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
*/
?>

For proper use you must be define all these methods except getArray()

Browse SPL's sources to be a very helpful think.

ps.: sry for my english
To Top