2009-07-14 4 views
3

Hackt Drupal (und/oder rennt) Hooks, die nichts mit dem Inhalt zu tun haben, der vom aktuellen Benutzer geladen wird?Parst Drupal Hooks, die nicht verwendet werden?

Zum Beispiel sage ich hatte ein Modul foo installiert und aktiv mit dem folgenden Haken:

<?php 
// .. stuff ...  
function foo_menu() { 
     $items = array(); 
     $items['foo/show'] = array(
     'title' => t('Foo!'), 
     'page callback' => 'foo_display_all', 
     'description' => 'All our foo are belong to you', 
     'type' => MENU_NORMAL_ITEM, 
    ); 
     return $items; 
    } 

    function foo_display_all() { 
    // About 100 lines of code 
    } 
// ... stuff ... 

würde Drupal Parse für Seiten (und damit die Ladezeit bewirken), die nicht in foo_menu aufgelistet ist? Anders gesagt, würde die Länge und Komplexität von foo_display_all beeinflussen, wie www.example.com/bar lädt?

Bei dem Risiko, hier zwei verschiedene Fragen zu haben, würde ich sagen, ich wäre dankbar für eine Erklärung (oder einen Link zu einer Erklärung), wie und warum Drupal nicht analysiert, sondern eine Ja/Nein-Antwort.

Antwort

6

hook_menu wird verwendet, um drupal darüber zu informieren, was bei bestimmten URLs zu tun ist, damit das Ergebnis zwischengespeichert wird.

Drupal führt nur den Inhalt der Hooks selbst aus und nicht den gesamten Inhalt der Datei, in der sie sich befinden. Wenn also das Hook-Menü im obigen Beispiel aufgerufen wird, wird die Funktion foo_menu() ausgeführt. Sie einen Blick auf die Introtext nehmen können an der Hooks API

Edit: Damit PHP die Funktion auszuführen, muss es um die Datei schließen, wo es sich befindet. Wenn Drupal also einen Hook ausführen möchte, müsste PHP den Code in dieser Datei analysieren. So ist PHP konzipiert, also haben Sie nicht viel mit Drupal zu tun.

Dies ist auch der Grund, warum eine Menge von Modulen viele inc-Dateien erstellen, um die Menge an Code zu begrenzen, der beim Hooks analysiert werden muss.

+0

Danke. Aber ich fragte mich eher, ob die Dateien gelesen und geparst werden würden - ich bin dankbar, dass Drupal schlau genug ist, unbenutzte Funktionen nicht wirklich auszuführen, aber ich weiß nicht, ob es sie liest/analysiert und dann ignoriert, oder wenn es sie überhaupt nicht liest, außer sie werden gebraucht. Vielleicht haben Sie das gemeint? – anschauung

+1

Ich denke es ist, wenn Sie nicht möchten, dass es eine inc-Datei verwendet. –

+0

Danke für die Erklärung. Ihre Antwort zur Verwendung von INC-Dateien widerspricht etwas Craigs Antwort unten, aber ich werde eine neue Frage stellen, um das zu lösen. – anschauung

3

Drupal enthält alle MODULE.module-Dateien (und alles, was sie enthalten) für jedes Modul für jede Anfrage.

Die einzige Möglichkeit für Drupal core, zu wissen, ob das Modul irgendwelche Haken hat, die es aufrufen muss, ist das Laden der Datei. Dies wird Zeit und Gedächtnis brauchen.

+0

Danke für die Erklärung. Ihr Kommentar zur Verwendung von INC-Dateien widerspricht @ Googletorps Antwort etwas, aber ich nehme an, dass eine neue Frage der beste Weg ist, dies zu lösen. – anschauung

+0

Wenn die .module-Datei die Include-Anweisung in einer Funktion enthält, wird die enthaltene Datei nur gelesen, wenn die Funktion aufgerufen wird. Wenn das Include global ist, wird die Include-Datei immer gelesen. – Craig

3

Firs aller, ich bin kein erfahrener Drupal Entwickler, zweitens ist es nicht eine schöne Umsetzung ist und drittens, ich habe nicht versucht, aber sollte

function foo_display_all() { 
    include("foo_display_all_body.php"); 
} 

Auf diese Weise werden die Haken analysiert arbeiten werden jedes Mal + eine zusätzliche PHP-Datei mit dem Funktionskörper.

Viertens ist es Mikrooptimierung. Es könnte besser sein, es zu vermeiden, wenn es nicht absolut notwendig ist, da die zusätzliche Komplexität (und die gelesene + 1-Datei) auf lange Sicht mehr für Sie kosten kann als das Parsen.

Wenn Sie die PHP-Code Parsen schneller machen möchten, sollten Sie einen Opcode Cache

4

Ja verwenden. Wie andere bereits angemerkt haben, ist es die einzige Möglichkeit, das Problem zu lösen, wenn man Dinge in Dateien aufteilt, die bedingt geladen sind. Ab Drupal 6 wurde es möglich, theme_whatever() - Funktionen sowie hook_menu() -Rückrufe in separate Include-Dateien zu verschieben. Drupal lädt sie automatisch, wenn sie benötigt werden, ohne dass Sie explizit require_once() jonglieren. Weitere Informationen finden Sie in der Dokumentation hook_menu() und hook_theme().

Es ist auch wichtig zu beachten, dass, wenn Sie einen Opcode Cache wie APC laufen lassen, Splitting Dinge in einen Haufen von bedingten enthält, ist eigentlich schlimmen - APC kann alle von der Analyse und Erstellung von PHP-Quelle tun in einmal gehen und zwischen Anfragen bestehen. Die bedingungslose Aufteilung der Dinge führt dazu, dass mehrere diskrete "Codebasen" kompiliert werden, je nachdem, was getan wird.

In der zur Zeit in Entwicklung befindlichen Drupal 7 wurde eine allgemeine Code registry hinzugefügt, die es ermöglicht, jede Hook-Implementierung in eine separate Include-Datei aufzuteilen. Der Overhead der Verwaltung dieses internen Caches mit Funktionen und .inc-Speicherorten und deren laufendem Laden verschlingt jedoch die Leistungsgewinne der kleineren zu analysierenden Codebasis. Die einzige wirkliche Belohnung ist die verringerte Speicherauslastung für Shared-Hosts mit engen Speichergrenzen von 12-16 Megabyte. Es ist unklar, ob die Änderung bis zur endgültigen Veröffentlichung von Drupal 7 angesichts der Kompromisse überleben wird.

Das Ergebnis: in Drupal 6, spaltet die Menü Callbacks, die benutzerdefinierte Seiten in eine separate INC-Datei erstellen, und es wird nur geladen, wenn diese Seiten erstellt werden. Machen Sie dasselbe mit allen Themenfunktionen. Und Wenn Sie einen Opcode-Cache wie APC verwenden, denken Sie daran, dass Ihre separaten INC-Dateien nur für organisatorische Zwecke gut sind - sie werden Ihnen keine Leistungssteigerung geben.

+0

Große Antwort - danke für die ausführliche Erklärung! – anschauung

0

APC scheint jetzt sowohl INC-Dateien als auch PHP zu cachen, was einen großen Leistungsschub bringt.