¿Funciones individuales.php o divididas en muchos archivos pequeños?

14

Estoy creando un marco simple con opciones de tema. He dividido fragmentos de código dentro functions.phpy los he colocado dentro de una estructura de carpetas específica.

Ahora en mi functions.phparchivo principal , solo tengo require_oncellamadas a estos archivos.

Pero en aras de la discusión, digamos que terminaré con 20 archivos para incluir.

PREGUNTAS

  1. ¿Tiene esto algún efecto en el rendimiento de WP de manera visible?
  2. ¿Es mejor mantenerlo todo dentro de 1 archivo (functions.php)
  3. ¿Cuál es la mejor manera de hacer esto?

Gracias.

Megaman
fuente

Respuestas:

12

1. ¿Tiene esto efecto en el rendimiento de WP de manera visible?

SI tendría un efecto real para algunos archivos pequeños, tendría un impacto menor que WP: PHP y el rendimiento del servidor. ¿Realmente tiene un efecto? Realmente no. Pero aún puede comenzar a hacer pruebas de rendimiento usted mismo.

2. ¿Es mejor mantenerlo todo dentro de 1 archivo (functions.php)

Ahora la pregunta es "¿Qué es mejor"? ¿Del tiempo total de carga de los archivos? ¿Desde el punto de vista de la organización de archivos? De todos modos, no hace ninguna diferencia. Hágalo de manera que no pierda la visión general y pueda mantener el resultado de una manera agradable para usted.

3. ¿ Cuál es la mejor manera de hacer esto?

Lo que normalmente hago es simplemente engancharme en algún lugar ( plugins_loaded, after_setup_themeetc., depende de lo que necesites) y luego solo requerirlos a todos:

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

De todos modos, también puedes hacerlo un poco más complicado y flexible. Echa un vistazo a ese ejemplo:

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

Es una clase que hace básicamente lo mismo (necesita PHP 5.3+). El beneficio es que es un poco más fino, por lo que puede cargar fácilmente archivos de carpetas que necesita para realizar una tarea específica:

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

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

Actualizar

Como vivimos en un nuevo mundo posterior a PHP v5.2, podemos hacer uso de \FilterIterator. Ejemplo de la variante más corta:

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

Si tiene que seguir con PHP v5.2, entonces aún puede \DirectoryIteratorusar el mismo código.

emperador
fuente
frio. Gracias por la explicación :) comprobar los archivos en una carpeta específica probablemente no ayudará con lo que estoy haciendo, aunque es una buena idea. Estoy tratando de hacer un marco que sea modular. Por lo tanto, todos los "módulos" estarían en archivos separados que se enumerarían como entradas separadas (require_once) en functions.php. De esa manera, si alguien no quiere incluir uno de los módulos (por ejemplo: personalizador de temas), puede comentarlo, etc. Ese es el plan de todos modos :) Gracias de nuevo.
MegaMan
@MegaMan También podría filtrar la salida antes de llamar loadFile()o require_once. Entonces, simplemente ofrezca algo como soporte de temas donde el usuario mismo pueda usar add_theme_support()/remove_*()para tomar solo los módulos que desee. Luego simplemente use el resultado para $loadFile()o glob(). Por cierto, si esta fue su solución, márquela como tal. Gracias.
Kaiser
0

Rediseñé un poco la respuesta de @kaiser a mis necesidades, pensé en compartirla. Quería más opciones, esas se explican dentro del código y en el ejemplo de uso a continuación.

Código:

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


Ejemplo de uso:

$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
fuente