Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am creating a simple framework with theme options. I have divided chunks of code within functions.php and placed it within a specific folder structure.

Now in my main functions.php file, I only have require_once calls to these files.

But for the sake of argument - let's say that I'll end up with 20 files to include.

QUESTIONS:

  1. Does this have effect on WP performance in a visible way ?
  2. Is it better to keep it all within 1 file (functions.php)
  3. what is the best way to go about this ?

Thanks.

share|improve this question

2 Answers 2

up vote 11 down vote accepted

1. Does this have effect on WP performance in a visible way ?

IF it would have a real affect for some small files, then it would have an affect that has an impact lower than WP: PHP and server performance. Does it really have an affect? Not really. But you can still simply start doing performance tests yourself.

2. Is it better to keep it all within 1 file (functions.php)

Now the question is "What is better"? From overall file(s) loading time? From file organisation point of view? Anyway, it doesn't make any difference. Do it in a way so you don't loose overview and can maintain the result in a way that is pleasant for you.

3. what is the best way to go about this?

What I normally do is simply hooking somewhere in (plugins_loaded, after_setup_theme, etc. - depends on what you need) and then just require them all:

foreach ( glob( plugin_dir_path( __FILE__ ) ) as $file )
    require_once $file;

Anyway, you can make it a little more complicated and flexible as well. Take a look at that example:

<?php

namespace WCM;

defined( 'ABSPATH' ) OR exit;

class FilesLoader implements \IteratorAggregate
{
    private $path = '';

    private $files = array();

    public function __construct( $path )
    {
        $this->setPath( $path );
        $this->setFiles();
    }

    public function setPath( $path )
    {
        if ( empty( $this->path ) )
            $this->path = \plugin_dir_path( __FILE__ ).$path;
    }

    public function setFiles()
    {
        return $this->files = glob( "{$this->getPath()}/*.php" );
    }

    public function getPath()
    {
        return $this->path;
    }

    public function getFiles()
    {
        return $this->files;
    }

    public function getIterator()
    {
        $iterator = new \ArrayIterator( $this->getFiles() );
        return $iterator;
    }

    public function loadFile( $file )
    {
        include_once $file;
    }
}

It's a class that does basically the same (needs PHP 5.3+). The benefit is that it's a bit more fine grained, so you can easily just load files from folders that you need to perform a specific task:

$fileLoader = new WCM\FilesLoader( 'assets/php' );

foreach ( $fileLoader as $file )
    $fileLoader->loadFile( $file );
share|improve this answer
    
cool. Thank you for the explanation :) checking for files in a specific folder probably won't help with what I'm doing, although it's a nice idea. I'm trying to make a framework which is Modular. So all "modules" would be in separate files which would be listed as separate entries (require_once) in the functions.php. That way if someone doesn't want to include one of the modules (for example: theme-customizer) - then can just comment that out etc. That's the plan anyways :) Thanks again. –  MegaMan Aug 29 '13 at 11:54
    
@MegaMan You could as well filter the output before calling loadFile() or require_once. So simply offer something like theme support where the user himself can use add_theme_support()/remove_*() to only take the modules he wants. Then simply use the result for $loadFile() or glob(). Btw, if this was your solution, please mark it as such. Thanks. –  kaiser Aug 29 '13 at 12:03

I reworked @kaiser answer a bit to my needs - thought I share it. I wanted more options, those are explained inside the code and at the usage example below.

Code:

<?php

defined( 'ABSPATH' ) OR exit;

/**
 * Functions_File_Loader
 * 
 * Makes it possible to clutter the functions.php into single files.
 * 
 * @author kaiser
 * @author ialocin
 * @link http://wordpress.stackexchange.com/q/111970/22534
 *
 */

class Functions_File_Loader implements IteratorAggregate {

    /**
     * @var array
     */
    private $parameter = array();

    /**
     * @var string
     */
    private $path;

    /**
     * @var string
     */
    private $pattern;

