|
Standard PHP Library (SPL) FunctionsSPL is a collection of interfaces and classes that are meant to solve standard problems.
Tip:
A more detailed documentation of SPL can be found » here. The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime.
Warning:
SPL uses class constants since PHP 5.1. Prior releases use global constants
in the form
Table of Contents
Code Examples / Notes » ref.spljce
You may access the ArrayObject as an array by using explicit typecasts: class myArrayObject extends ArrayObject { function getArray() { return (array) $this; } } prometheus - csaba dot dobai
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 foo=>foo array 'foo' => string 'foo' (length=3) String teszt */ ?> 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 villewittgmailcom
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: <? 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(); ?> helly
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) { ... } dave
There are some interfaces used here that are not documented. It took a bit to figure this one out, but you can create your own ArrayObject type class (that is, one who's objects can be access using the array [$index] syntax). Your class must just implement ArrayAccess. Which has four abstract methods you must define. For example: <?php class Collection Implements ArrayAccess{ protected $array; function offsetExists($offset){ if(isset($this->array[$offset])){ return TRUE; } else{ return FALSE; } } function offsetGet($offset){ return $this->array[$offset]; } function offsetSet($offset, $value){ if($offset){ $this->array[$offset] = $value; } else{ $this->array[] = $value; } } function offsetUnset($offset){ } } ?> You'll have to jump through a couple more hoops to get foreach and print_r and the likes to behave properly. But with just this, you can : <?php $col = new Collction(); $col[] = new ObjectX(); $col[] = new ObjectX(123); echo $col[0]->name; // etc. ?> kevin
The most comprehensive of all tutorials regarding SPL has been written with some help from Marcus and can be found here. http://www.phpro.org/tutorials/Introduction-to-SPL.html Enjoy adove
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. prometheus - csaba dot dobai
Oops, I was take a mistake on previos post's last comment. Here it is the correct version: <?php /* 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 */ ?> Sorry for that, I missed to refresh my browser :) mastabog
Marcus Boerger has done a wonderful job developing the SPL. He also provided many examples using the SPL that can be found in the php5 sources. Just unpack the sources and in the ext/spl/examples directory you have some very nice ones. Thank you Marcus for all your efforts! Now, a contribution of mine (i think it will be implemented later anyway). The RecursiveIteratorIterator could use a depth limit option. Very useful in many situations (e.g. show just the 1st subdirectory of a list of dirs). I'm sure this can be done in other ways. Here's my 2 cents: <?php /** * Limit Depth RecursiveIteratorIterator class * */ class LimitRecursiveIteratorIterator extends RecursiveIteratorIterator { protected $depth_limit; /** * No depth limit by default * **/ public function __construct (Iterator $it, $mode = RIT_SELF_FIRST, $depth_limit = -1) { parent::__construct($it, $mode); $this->depth_limit = $depth_limit; } /** * After the call to next() if depth is bigger than limit then * just skip all subIterators for that depth until depth end. * **/ public function next () { parent::next(); if ($this->getDepth() == $this->depth_limit) { while ($this->getSubIterator()->valid()) $this->getSubIterator()->next(); parent::next(); } } } ?> Then you can try this: <?php /** * Directories only filter iterator class * */ class DirectoriesOnlyIterator extends FilterIterator implements RecursiveIterator { public function __construct ($path) { parent::__construct(new RecursiveDirectoryIterator($path)); } public function accept() { return $this->getInnerIterator()->hasChildren(); } public function hasChildren () { return $this->getInnerIterator()->hasChildren(); } public function getChildren () { return new self($this->getInnerIterator()->getPathname()); } } $it = new LimitRecursiveIteratorIterator(new DirectoriesOnlyIterator('c:'), RIT_SELF_FIRST, 2); // list all dirs and 1st subdir of the c: drive (might take a while depending on how many you have) foreach ($it as $key => $value) { echo str_repeat(' ', $it->getDepth()) . "$value\n"; } ?> This is considerably faster than using just the RecursiveIteratorIterator and ignoring yourself in the foreach loop the values for depth > limit (i.e. if($it->getDepth() > $limit) continue;). that is because the class will still parse everything up to the last depth level of every head node. You can then play and display nice trees (might need a while() loop or the CachingRecursiveIterator to detect end nodes/leafs). There is already an example provided by Marcus in the ext/spl/examples dir i mentioned above. Happy SPL-ing :), Bogdan P.S. I think some of the classes should call rewind() at instantiation time ... If you try to put a Caching* object in a foreach loop you will lose the first/last element. Instead, you should call rewind() and then go with a while($cit->valid()) loop and using current() and key() inside it. just_somedood
Just a follow up on dave at tunasoft's post. To give his example of ArrayAccess use of foreach, it's easiest to implement IteratorAggregate and use the ArrayIterator object as the iterator, as below: <?php class Collection implements ArrayAccess,IteratorAggregate { public $objectArray = Array(); //**these are the required iterator functions function offsetExists($offset) { if(isset($this->objectArray[$offset])) return TRUE; else return FALSE; } function & offsetGet($offset) { if ($this->offsetExists($offset)) return $this->objectArray[$offset]; else return (false); } function offsetSet($offset, $value) { if ($offset) $this->objectArray[$offset] = $value; else $this->objectArray[] = $value; } function offsetUnset($offset) { unset ($this->objectArray[$offset]); } function & getIterator() { return new ArrayIterator($this->objectArray); } //**end required iterator functions public function doSomething() { echo "I'm doing something"; } } ?> I LOVE the new SPL stuff in PHP. The above allows you to have methods inside of your array, and when treated as an array the data components are returned, such as: <?php class Contact { protected $name = NULL; public function set_name($name) { $this->name = $name; } public function get_name() { return ($this->name); } } $bob = new Collection(); $bob->doSomething(); $bob[] = new Contact(); $bob[5] = new Contact(); $bob[0]->set_name("Superman"); $bob[5]->set_name("a name of a guy"); foreach ($bob as $aContact) { echo $aContact->get_name() . "\r\n"; } ?> Would work just fine. This make code so much simpler and easy to follow, it's great. This is exactly the direction I had hoped PHP5 was going! ericjr !_
In addition to "mastabog at hotmail dot com"`s note about the recursive directory iterator, his method skips symlinked directories, because getChildren() doesn't return true if the directory is symlinked. To fix this, the script should always instanciate an innerInterator when dealing with symlinked directories like so: <? class DirectoriesOnlyIterator extends FilterIterator implements RecursiveIterator { public function __construct ($path) { parent::__construct(new RecursiveDirectoryIterator($path)); } public function accept() { return $this->getInnerIterator()->hasChildren(); } public function hasChildren () { return $this->hasChildren() || $this->isLink(); } public function getChildren () { return new self($this->getInnerIterator()->getPathname()); } } zaufi
I'v done with my PluginsManager... Sample code to use plugins may looks lije this: <?php require_once('lib/plugins-manager.inc.php'); // Load and use conctere plugin module $p = new Plugin('test.class.php'); $test = $p->class_factory('test', 1, 2); $test->foo(); // ... oneliner ;) $p = $pm['test.class.php']->class_factory('test', 1, 2)->foo(); // Scan for plugable modules, construct an instance and call foo() $pm = new PluginsManager('.'); foreach ($pm as $p) { $p->class_factory('test', 1, 2)->foo(); } ?> You may download php files at my tw.o page: http://tikiwiki.org/tiki-index.php?page=UserPagezaufi (see page attachments below) phil &ersat; flatnet.net
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:/')); ?>
Excelent article here by Harry Fuecks... http://www.sitepoint.com/print/php5-standard-library and some auto generated documentation that could be of some use here... http://www.php.net/~helly/php/ext/spl/index.html semperluc
<?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>"; // ?> |
Change Language.NET Functions Apache-specific Functions Alternative PHP Cache Advanced PHP debugger Array Functions Aspell functions [deprecated] BBCode Functions BCMath Arbitrary Precision Mathematics Functions PHP bytecode Compiler Bzip2 Compression Functions Calendar Functions CCVS API Functions [deprecated] Class/Object Functions Classkit Functions ClibPDF Functions [deprecated] COM and .Net (Windows) Crack Functions Character Type Functions CURL Cybercash Payment Functions Credit Mutuel CyberMUT functions Cyrus IMAP administration Functions Date and Time Functions DB++ Functions Database (dbm-style) Abstraction Layer Functions dBase Functions DBM Functions [deprecated] dbx Functions Direct IO Functions Directory Functions DOM Functions DOM XML Functions enchant Functions Error Handling and Logging Functions Exif Functions Expect Functions File Alteration Monitor Functions Forms Data Format Functions Fileinfo Functions filePro Functions Filesystem Functions Filter Functions Firebird/InterBase Functions Firebird/Interbase Functions (PDO_FIREBIRD) FriBiDi Functions FrontBase Functions FTP Functions Function Handling Functions GeoIP Functions Gettext Functions GMP Functions gnupg Functions Net_Gopher Haru PDF Functions hash Functions HTTP Hyperwave Functions Hyperwave API Functions i18n Functions IBM Functions (PDO_IBM) IBM DB2 iconv Functions ID3 Functions IIS Administration Functions Image Functions Imagick Image Library IMAP Informix Functions Informix Functions (PDO_INFORMIX) Ingres II Functions IRC Gateway Functions PHP / Java Integration JSON Functions KADM5 LDAP Functions libxml Functions Lotus Notes Functions LZF Functions Mail Functions Mailparse Functions Mathematical Functions MaxDB PHP Extension MCAL Functions Mcrypt Encryption Functions MCVE (Monetra) Payment Functions Memcache Functions Mhash Functions Mimetype Functions Ming functions for Flash Miscellaneous Functions mnoGoSearch Functions Microsoft SQL Server Functions Microsoft SQL Server and Sybase Functions (PDO_DBLIB) Mohawk Software Session Handler Functions mSQL Functions Multibyte String Functions muscat Functions MySQL Functions MySQL Functions (PDO_MYSQL) MySQL Improved Extension Ncurses Terminal Screen Control Functions Network Functions Newt Functions NSAPI-specific Functions Object Aggregation/Composition Functions Object property and method call overloading Oracle Functions ODBC Functions (Unified) ODBC and DB2 Functions (PDO_ODBC) oggvorbis OpenAL Audio Bindings OpenSSL Functions Oracle Functions [deprecated] Oracle Functions (PDO_OCI) Output Control Functions Ovrimos SQL Functions Paradox File Access Parsekit Functions Process Control Functions Regular Expression Functions (Perl-Compatible) PDF Functions PDO Functions Phar archive stream and classes PHP Options&Information POSIX Functions Regular Expression Functions (POSIX Extended) PostgreSQL Functions PostgreSQL Functions (PDO_PGSQL) Printer Functions Program Execution Functions PostScript document creation Pspell Functions qtdom Functions Radius Rar Functions GNU Readline GNU Recode Functions RPM Header Reading Functions runkit Functions SAM - Simple Asynchronous Messaging Satellite CORBA client extension [deprecated] SCA Functions SDO Functions SDO XML Data Access Service Functions SDO Relational Data Access Service Functions Semaphore SESAM Database Functions PostgreSQL Session Save Handler Session Handling Functions Shared Memory Functions SimpleXML functions SNMP Functions SOAP Functions Socket Functions Standard PHP Library (SPL) Functions SQLite Functions SQLite Functions (PDO_SQLITE) Secure Shell2 Functions Statistics Functions Stream Functions String Functions Subversion Functions Shockwave Flash Functions Swish Functions Sybase Functions TCP Wrappers Functions Tidy Functions Tokenizer Functions Unicode Functions URL Functions Variable Handling Functions Verisign Payflow Pro Functions vpopmail Functions W32api Functions WDDX Functions win32ps Functions win32service Functions xattr Functions xdiff Functions XML Parser Functions XML-RPC Functions XMLReader functions XMLWriter Functions XSL functions XSLT Functions YAZ Functions YP/NIS Functions Zip File Functions Zlib Compression Functions |