1

I've made this little function which I'm wanting to call all the files within a directory.

I don't think the glob() == false would work though. I'm new to this function so not aware of all possibilities and I find the php.net references unhelpful to some extent.

My desired outcome is if glob() fails to load any files an array of the files can be loaded via require_once() separately for each file. This would just be more of a fallback, unless there is an easier more efficient option.

if(glob() == false) { echo "0 files found" } else {
    foreach( glob(get_stylesheet_directory() . '/postypes/*.php') as $path )
        require_once( $path );
}
3
  • 1
    Have you considered using an autoloader? The files in question would only be loaded as and when they are needed with no manual requires or includes necessary – Tom J Nowell May 8 '14 at 16:02
  • @TomJNowell Please consider adding an answer for that – kaiser May 8 '14 at 16:10
  • I could but while interesting/useful to the asker, it wouldn't actually answer the question, perhaps a new question.. once I've had a cup of tea – Tom J Nowell May 8 '14 at 16:38
3

Loading files from a directory - the historical way

The glob() function has three possible return values:

  • Array( filenames ) => success
  • Array() empty => nothing found
  • FALSE => Error

So the correct check would be

$files = glob( sprintf( 
    '%s/postypes/*.php',
    get_stylesheet_directory()
) );
if ( empty( $files )
{
    _e( 'No PHP files found', 'your-textdomain' );
}
elseif ( ! $files )
{
    _e( 'Shrug! There went something terribly wrong!', 'your-textdomain' );
}
else
{
    foreach ( $files as $file )
        include_once $file;
}

…buuuut…

The current days way to fetch & load files - PHP 5.3+

Since we are already reaching the end of life of PHP 5.3 support, we can assume that someone at least got PHP 5.3.x installed and therefore has the SPL (Standard PHP Library) extension installed - even Ubuntu 12.04 LTS (Long term support) has 5.3 packaged / Ubuntu current is v14. Even when you are running PHP 5.2.x, the SPL has to be forcefully turned off.

And the SPL ships with the DirectoryIterator. So a good setup to load files would look like this:

$it = new DirectoryIterator( sprintf( 
    '%s/postypes/*.php',
    get_stylesheet_directory()
) );

$it->rewind();
foreach ( $it as $fileInfo )
{
    if ( $fileInfo->isDot() )
        continue;

    include_once $fileInfo->getFileName();
}

Extended ...

(Edit) For some reason, I mixed the DirectoryIterator with the FilesystemIterator. Of course you should use the later for PHP 5.3 as the later one is a follow up development of the first one.

The nice thing is, that the FilesystemIterator as well as the RecursiveDirectoryIterator has FLAGS, so you can - instead of using the isDot() method - simply set a flag:

$it = new FilesystemIterator( __DIR__.'/assets', FilesystemIterator::SKIP_DOTS );
$it = new RecursiveDirectoryIterator( __DIR__.'/assets', FilesystemIterator::SKIP_DOTS );

Here's a different example with a little more detailed checks:

# Assume we got this in the functions.php file of a theme
# and we want to load PHP vendor files.
$it = new FilesystemIterator(
    __DIR__.'/vendor/*.php',
    FilesystemIterator::SKIP_DOTS
    | FilesystemIterator::CURRENT_AS_FILEINFO
);

$it->rewind();
while ( $it->valid() )
{
    if (
        $it->isReadable()
        AND $it->isFile()
        AND $it->current() instanceof \SplFileInfo
    )
        include_once $it->current()->getFilename()

    $it->next();
}

You could as well search through different directories using the RecursiveDirectoryIterator and adding your pattern there. Make sure to use a max depth to not overdo it with a search.

What you could do as well, is using a NoRewindIterator, which takes an Iterator or something else that implements Traversable and loops over it. This way you can make sure that you won't iterator over a single file more than once.

$it = new RecursiveDirectoryIterator(
    __DIR__.'/vendor/*.php',
    FilesystemIterator::SKIP_DOTS
    | FilesystemIterator::CURRENT_AS_FILEINFO
);
$it->rewind();
$files = new NoRewindIterator( $it );
$files->rewind();
foreach ( $files as $file )
    # ...

but that may just be too much.

2
  • Great awnser Kaiser. I understand this and nice to see an OOP option so DirectoryIterator is a new class shopped with SPL? also is there a way to load multiple directories applying an array of values within the sprintf? – Dannyw24 May 8 '14 at 15:13
  • @Dannyw24 see update – kaiser May 8 '14 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.