Organisieren von Code in den functionen Ihres WordPress Theme.php Datei?

Je mehr Anpassung ich an WordPress mache, desto mehr denke ich darüber nach, ob ich diese Datei organisieren oder aufteilen sollte.

Genauer gesagt, wenn ich eine Reihe von benutzerdefinierten functionen habe, die nur für den Admin-Bereich gelten und andere, die nur für meine öffentliche Website gelten, gibt es irgendeinen Grund, möglicherweise alle Admin-functionen in ihre eigene Datei aufzunehmen oder sie zusammen zu gruppieren?

Würden sie in einzelne Dateien aufgeteilt oder gruppiert werden, könnte dies eine WordPress-Website beschleunigen oder überspringt WordPress / PHP automatisch functionen mit einem is_admin-Code-Präfix?

Was ist der beste Weg, mit einer großen functionsdatei umzugehen (meine ist 1370 Zeilen lang).

Solutions Collecting From Web of "Organisieren von Code in den functionen Ihres WordPress Theme.php Datei?"

Wenn Sie zu dem Punkt kommen, an dem der Code in der functions.php Ihres Themas beginnt, Sie zu überwältigen, würde ich definitiv sagen, dass Sie bereit sind, darüber nachzudenken, ihn in mehrere Dateien aufzuteilen. Ich tendiere dazu, dies fast schon an zweiter Stelle zu tun.

Verwende Include-Dateien in der functions.php Datei deines Themes

Ich erstelle ein Unterverzeichnis namens “includes” unter meinem Themenverzeichnis und segmentiere meinen Code in Include-Dateien, die von dem organisiert werden, was für mich zu der Zeit Sinn macht (was bedeutet, dass ich Code ständig neu entwickle und umstelle.) Ich auch selten Legen Sie einen echten Code in functions.php ; alles geht in die Include-Dateien; nur meine Vorliebe.

Nur um Ihnen ein Beispiel zu geben, hier ist meine Test-Installation, die ich verwende, um meine Antworten auf Fragen hier auf WordPress-Antworten zu testen. Jedes Mal, wenn ich eine Frage beantworte, behalte ich den Code für den Fall, dass ich ihn wieder brauche. Dies ist nicht genau das, was Sie für eine Live-Site tun, aber es zeigt die Mechanismen der Aufteilung des Codes:

 < ?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'); 

Oder Erstelle Plugins

Eine andere Möglichkeit, den Code nach functionen zu gruppieren und eigene Plugins zu erstellen. Für mich fange ich an, in der functions.php Datei des Themas zu programmieren, und bis ich den Code ausgearbeitet habe, habe ich den Großteil meines Codes in Plugins verschoben.

Jedoch KEINE signifikante performancessteigerung durch PHP-Code-Organisation

Auf der anderen Seite ist die Strukturierung Ihrer PHP-Dateien 99% über die Schaffung von Ordnung und Wartbarkeit und 1% über performance, wenn dies (Organisieren von .js und .css Dateien vom Browser über HTTP aufgerufen ist ein ganz anderer Fall und hat enorme Auswirkungen auf die performance.) Aber wie Sie Ihren PHP-Code auf dem Server organisieren, ist aus performancesperspektive ziemlich egal.

Und Code-Organisation ist persönliche Präferenz

Und nicht zuletzt ist die Code-Organisation eine persönliche Präferenz. Manche Leute würden es hassen, wie ich den Code organisiere, genauso wie ich es hasse, wie sie das tun. Finden Sie etwas, das Ihnen gefällt und bleiben Sie dabei, aber erlauben Sie Ihrer Strategie, sich im Laufe der Zeit zu entwickeln, während Sie mehr lernen und sich damit wohler fühlen.

Späte Antwort

Wie Sie Ihre Dateien richtig einbinden:

 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' ); 

Das Gleiche funktioniert auch in Plugins.

Wie man den richtigen Weg oder URi bekommt

Sehen Sie sich auch API-functionen für das Dateisystem an:

  • 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.

Wie man die Anzahl von include/require reduziert

Wenn Sie alle Dateien aus einem Verzeichnis holen müssen, gehen Sie mit

 foreach ( glob( 'path/to/folder/*.php' ) as $file ) include $file; 

Beachten Sie, dass dies Fehler ignoriert (möglicherweise gut für die Produktion) / nicht ladbare Dateien.

Um dieses Verhalten zu ändern, möchten Sie möglicherweise während der Entwicklung eine andere Konfiguration verwenden:

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

Bearbeiten: OOP / SPL-Ansatz

