Fonctions.php uniques ou divisées en plusieurs petits fichiers?

14

Je crée un cadre simple avec des options de thème. J'ai divisé des morceaux de code functions.phpet les ai placés dans une structure de dossiers spécifique.

Maintenant, dans mon functions.phpfichier principal , je n'ai que des require_onceappels vers ces fichiers.

Mais pour les besoins de l'argument - disons que je vais me retrouver avec 20 fichiers à inclure.

DES QUESTIONS:

  1. Cela a-t-il un effet visible sur les performances de WP?
  2. Est-il préférable de tout garder dans un seul fichier (functions.php)
  3. Quelle est la meilleure manière de s'occuper de ça ?

Merci.

MegaMan
la source

Réponses:

12

1. Cela a-t-il un effet visible sur les performances de WP?

SI cela aurait un effet réel pour certains petits fichiers, alors il aurait un effet qui aurait un impact inférieur à WP: PHP et aux performances du serveur. Cela a-t-il vraiment un effet? Pas vraiment. Mais vous pouvez tout simplement commencer à faire vous-même des tests de performances.

2. Est-il préférable de tout garder dans un seul fichier (functions.php)

Maintenant, la question est "Quoi de mieux"? Du temps de chargement global des fichiers? Du point de vue de l'organisation des fichiers? De toute façon, cela ne fait aucune différence. Faites-le de manière à ne pas perdre la vue d'ensemble et à maintenir le résultat d'une manière qui vous soit agréable.

3. quelle est la meilleure façon de procéder?

Ce que je fais d' habitude est simplement accrocher quelque part dans ( plugins_loaded, after_setup_theme, etc. - dépend de ce que vous avez besoin) et il suffit de les exiger de tous:

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

Quoi qu'il en soit, vous pouvez également le rendre un peu plus compliqué et flexible. Jetez un œil à cet exemple:

<?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;
    }
}

C'est une classe qui fait essentiellement la même chose (nécessite PHP 5.3+). L'avantage est qu'il est un peu plus fin, vous pouvez donc simplement charger des fichiers à partir de dossiers dont vous avez besoin pour effectuer une tâche spécifique:

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

foreach ( $fileLoader as $file )
    $fileLoader->loadFile( $file );

Mise à jour

Comme nous vivons dans un nouveau monde post-PHP v5.2, nous pouvons utiliser le \FilterIterator. Exemple de la variante la plus courte:

$files = new \FilesystemIterator( __DIR__.'/src', \FilesystemIterator::SKIP_DOTS );
foreach ( $files as $file )
{
    /** @noinspection PhpIncludeInspection */
    ! $files->isDir() and include $files->getRealPath();
}

Si vous devez vous en tenir à PHP v5.2, vous pouvez toujours utiliser \DirectoryIteratorle code à peu près le même.

kaiser
la source
cool. Merci pour l'explication :) vérifier les fichiers dans un dossier spécifique n'aidera probablement pas ce que je fais, bien que ce soit une bonne idée. J'essaie de créer un cadre modulaire. Ainsi, tous les "modules" seraient dans des fichiers séparés qui seraient listés comme des entrées distinctes (require_once) dans le functions.php. De cette façon, si quelqu'un ne veut pas inclure l'un des modules (par exemple: thème-personnalisateur) - alors il suffit de le commenter, etc. C'est le plan de toute façon :) Merci encore.
MegaMan
@MegaMan Vous pouvez également filtrer la sortie avant d'appeler loadFile()ou require_once. Il suffit donc d'offrir quelque chose comme un support de thème où l'utilisateur lui-même ne peut utiliser add_theme_support()/remove_*()que les modules qu'il souhaite. Utilisez ensuite simplement le résultat pour $loadFile()ou glob(). Btw, si c'était votre solution, veuillez la marquer comme telle. Merci.
kaiser
0

J'ai retravaillé @kaiser pour répondre un peu à mes besoins - j'ai pensé le partager. Je voulais plus d'options, celles-ci sont expliquées dans le code et dans l'exemple d'utilisation ci-dessous.

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;
    }
}


Exemple d'utilisation:

$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 );
}
Nicolai
la source