Skip to content

Instantly share code, notes, and snippets.

@kabel
Created April 20, 2012 22:18
Show Gist options
  • Select an option

  • Save kabel/2432298 to your computer and use it in GitHub Desktop.

Select an option

Save kabel/2432298 to your computer and use it in GitHub Desktop.
Compare PHP RecursiveIteratorIterator use with FilterIteractors
<?php
/*
Filesystem layout of ./backup/
total 0
drwxrwxr-x 3 kabel staff 102 Apr 20 16:00 db
drwxrwx--x 3 root wheel 102 Apr 20 16:31 do-not-backup
./db:
total 8
-rw-rw-r-- 1 kabel staff 1 Apr 20 16:00 foo
./do-not-backup:
total 0
-rw-r--r-- 1 kabel staff 0 Apr 20 16:31 bar
*/
/**
* @author kabel
*
* @method RecursiveDirectoryIterator getInnerIterator()
* @method SplFileInfo current()
*/
class RecursiveDirectoryFilterIterator extends RecursiveFilterIterator
{
protected $_filters;
public function __construct(RecursiveDirectoryIterator $iterator, array $filters = array())
{
parent::__construct($iterator);
$this->_filters = $filters;
}
public function accept()
{
$current = (string)$this->current();
$currentFilename = $this->current()->getFilename();
if ($currentFilename == '.' || $currentFilename == '..') {
return false;
}
foreach ($this->_filters as $filter) {
if (false !== strpos($current, $filter)) {
return false;
}
}
return true;
}
public function getChildren()
{
return new self($this->getInnerIterator()->getChildren(), $this->_filters);
}
}
/* BEGIN file from the magento core - lib/Mage/Backup/Filesystem/Iterator/Filter.php: */
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category Mage
* @package Mage_Backup
* @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Filter Iterator
*
* @category Mage
* @package Mage_Backup
* @author Magento Core Team <core@magentocommerce.com>
*/
class Mage_Backup_Filesystem_Iterator_Filter extends FilterIterator
{
/**
* Array that is used for filtering
*
* @var array
*/
protected $_filters;
/**
* Constructor
*
* @param Iterator $iterator
* @param array $filters list of files to skip
*/
public function __construct(Iterator $iterator, array $filters)
{
parent::__construct($iterator);
$this->_filters = $filters;
}
/**
* Check whether the current element of the iterator is acceptable
*
* @return bool
*/
public function accept()
{
$current = $this->current()->__toString();
$currentFilename = $this->current()->getFilename();
if ($currentFilename == '.' || $currentFilename == '..') {
return false;
}
foreach ($this->_filters as $filter) {
if (false !== strpos($current, $filter)) {
return false;
}
}
return true;
}
}
/* END */
// Inner Filter <- good
$itr = new RecursiveIteratorIterator(new RecursiveDirectoryFilterIterator(
new RecursiveDirectoryIterator(dirname(__FILE__) . '/backup'), array('do-not-backup')
), RecursiveIteratorIterator::CHILD_FIRST);
foreach ($itr as $filePath => $fileInfo) {
echo $filePath . PHP_EOL;
}
// Outer Filter <- bad
$itr = new Mage_Backup_Filesystem_Iterator_Filter(new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(dirname(__FILE__) . '/backup'), RecursiveIteratorIterator::CHILD_FIRST
), array('do-not-backup'));
// This loop will throw an exception when it reaches the directory owned by root (permission denied)
// even though it is marked to be filtered out. FATAL ERROR :(
foreach ($itr as $filePath => $fileInfo) {
echo $filePath . PHP_EOL;
}
@kabel
Copy link
Copy Markdown
Author

kabel commented Apr 20, 2012

It is important to note that this test REQUIRES the filesystem layout described at the top (specifically note that the do-not-backup directory is owned by a different user AND is not readable by my user).

This will produce output similar to:

/Users/kabel/phptest/backup/db/foo
/Users/kabel/phptest/backup/db
/Users/kabel/phptest/backup/db/foo
/Users/kabel/phptest/backup/db
PHP Fatal error:  Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(/Users/kabel/phptest/backup/do-not-backup): failed to open dir: Permission denied' in /Users/kabel/phptest/RecursiveDirectoryIterator-test.php:154
Stack trace:
#0 [internal function]: RecursiveDirectoryIterator->__construct('/Users/kabel/ph...', 0)
#1 [internal function]: RecursiveDirectoryIterator->getChildren()
#2 /Users/kabel/phptest/RecursiveDirectoryIterator-test.php(154): FilterIterator->next()
#3 {main}
  thrown in /Users/kabel/phptest/RecursiveDirectoryIterator-test.php on line 154

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment