fleshed out (recursive)callbackfilteriterator

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@313182 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Peter Cowburn 2011-07-12 19:57:55 +00:00
parent 09bf078e8e
commit 07adc6b4c2
9 changed files with 316 additions and 79 deletions

View file

@ -12,7 +12,9 @@
<section xml:id="callbackfilteriterator.intro">
&reftitle.intro;
<para>
The <classname>CallbackFilterIterator</classname> is a concrete
<classname>FilterIterator</classname> which uses a <type>callback</type>
for filtering.
</para>
</section>
<!-- }}} -->
@ -29,31 +31,32 @@
<ooclass>
<classname>CallbackFilterIterator</classname>
</ooclass>
<ooclass>
<modifier>extends</modifier>
<classname>FilterIterator</classname>
<ooclass>
<modifier>extends</modifier>
<classname>FilterIterator</classname>
</ooclass>
<oointerface>
<interfacename>Iterator</interfacename>
</oointerface>
<oointerface>
<interfacename>Traversable</interfacename>
</oointerface>
<oointerface>
<interfacename>OuterIterator</interfacename>
<oointerface>
<interfacename>Iterator</interfacename>
</oointerface>
<oointerface>
<interfacename>Traversable</interfacename>
</oointerface>
<oointerface>
<interfacename>OuterIterator</interfacename>
</oointerface>
</classsynopsisinfo>
<!-- }}} -->
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.callbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[1])" />
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.callbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
<classsynopsisinfo role="comment">&InheritedMethods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.filteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
<classsynopsisinfo role="comment">&InheritedMethods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.filteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
</classsynopsis>
<!-- }}} -->

View file

@ -14,10 +14,13 @@
<void />
</methodsynopsis>
<para>
This method calls the callback with the current value, current key
and the inner iterator.
</para>
<para>
The callback is expected to return &true; if the current item is
to be accepted, or &false; otherwise.
</para>
&warn.undocumented.func;
</refsect1>
@ -29,10 +32,19 @@
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns &true; to accept the current item, or &false; otherwise.
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="callbackfilteriterator.examples">CallbackFilterIterator Examples</link></member>
<member><methodname>CallbackFilterIterator::__construct</methodname></member>
</simplelist>
</para>
</refsect1>
</refentry>

View file

@ -4,22 +4,21 @@
<refentry xml:id="callbackfilteriterator.construct" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>CallbackFilterIterator::__construct</refname>
<refpurpose>Create an Iterator from another iterator</refpurpose>
<refpurpose>Create a filtered iterator from another iterator</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<constructorsynopsis role="oop">
<modifier>public</modifier>
<methodname>CallbackFilterIterator::__construct</methodname>
<methodparam><type>Iterator</type><parameter>iterator</parameter></methodparam>
<methodparam><type>string</type><parameter>callback</parameter></methodparam>
</methodsynopsis>
<methodparam><type>callback</type><parameter>callback</parameter></methodparam>
</constructorsynopsis>
<para>
Creates a filtered iterator using the <parameter>callback</parameter> to
determine which items are accepted or rejected.
</para>
&warn.undocumented.func;
</refsect1>
<refsect1 role="parameters">
@ -29,7 +28,7 @@
<term><parameter>iterator</parameter></term>
<listitem>
<para>
The iterator to be filtered.
</para>
</listitem>
</varlistentry>
@ -37,7 +36,12 @@
<term><parameter>callback</parameter></term>
<listitem>
<para>
The callback, which should return &true; to accept the current item
or &false; otherwise.
See <link linkend="callbackfilteriterator.examples">Examples</link>.
</para>
<para>
May be any valid <type>callback</type> value.
</para>
</listitem>
</varlistentry>
@ -47,10 +51,19 @@
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.void;
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="callbackfilteriterator.examples">CallbackFilterIterator Examples</link></member>
<member><methodname>CallbackFilterIterator::accept</methodname></member>
</simplelist>
</para>
</refsect1>
</refentry>

