Template laden: include() vs. eval()

Über die PHP Template Engine Smarty hinaus gibt es zahleiche Möglichkeiten, die Darstellungsschicht einer Webanwendung mittels PHP zu laden. Neben der Strukturierung bzw. Architektur der Anwendung nach dem Model View Controller-Modell spielt natürlich die Performanz eine gewichtige Rolle bei der Entscheidung für oder gegen die Verwendung bestimmter Frameworks oder eine bestimmte Vorgehensweise.

Nachfolgend werden die sehr einfachen Möglichkeiten, HTML-Dateien mit gerinfügigem dynamisch generiertem Inhalt mittels der PHP-Funktionen  include()  bzw.  eval()  zu laden, hinsichtlich ihrer Performanz verglichen. Der Vorteil von  eval()  ist in der strikteren Trennung zwischen Darstellungs- und Anwendungsschicht zu sehen. So müssen sich Webdesigner oder Webmaster nicht unnötig mit PHP-Code in den HTML-Templates auseinandersetzen. Mit  include()  ist mehr Flexibilität durch die weniger stringenten Schichtgrenzen gegeben. Doch welche Variante ist performanter?

Template laden mit eval()

Logischerweise werden zwei Dateien für den Benchmark-Test benötigt. Dies ist zum einen die PHP-Datei, die das Template lädt, und die das Template repräsentierende HTML-Datei.

test.php

<?php
$var = 'abc';
for ($i = 0;$i < 1000;$i++) {
    $tmp = file_get_contents('./template.html');
    eval("\$tmp=\"" . str_replace('"', '\"', $tmp) . "\";");
    echo $tmp;
}
?>

Erläuterung:
In einer  for -Schleife wird 10.000mal der Inhalt einer HTML-Datei eingelesen, evaluiert und ausgegeben.

template.html

  <html> 
     <head> 
         <title></title> 
     </head> 
     <body> 
         <p>{$var}</p> 
     </body> 
 </html>

Erläuterung:
Es handelt sich um das Grundgerüst einer HTML-Webseite, die eine Variable namens  $var  enthält.

Template laden mit include()

Auch bei der  include() -Variante werden zwei Dateien benötigt:

test.php

<?php
$var = 'abc';
for ($i = 0;$i < 1000;$i++) {
    include ('./template.html');
}
?>

Erläuterung:
Innerhalb der schon in der  eval() -Variante verwendeten  for -Schleife wird 10.000mal die Template-Datei includiert.

template.html

  <html> 
     <head> 
         <title></title> 
     </head> 
     <body> 
         <p><?php echo $var; ?></p> 
     </body> 
 </html>

Erläuterung:
Im Gegensatz zur  eval() -Variante wird der Inhalt der Template-Datei nicht evaluiert, muss also die  echo -Anweisung für die Ausgabe des Inhalts der Variablen  $var  enthalten.

Ergebnis

Requests per second (RPS)Time per Request (TPR)Vergleich
Template laden mit eval()36.27 [#/sec] (mean)27.569 [ms] (mean)
88.4%
46.9%
Template laden mit include()19.25 [#/sec] (mean)51.949 [ms] (mean)

Die Variante, bei der die Template-Datei mittels  eval()  eingebunden wird, ist annähernd doppelt so schnell wie die  include() -Variante.

Fazit

Nicht berücksichtigt wurde der Speicherverbrauch und mögliche Caching-Verhalten von  file_get_contents()  bzw.  eval() . Zudem hat die in den Benchmarks verwendete HTML-Datei einen unrealistisch geringen Umfang. Das Ergebnis zeigt jedoch, dass man entgegen der weit verbreiteten Ansicht beim Einsatz von  include()  kein schlechtes Gewissen haben muss und andere Argumente als die Performanz gewichtiger sind.

 

Anmerkung:
Die Tests wurden mit dem Apache HTTP server benchmarking tool ab auf einem im Februar 2017 nicht mehr dem Stand der Technik entsprechenden Server durchgeführt. Die RPS und TPR der getesteten PHP-Scripte sollten auf einem im Produktiv-Einsatz befindlichen Webserver deutlich besser sein.