Solución:
Si está llegando al punto en el que el código de su tema functions.php
está comenzando a abrumarlo. Definitivamente diría que está listo para considerar dividirlo en varios archivos. Tiendo a hacer eso casi como una segunda naturaleza en este momento.
Utilice Incluir archivos en su tema functions.php
Expediente
Creo un subdirectorio llamado “incluye” en mi directorio de temas y segmentar mi código en archivos de inclusión organizados por lo que tiene sentido para mí en ese momento (lo que significa que estoy constantemente refactorizando y moviendo el código a medida que un sitio evoluciona). functions.php
; todo va en los archivos de inclusión; solo mi preferencia.
Solo para darle un ejemplo, aquí está mi instalación de prueba que utilizo para probar mis respuestas a las preguntas aquí en Respuestas de WordPress. Cada vez que contesto una pregunta, guardo el código en caso de que lo necesite nuevamente. Esto no es exactamente lo que harás para un sitio en vivo, pero muestra la mecánica de dividir el código:
<?php
/*
* functions.php
*
*/
require_once( __DIR__ . '/includes/null-meta-compare.php');
require_once( __DIR__ . '/includes/older-examples.php');
require_once( __DIR__ . '/includes/wp-admin-menu-classes.php');
require_once( __DIR__ . '/includes/admin-menu-function-examples.php');
// WA: Adding a Taxonomy Filter to Admin List for a Custom Post Type?
// http://wordpress.stackexchange.com/questions/578/
require_once( __DIR__ . '/includes/cpt-filtering-in-admin.php');
require_once( __DIR__ . '/includes/category-fields.php');
require_once( __DIR__ . '/includes/post-list-shortcode.php');
require_once( __DIR__ . '/includes/car-type-urls.php');
require_once( __DIR__ . '/includes/buffer-all.php');
require_once( __DIR__ . '/includes/get-page-selector.php');
// http://wordpress.stackexchange.com/questions/907/
require_once( __DIR__ . '/includes/top-5-posts-per-category.php');
// http://wordpress.stackexchange.com/questions/951/
require_once( __DIR__ . '/includes/alternate-category-metabox.php');
// http://lists.automattic.com/pipermail/wp-hackers/2010-August/034384.html
require_once( __DIR__ . '/includes/remove-status.php');
// http://wordpress.stackexchange.com/questions/1027/removing-the-your-backup-folder-might-be-visible-to-the-public-message-generate
require_once( __DIR__ . '/includes/301-redirects.php');
O crear complementos
Otra opción es comenzar a agrupar su código por función y crear sus propios complementos. Para mí, empiezo a codificar en el tema functions.php
y para cuando obtengo el código completo, he movido la mayor parte de mi código a complementos.
Sin embargo, NO hay una ganancia de rendimiento significativa de la organización del código PHP
Por otro lado, estructurar sus archivos PHP es 99% sobre la creación de orden y mantenibilidad y 1% sobre el rendimiento, si eso (organizar .js
y .css
archivos llamados por el navegador a través de HTTP es un caso completamente diferente y tiene enormes implicaciones de rendimiento). Pero cómo organiza su código PHP en el servidor prácticamente no importa desde una perspectiva de rendimiento.
Y la organización del código es una preferencia personal
Y por último, pero no menos importante, la organización del código es una preferencia personal. Algunas personas odiarían cómo organizo el código del mismo modo que yo podría odiar cómo lo hacen ellos también. Encuentre algo que le guste y cúmplalo, pero permita que su estrategia evolucione con el tiempo a medida que aprende más y se siente más cómodo con él.
Respuesta tardía
Cómo incluir sus archivos de la manera correcta:
function wpse1403_bootstrap()
{
// Here we load from our includes directory
// This considers parent and child themes as well
locate_template( array( 'inc/foo.class.php' ), true, true );
}
add_action( 'after_setup_theme', 'wpse1403_bootstrap' );
Lo mismo funciona en los complementos también.
Cómo obtener el camino correcto o URi
También eche un vistazo a las funciones de la API del sistema de archivos como:
home_url()
plugin_dir_url()
plugin_dir_path()
admin_url()
get_template_directory()
get_template_directory_uri()
get_stylesheet_directory()
get_stylesheet_directory_uri()
- etc.
Cómo reducir el número de include/require
Si necesitas ir a buscar todos los archivos de un directorio van con
foreach ( glob( 'path/to/folder/*.php' ) as $file )
include $file;
Tenga en cuenta que esto ignora fallas (tal vez sea bueno para uso en producción) / archivos no cargables.
Para modificar este comportamiento, es posible que desee utilizar una configuración diferente durante el desarrollo:
$files = ( defined( 'WP_DEBUG' ) AND WP_DEBUG )
? glob( 'path/to/folder/*.php', GLOB_ERR )
: glob( 'path/to/folder/*.php' )
foreach ( $files as $file )
include $file;
Editar: enfoque OOP / SPL
Como acabo de regresar y vi que esta respuesta está obteniendo más y más votos positivos, pensé que podría mostrar cómo lo estoy haciendo hoy en día, en un mundo PHP 5.3+. El siguiente ejemplo carga todos los archivos de una subcarpeta de temas denominada src/
. Aquí es donde tengo mis bibliotecas que manejan ciertas tareas como menús, imágenes, etc. Ni siquiera tienes que preocuparte por el nombre ya que se cargan todos los archivos. Si tiene otras subcarpetas en este directorio, se ignoran.
los FilesystemIterator
es el PHP 5.3+ supercedor sobre el DirectoryIterator
. Ambos son parte de PHP SPL. Si bien PHP 5.2 hizo posible desactivar la extensión SPL incorporada (menos del 1% de todas las instalaciones lo hicieron), SPL ahora es parte del núcleo de PHP.
<?php
namespace Theme;
$files = new FilesystemIterator( __DIR__.'/src', FilesystemIterator::SKIP_DOTS );
foreach ( $files as $file )
{
/** @noinspection PhpIncludeInspection */
! $files->isDir() and include $files->getRealPath();
}
Anteriormente, aunque todavía era compatible con PHP 5.2.x, usé la siguiente solución: A FilterIterator
en el src/Filters
directorio para recuperar solo archivos (y no punteros de carpetas) y un DirectoryIterator
para hacer el bucle y la carga.
namespace Theme;
use ThemeFiltersIncludesFilter;
$files = new IncludesFilter( new DirectoryIterator( __DIR__.'/src' ) );
foreach ( $files as $file )
{
include_once $files->current()->getRealPath();
}
los FilterIterator
fue tan fácil como eso:
<?php
namespace ThemeFilters;
class IncludesFilter extends FilterIterator
{
public function accept()
{
return
! $this->current()->isDot()
and $this->current()->isFile()
and $this->current()->isReadable();
}
}
Aparte de que PHP 5.2 está muerto / EOL a estas alturas (y 5.3 también), existe el hecho de que hay más código y un archivo más en el juego, por lo que no hay razón para optar por la versión posterior y admitir PHP 5.2.x.
Resumió
EDITAR La forma obviamente correcta es usar namespace
d, preparado para la carga automática de PSR-4 colocando todo en el directorio apropiado que ya está definido a través del espacio de nombres. Entonces solo usa Composer y un composer.json
para administrar sus dependencias y dejar que autoconstruya su autocargador PHP (que importa automáticamente un archivo con solo llamar use <namespace>ClassName
). Ese es el estándar de facto en el mundo PHP, la forma más fácil de hacerlo y aún más pre-automatizada y simplificada por WP Starter.
Me gusta usar una función para los archivos dentro de una carpeta. Este enfoque facilita la adición de nuevas funciones al agregar nuevos archivos. Pero siempre escribo en clase o con espacios de nombres: le doy más control sobre el espacio de nombres de funciones, métodos, etc.
A continuación un pequeño ejemplo; ut también useage con el acuerdo sobre la clase * .php
public function __construct() {
$this->load_classes();
}
/**
* Returns array of features, also
* Scans the plugins subfolder "/classes"
*
* @since 0.1
* @return void
*/
protected function load_classes() {
// load all files with the pattern class-*.php from the directory classes
foreach( glob( dirname( __FILE__ ) . '/classes/class-*.php' ) as $class )
require_once $class;
}
En Temas utilizo a menudo otro escenario. Defino la función del archivo externo en un ID de soporte, vea el ejemplo. Eso es útil si desactivo fácilmente la fuente del archivo externo. Yo uso la función principal de WP require_if_theme_supports()
y solo carga, si el ID de soporte estaba activo. En el siguiente ejemplo, definí esta ID admitida en la línea antes de cargar el archivo.
/**
* Add support for Theme Customizer
*
* @since 09/06/2012
*/
add_theme_support( 'documentation_customizer', array( 'all' ) );
// Include the theme customizer for options of theme options, if theme supported
require_if_theme_supports(
'documentation_customizer',
get_template_directory() . '/inc/theme-customize.php'
);
Puedes ver más de esto en el repositorio de este tema.