Als ich gerade zurückkam und sah, dass diese Antwort immer mehr aufwertete, dachte ich, ich könnte zeigen, wie ich es heute mache – in einer PHP 5.3 + Welt. Im folgenden Beispiel werden alle Dateien aus einem Themes-Unterordner namens src/ . Dies ist, wo ich meine Bibliotheken habe, die bestimmte Aufgaben wie Menüs, Bilder usw. behandeln. Sie müssen sich nicht einmal um den Namen kümmern, da jede einzelne Datei geladen wird. Wenn Sie in diesem Verzeichnis andere Unterordner haben, werden diese ignoriert.

Der \FilesystemIterator ist der PHP 5.3+ Supercedor über den \DirectoryIterator . Beide sind Teil des PHP SPL. Während PHP 5.2 es ermöglichte, die eingebaute SPL-Erweiterung auszuschalten (weniger als 1% aller Installationen taten das), ist die SPL nun Teil des PHP-cores.

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

Zuvor, während ich PHP 5.2.x noch unterstützte, verwendete ich die folgende Lösung: Ein \FilterIterator im Verzeichnis src/Filters um nur Dateien (und nicht Punktzeiger von Ordnern) und einen \DirectoryIterator zum Loopen und Laden zu erhalten.

 namespace Theme; use Theme\Filters\IncludesFilter; $files = new IncludesFilter( new \DirectoryIterator( __DIR__.'/src' ) ); foreach ( $files as $file ) { include_once $files->current()->getRealPath(); } 

Der \FilterIterator war so einfach:

 < ?php namespace Theme\Filters; class IncludesFilter extends \FilterIterator { public function accept() { return ! $this->current()->isDot() and $this->current()->isFile() and $this->current()->isReadable(); } } 

Abgesehen davon, dass PHP 5.2 mittlerweile tot ist / EOL (und auch 5.3), gibt es die Tatsache, dass es mehr Code und eine weitere Datei im Spiel gibt, also gibt es keinen Grund, mit dem späteren zu gehen und PHP 5.2.x zu unterstützen.

Zusammengefasst

Ein noch ausführlicherer Artikel findet sich hier auf WPKrauts .

EDIT Der offensichtlich korrekte Weg ist die Verwendung von namespace d-Code, der für das Autoloading von PSR-4 vorbereitet ist, indem alles in das entsprechende Verzeichnis geschrieben wird, das bereits über den Namespace definiert ist. Verwenden Sie dann Composer und composer.json , um Ihre Abhängigkeiten zu verwalten und automatisch Ihren PHP-Autoloader erstellen zu lassen (der automatisch eine Datei importiert, indem er einfach use \\ClassName ). Das ist der De-facto-Standard in der PHP-Welt, der einfachste Weg zu gehen und noch mehr automatisiert und vereinfacht von WP Starter .

in Bezug auf die Aufschlüsselung verwende ich in meiner Boiler-Platte eine benutzerdefinierte function, um nach einem Ordner namens functions im theme-Verzeichnis zu suchen, wenn es nicht dort ist, erstellt es es. Dann wird ein Array aller .php-Dateien erstellt, die es in diesem Ordner findet (falls vorhanden), und es wird ein include () ausgeführt. auf jedem von ihnen.