View file

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="callbackfilteriterator.examples" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>CallbackFilterIterator &amp; RecursiveCallbackFilterIterator Examples</title>
<para>
The main purpose of the <classname>CallbackFilterIterator</classname> and
<classname>RecursiveCallbackFilterIterator</classname> classes is to
filter the contents of an iterator using a callback rather than having
to go to the trouble of creating a bespoke class extending
the abstract <classname>FilterIterator</classname>.
</para>
<para>
The callback should accept up to three arguments:
the current item, the current key and the iterator, respectively.
</para>
<example xml:id="callbackfilteriterator.examples.args">
<title>Available callback arguments</title>
<programlisting role="php">
<![CDATA[
<?php
/**
* Callback for CallbackFilterIterator
*
* @param $current Current item's value
* @param $key Current item's key
* @param $iterator Iterator being filtered
* @return boolean TRUE to accept the current item, FALSE otherwise
*/
function my_callback($current, $key, $iterator) {
// Your filtering code here
}
?>
]]>
</programlisting>
</example>
<para>
Any <type>callback</type> may be used; such as a string containing a
function name, an array for a method, or an anonymous
function.
</para>
<example xml:id="callbackfilteriterator.examples.basic">
<title>Callback basic examples</title>
<programlisting role="php">
<![CDATA[
<?php
$dir = new FilesystemIterator(__DIR__);
// Filter large files ( > 100MB)
function is_large_file($current) {
return $current->isFile() && $current->getSize() > 104857600;
}
$large_files = new CallbackFilterIterator($dir, 'is_large_file');
// Filter directories
$files = new CallbackFilterIterator($dir, function ($current, $key, $iterator) {
return $current->isDir() && ! $iterator->isDot();
});
?>
]]>
</programlisting>
</example>
<para>
Filtering a recursive iterator generally involves two conditions.
The first is that, to allow recursion, the callback function should return &true;
if the current iterator item has children.
The second is the normal filter condition, such as a file size or extension check as
in the example below.
</para>
<example xml:id="callbackfilteriterator.examples.recursive">
<title>Recursive callback basic examples</title>
<programlisting role="php">
<![CDATA[
<?php
$dir = new FilesystemIterator(__DIR__);
// Filter large files ( > 100MB)
$files = new CallbackFilterIterator($dir, function ($current, $key, $iterator) {
// Allow recursion
if ($iterator->hasChildren()) {
return TRUE;
}
// Check for large file
if ($current->isFile() && $current->getSize() > 104857600) {
return TRUE;
}
return FALSE;
});
foreach (new RecursiveIteratorIterator($files) as $file) {
echo $file->getPathname() . PHP_EOL;
}
?>
]]>
</programlisting>
</example>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

View file

@ -12,7 +12,9 @@
<section xml:id="recursivecallbackfilteriterator.intro">
&reftitle.intro;
<para>
The <classname>RecursiveCallbackFilterIterator</classname> is a concrete
<classname>RecursiveFilterIterator</classname> which uses a <type>callback</type>
for filtering.
</para>
</section>
<!-- }}} -->
@ -29,35 +31,36 @@
<ooclass>
<classname>RecursiveCallbackFilterIterator</classname>
</ooclass>
<ooclass>
<modifier>extends</modifier>
<classname>CallbackFilterIterator</classname>
<ooclass>
<modifier>extends</modifier>
<classname>CallbackFilterIterator</classname>
</ooclass>
<oointerface>
<interfacename>OuterIterator</interfacename>
</oointerface>
<oointerface>
<interfacename>Traversable</interfacename>
</oointerface>
<oointerface>
<interfacename>Iterator</interfacename>
</oointerface>
<oointerface>
<interfacename>RecursiveIterator</interfacename>
<oointerface>
<interfacename>OuterIterator</interfacename>
</oointerface>
<oointerface>
<interfacename>Traversable</interfacename>
</oointerface>
<oointerface>
<interfacename>Iterator</interfacename>
</oointerface>
<oointerface>
<interfacename>RecursiveIterator</interfacename>
</oointerface>
</classsynopsisinfo>
<!-- }}} -->
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.recursivecallbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[1])" />
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.recursivecallbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
<classsynopsisinfo role="comment">&InheritedMethods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.callbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
<classsynopsisinfo role="comment">&InheritedMethods;</classsynopsisinfo>
<xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.callbackfilteriterator')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[1])" />
</classsynopsis>
<!-- }}} -->

View file