    /**
     * @var integer
     */
    private $flags;

    /**
     * @var array
     */
    private $files = array();

    /**
     * __construct
     *
     * @access public 
     * @param array $parameter
     */
    public function __construct( $parameter ) {
        $this->set_parameter( $parameter );
        $this->set_path( $this->parameter[ 'path' ] );
        $this->set_pattern( $this->parameter[ 'pattern' ] );
        $this->set_flags( $this->parameter[ 'flags' ] );
        $this->set_files();
    }

    /**
     * set_parameter
     *
     * @access public 
     * @param array $parameter
     */
    public function set_parameter( $parameter ) {
        if ( empty( $parameter ) )
            $this->parameter = array('','','');
        else
            $this->parameter = $parameter;
    }

    /**
     * get_parameter
     *
     * @access public 
     * @return array
     */
    public function get_parameter() {
        return $this->parameter;
    }

    /**
     * set_path
     *
     * defaults to get_stylesheet_directory()
     * 
     * @access public 
     * @param string $path
     */
    public function set_path( $path ) {
        if ( empty( $path ) )
            $this->path = get_stylesheet_directory().'/';
        else
            $this->path = get_stylesheet_directory().'/'.$path.'/';
    }

    /**
     * get_path
     *
     * @access public 
     * @return string
     */
    public function get_path() {
        return $this->path;
    }

    /**
     * set_pattern
     *
     * defaults to path plus asterisk »*«
     * 
     * @access public 
     * @param string $pattern
     */
    public function set_pattern( $pattern ) {
        if ( empty( $pattern ) )
            $this->pattern = $this->get_path() . '*';
        else
            $this->pattern = $this->get_path() . $pattern;
    }

    /**
     * get_pattern
     *
     * @access public 
     * @return string
     */
    public function get_pattern() {
        return $this->pattern;
    }

    /**
     * set_flags
     *
     * @access public 
     * @param integer $flags
     */
    public function set_flags( $flags ) {
        if ( empty( $flags ) )
            $this->flags = '0';
        else
            $this->flags = $flags;
    }

    /**
     * get_flags
     *
     * @access public 
     * @return integer
     */
    public function get_flags() {
        return $this->flags;
    }


    /**
     * set_files
     *
     * @access public 
     */
    public function set_files() {
        $pattern = $this->get_pattern();
        $flags = $this->get_flags();
        $files = glob( $pattern, $flags );
        $this->files = $files;
    }


    /**
     * get_files
     *
     * @access public 
     * @return array
     */
    public function get_files() {
        return $this->files;
    }

    /**
     * getIterator
     * 
     * This function name has to be kept
     * 
     * @access public 
     * @return void
     */
    public function getIterator() {
        $iterator = new ArrayIterator( $this->get_files() );
        return $iterator;
    }

    /**
     * load_file
     *
     * @access public 
     * @param string $file
     */
    public function load_file( $file ) {
        include_once $file;
    }
}


Usage example:

$parameter = array(
        // define path relative to get_stylesheet_directory()
        // optional, defaults to get_stylesheet_directory()
        'path' => 'includes/plugins',
        // optional, defaults to asterisk »*«
        // matches all files ending with ».php« 
        // and not beginning with »_«, good for quickly deactivating 
        // directories searched are »path« and »subfolders«
        // Additional examples:
        // '{*/,}{[!_],}func-*.php' same as above but for files with a prefix
        // '[!_]*.php' php files in defined »path«, not beginning with »_« 
        'pattern' => '{*/,}[!_]*.php',
        // optional, defaults to 0
        // needed if for example brackets are used
        // more information: http://www.php.net/manual/en/function.glob.php
        'flags' => GLOB_BRACE
    );
// create object
$functionsfileloader = new Functions_File_Loader( $parameter );
// load the files
foreach ( $functionsfileloader as $file ) {
    $functionsfileloader->load_file( $file );
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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