Auf diese Weise muss ich jedes Mal, wenn ich neue functionen schreiben muss, eine PHP-Datei zum Ordner functions hinzufügen und muss mich nicht darum kümmern, sie in die Site zu schreiben.

 < ?php /* FUNCTIONS for automatically including php documents from the functions folder. */ //if running on php4, make a scandir functions if (!function_exists('scandir')) { function scandir($directory, $sorting_order = 0) { $dh = opendir($directory); while (false !== ($filename = readdir($dh))) { $files[] = $filename; } if ($sorting_order == 0) { sort($files); } else { rsort($files); } return ($files); } } /* * this function returns the path to the funtions folder. * If the folder does not exist, it creates it. */ function get_function_directory_extension($template_url = FALSE) { //get template url if not passed if (!$template_url)$template_url = get_bloginfo('template_directory'); //replace slashes with dashes for explode $template_url_no_slash = str_replace('/', '.', $template_url); //create array from URL $template_url_array = explode('.', $template_url_no_slash); //--splice array //Calculate offset(we only need the last three levels) //We need to do this to get the proper directory, not the one passed by the server, as scandir doesn't work when aliases get involved. $offset = count($template_url_array) - 3; //splice array, only keeping back to the root WP install folder (where wp-config.php lives, where the front end runs from) $template_url_array = array_splice($template_url_array, $offset, 3); //put back togther as string $template_url_return_string = implode('/', $template_url_array); fb::log($template_url_return_string, 'Template'); //firephp //creates current working directory with template extention and functions directory //if admin, change out of admin folder before storing working dir, then change back again. if (is_admin()) { $admin_directory = getcwd(); chdir(".."); $current_working_directory = getcwd(); chdir($admin_directory); } else { $current_working_directory = getcwd(); } fb::log($current_working_directory, 'Directory'); //firephp //alternate method is chdir method doesn't work on your server (some windows servers might not like it) //if (is_admin()) $current_working_directory = str_replace('/wp-admin','',$current_working_directory); $function_folder = $current_working_directory . '/' . $template_url_return_string . '/functions'; if (!is_dir($function_folder)) mkdir($function_folder); //make folder, if it doesn't already exist (lazy, but useful....ish) //return path return $function_folder; } //removed array elements that do not have extension .php function only_php_files($scan_dir_list = false) { if (!$scan_dir_list || !is_array($scan_dir_list)) return false; //if element not given, or not array, return out of function. foreach ($scan_dir_list as $key => $value) { if (!strpos($value, '.php')) { unset($scan_dir_list[$key]); } } return $scan_dir_list; } //runs the functions to create function folder, select it, //scan it, filter only PHP docs then include them in functions add_action('wp_head', fetch_php_docs_from_functions_folder(), 1); function fetch_php_docs_from_functions_folder() { //get function directory $functions_dir = get_function_directory_extension(); //scan directory, and strip non-php docs $all_php_docs = only_php_files(scandir($functions_dir)); //include php docs if (is_array($all_php_docs)) { foreach ($all_php_docs as $include) { include($functions_dir . '/' . $include); } } } 

Ich verwende gerne eine function für die Dateien in einem Ordner. Dieser Ansatz erleichtert das Hinzufügen neuer functionen beim Hinzufügen neuer Dateien. Aber ich schreibe immer in class oder mit Namespaces – gebe mehr Kontrolle über den Namespace von functionen, Methoden etc.

Unten ein kleines Beispiel; ut auch mit der Vereinbarung über die class * .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; } 

In Themes verwende ich oft ein anderes Szenario. Ich definiere die function der externen Datei in einer Support-ID, siehe das Beispiel. Das ist nützlich, wenn ich die Datei der externen Datei einfach deaktivieren möchte. Ich verwende die WP-corefunktion require_if_theme_supports() und lädt nur, wenn die Support-ID aktiv war. Im folgenden Beispiel habe ich diese unterstützte ID in der Zeile vor dem Laden der Datei deaktiviert.

  /** * 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' ); 

Sie können mehr davon im Repo dieses Themas sehen .

Ich verwalte eine Website mit ungefähr 50 eindeutigen benutzerdefinierten Seitentypen in verschiedenen Sprachen über eine Netzwerkinstallation. Zusammen mit einer TON von Plugins.

Wir waren gezwungen, alles irgendwann aufzuteilen. Eine functionsdatei mit 20-30k Zeilen Code ist überhaupt nicht lustig.

Wir haben uns entschieden, den Code komplett zu refactorisieren, um die Codebasis besser zu verwalten. Die Standard-Wordpress-Themestruktur ist gut für kleine Sites, aber nicht für größere Sites.

Unsere neue functions.php enthält nur das, was notwendig ist, um die Seite zu starten, aber nichts, was zu einer bestimmten Seite gehört.

Das Design des Themas, das wir jetzt verwenden, ähnelt dem MCV-Entwurfsmuster, jedoch in einem prozeduralen Codierungsstil.

Zum Beispiel unsere Mitgliederseite:

page-member.php . Verantwortlich für die Initialisierung der Seite. Aufruf der korrekten Ajax-functionen oder ähnlichem. Könnte dem Controller-Teil im MCV-Stil entsprechen.

functionen-Mitglied.php . Enthält alle functionen auf dieser Seite. Dies ist auch in mehreren anderen Seiten enthalten, die functionen für unsere Mitglieder benötigen.

Inhalt-Mitglied.php . Bereitet die Daten auf HTML vor Entspricht dem Modell in MCV.

Layout-Mitglied.php . Der HTML-Teil.

Nachdem wir diese Änderungen vorgenommen haben, ist die Entwicklungszeit um 50% gesunken und der Produkteigner hat Schwierigkeiten, uns neue Aufgaben zu geben. 🙂

Von untergeordneten Themen functions.php file:

  require_once( get_stylesheet_directory() . '/inc/custom.php' ); 

In der functions.php wäre ein eleganterer Weg, eine benötigte Datei aufzurufen:

require_once locate_template (‘/ inc / functions / shortcodes.php’);