@ -9,17 +9,17 @@
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<constructorsynopsis role="oop">
<modifier>public</modifier>
<methodname>RecursiveCallbackFilterIterator::__construct</methodname>
<methodparam><type>RecursiveIterator</type><parameter>iterator</parameter></methodparam>
<methodparam><type>string</type><parameter>callback</parameter></methodparam>
</methodsynopsis>
</constructorsynopsis>
<para>
Creates a filtered iterator from a <interfacename>RecursiveIterator</interfacename>
using the <parameter>callback</parameter> to determine which
items are accepted or rejected.
</para>
&warn.undocumented.func;
</refsect1>
<refsect1 role="parameters">
@ -29,7 +29,7 @@
<term><parameter>iterator</parameter></term>
<listitem>
<para>
The recursive iterator to be filtered.
</para>
</listitem>
</varlistentry>
@ -37,7 +37,12 @@
<term><parameter>callback</parameter></term>
<listitem>
<para>
The callback, which should return &true; to accept the current item
or &false; otherwise.
See <link linkend="callbackfilteriterator.examples">Examples</link>.
</para>
<para>
May be any valid <type>callback</type> value.
</para>
</listitem>
</varlistentry>
@ -47,10 +52,20 @@
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.void;
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="callbackfilteriterator.examples">RecursiveCallbackFilterIterator Examples</link></member>
<member><methodname>RecursiveCallbackFilterIterator::getChildren</methodname></member>
<member><methodname>RecursiveCallbackFilteriterator::hasChildren</methodname></member>
</simplelist>
</para>
</refsect1>
</refentry>

View file

@ -14,11 +14,12 @@
<void />
</methodsynopsis>
<para>
Fetches the filtered children of the inner iterator.
</para>
<para>
<methodname>RecursiveCallbackFilterIterator::hasChildren</methodname> should be used
to determine if there are children to be fetched.
</para>
&warn.undocumented.func;
</refsect1>
<refsect1 role="parameters">
@ -29,7 +30,19 @@
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns a <classname>RecursiveCallbackFilterIterator</classname> containing
the children.
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="callbackfilteriterator.examples">RecursiveCallbackFilterIterator Examples</link></member>
<member><methodname>RecursiveCallbackFilterIterator::__construct</methodname></member>
<member><methodname>RecursiveCallbackFilteriterator::hasChildren</methodname></member>
</simplelist>
</para>
</refsect1>

View file

@ -14,11 +14,8 @@
<void />
</methodsynopsis>
<para>
Returns &true; if the current element has children, &false; otherwise.
</para>
&warn.undocumented.func;
</refsect1>
<refsect1 role="parameters">
@ -29,10 +26,51 @@
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns &true; if the current element has children, &false; otherwise.
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example xml:id="recursivecallbackfilteriterator.examples.basic">
<title><methodname>RecursiveCallbackFilterIterator::hasChildren</methodname> basic usage</title>
<programlisting role="php">
<![CDATA[
<?php
$dir = new FilesystemIterator(__DIR__);
// Recursively iterate over XML files
$files = new CallbackFilterIterator($dir, function ($current, $key, $iterator) {
// Allow recursion into directories
if ($iterator->hasChildren()) {
return TRUE;
}
// Check for XML file
if (!strcasecmp($current->getExtension(), 'xml')) {
return TRUE;
}
return false;
});
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><link linkend="callbackfilteriterator.examples">RecursiveCallbackFilterIterator Examples</link></member>
<member><methodname>RecursiveCallbackFilterIterator::__construct</methodname></member>
<member><methodname>RecursiveCallbackFilteriterator::getChildren</methodname></member>
</simplelist>
</para>
</refsect1>
</refentry>

View file

@ -1020,6 +1020,16 @@
<function name='multipleiterator::key' from='PHP 5 &gt;= 5.3.0'/>
<function name='multipleiterator::current' from='PHP 5 &gt;= 5.3.0'/>
<function name='multipleiterator::next' from='PHP 5 &gt;= 5.3.0'/>
<function name='callbackfilteriterator' from='PHP 5 &gt;= 5.4.0'/>
<function name='callbackfilteriterator::__construct' from='PHP 5 &gt;= 5.4.0'/>
<function name='callbackfilteriterator::accept' from='PHP 5 &gt;= 5.4.0'/>
<function name='recursivecallbackfilteriterator' from='PHP 5 &gt;= 5.4.0'/>
<function name='recursivecallbackfilteriterator::__construct' from='PHP 5 &gt;= 5.4.0'/>
<function name='recursivecallbackfilteriterator::getchildren' from='PHP 5 &gt;= 5.4.0'/>
<function name='recursivecallbackfilteriterator::haschildren' from='PHP 5 &gt;= 5.4.0'/>
</versions>
<!-- Keep this comment at the end of the file