PHP Workaround – file_get_contents() ohne allow_url_fopen nutzen
Ich gebe zu, der Titel ist etwas irreführend. Die PHP-Funktion file_get_contents(), die dazu genutzt werden kann Dateien aus dem Internet in einen String zu lesen, um sie weiterzuverarbeiten, funktioniert bei deaktiviertem allow_url_fopen einfach nicht. Daran wird auch dieser Artikel nichts ändern.
Entwickelt man jedoch eine Anwendung/ein Script, das auf möglichst vielen Serverumgebungen funktionieren soll, so wie zum Beispiel ein WordPress-Plugin, so gibt es einen guten Workaround, um Nutzer, auf dessen Webservern allow_url_fopen deaktiviert ist, nicht auszuschließen.
Und genau dieses kleine Snippet möchte ich euch heute zeigen und erklären.
$datei = "http://www.beispiel.de/meine_seite.php";
if (function_exists('curl_version'))
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $datei);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($curl);
curl_close($curl);
}
else if (file_get_contents(__FILE__) && ini_get('allow_url_fopen'))
{
$content = file_get_contents($datei);
}
else
{
echo 'Sie haben weder cURL installiert, noch allow_url_fopen aktiviert. Bitte aktivieren/installieren allow_url_fopen oder Curl!';
}
Zuerst wird überprüft, ob auf dem Server die cURL Erweiterung zur Verfügung steht. Wenn dies der Fall ist, wird die Datei per cURL geladen.
Steht cURL nicht zur Verfügung, so wird überprüft, ob allow_url_fopen aktiviert ist. Ist dies der Fall, wird die Datei per file_get_contents() geladen.
Stehen beide Möglichkeiten nicht zur Verfügung, wird eine Fehlermeldung ausgegeben, was den Endanwender vor etwaigen, für ihn “kryptischen”, Fehlermeldungen bewahren soll.
Falls ihr euch fragt, warum ich cURL den Vorzug gegenüber file_get_contents() gebe, so liegt das daran, dass ich die Erfahrung gemacht habe, dass cURL, bezogen auf diesen Anwendungsfall, etwas performanter ist.
Abschließend lässt sich sagen, dass ihr bei Verwendung der hier aufgezeigten Methode, die Chance darauf, dass euer Script bei möglichst vielen Usern läuft, verdoppeln könnt. Das ist doch schon mal was, oder?
Was haltet ihr von meinem Snippet? Würdet ihr es genauso umsetzen oder haltet ihr davon eher nichts? Wie geht ihr mit der “Problematik” allow_url_fopen um?
Viele Grüße,
Raffi
Einfacher Syntaxhighlighter in PHP
In folgendem Artikel möchte ich euch zeigen, wie ihr in wenigen Zeilen euren eigenen Syntaxhighlighter schreiben könnt. Mit Hilfe des folgenden PHP Snippets könnt ihr ohne Weiteres Quellcode, gut lesbar, auf eurer Homepage anzeigen lassen.
Das Ganze geht einfacher als ihr denkt. Die wesentliche Arbeit nimmt uns die interne PHP-Funktion highlight_file ab. Diese Funktion liest eine Datei ein und formatiert den Quelltext farbig. Wir müssen dann lediglich noch die Zeilen der Datei zählen und die Zeilennummern, sowie den vorformatierten Text in einem ansehnlichen Format ausgeben.
Da das Snippet nicht all zu lang ist, denke ich, dass die Kommentare im Snippet selber ausreichen. Solltet ihr dennoch Fragen haben, schreibt einfach einen Kommentar.
<?php
function highlight_quellcode($datei)
{
//Zeilen der Quellcode-Datei zählen
$anzahl_zeilen = count(file($datei));
//Liste mit Ziffern aller Zeilennummern erstellen
$liste_zeilennummern = range(1, $anzahl_zeilen);
//Zeilennummern als String formatieren. Hinter jede
//Zeilennummer einen Zeilenumbruch in HTML (<br />)
$zeilen = implode($liste_zeilennummern, '<br />');
//Quellcode einlesen und formatieren
//'true' legt Quellcode in Variable ab
//'false' würde Quellcode an Ort und Stelle ausgeben
$quellcode = highlight_file($datei, true);
//HTML-Ausgabe. CSS Code zur Formatierung der Tabelle
//Zeilennummern und Quellcode werden in jeweils einer
//Tabellenspalte ausgegeben
echo '
<html>
<head>
<style type="text/css">
.codewrapper {
margin: 5px;
border: 1px dashed dimgray;}
.id {
text-align: right;
color: dimgray;
font: 10pt \'Courier New\';
padding-right: 5px;
border-right: 1px dashed dimgray;}
.code {
padding-left: 5px;}
</style>
</head>
<body>
<table class="codewrapper">
<tr>
<td class="id">'.$zeilen.'</td>
<td class="code">'.$quellcode.'</td>
</tr>
</table>
</body>
</html>';
}
//Aufrufen der Syntaxhighlightfunktion. Als Einzulesende Datei
//wird diese Datei selbst ausgegeben.
highlight_quellcode("short.php");
?>
Ich habe das Snippet in einer Datei namens short.php abgespeichgert. Im Snippet ruft sich das PHP-Script selbst auf und gibt somit seinen eigenen Quelltext aus. Eine Demo könnt ihr euch hier anschauen.
Viele Grüße,
Raffi
Gzip-Komprimierung in WordPress aktivieren
Bisher habe ich mir über die Ladezeiten meiner Seite noch keine großen Gedanken gemacht. Bisher war ich auch der Überzeugung, dass WordPress von sich aus die Gzip-Komprimierung nutzen würde. Wie gesagt, bisher. Heute musste ich feststellen, dass WordPress genau jenes eben nicht tut.
Für all jene, die nichts mit Gzip anfangen können, noch eine schnelle Erklärung. Gzip ist ein Kompressionsverfahren, um die Größe einer Datei zu minimieren. Am populärsten ist es heutzutage auf Unix-Systemen. Verwendung im Webseitenbereich findet es, wenn es darum geht, die vom Server an den Nutzer zu sendenden Daten zu verkleinern. So wird der beim Aufruf entstehende Traffic vermindert, was gleichzeitig eine Verringerung der Ladezeit der Webseite mit sich bringt.
Langer Rede, kurzer Sinn. Wie bekomme ich denn nun die Gzip-Komprimierung in WordPress aktiviert? Eine Option in der Einstellungsseite von WordPress gibt es dafür leider nicht. Es bleiben also zwei Möglichkeiten. Zum einen die Nutzung eines Plugins wie z.B. GZippy oder zum anderen die manuelle Aktivierung. Zweites bevorzuge ich persönlich, da ich gegebenenfalls nicht auf die Aktualisierung eines Plugins warten muss und der Einbau in Falle der GZip-Komprimierung wirklich schnell vonstatten geht.
Zum manuellen Aktivieren müsst ihr in der WordPress Sidebar auf den Menüpunkt Editor im Gruppenmenü Design klicken. Öffnet nun die Datei functions.php und fügt ganz oben unter dem einleitenden PHP Tag folgenden Befehl ein.
ob_start("ob_gzhandler");
Das war’s auch schon. Von nun an wird euer Blog per Gzip ausgeliefert. (Natürlich nur solange der Browser des Besuchers dies auch unterstützt.)
Viele Grüße,
Raffi
Zufallszahlen in PHP mit rand() oder mt_rand() erstellen?
Nachdem mich René in den Kommentaren zu meinem Artikel über die Generierung von unterschiedlichen Zufallszahlen in PHP darauf hingewiesen hat, dass es sinnvoller sei, die PHP-Funktion mt_rand() anstelle von rand() zur Erstellung von Zufallszahlen zu nutzen, habe ich beschlossen ein wenig nachzuforschen und einen Artikel darüber zu schreiben. Aber was ist mt_rand() eigentlich?
Mit mt_rand() kann man genauso wie mit rand() Zufallszahlen generieren. Der Aufruf der Funktion erfolgt genauso, wie mit der normalen rand() Funktion. Zusätzlich heißt es in der PHP-Doku, würde mt_rand() Zufallszahlen bis zu 4-mal schneller generieren und diese auch wesentlich willkürlicher Auswählen. Kurz: Die von rand() erstellten Zufallszahlen seien nicht wirklich zufällig.
Mir war die ganze “Problematik” bis dato nicht bekannt und schon nach kurzem googeln musste ich feststellen, dass René mit seiner Meinung nicht alleine ist. Allerdings muss man auch dazu sagen, dass die meisten Beiträge, die beklagen, dass rand() nicht sauber arbeitet schon “etwas älter” sind.
Oft zitiert zur Unterstützung der Argumente ist ein Artikel von Dog.net Development, der die angeblichen Nachteile von rand() im Gegenteil zu mt_rand() visualisiert. Die oben schon genannte Behauptung, rand() würde keine korrekten Zufallszahlen erstellen, belegt der Autor mit einem kurzen aber effektiven PHP-Script. Ich habe euch zur Anschauung mal eben ein ähnliches Script geschrieben.
<?php
header("Content-type: image/png");
$img = imagecreatetruecolor(256, 256)
or die("Fehler beim Erstellen der Grafik!");
$farbeWeiss = imagecolorallocate($img, 255, 255, 255);
for ($x=0; $x<256; $x++)
{
for ($y=0; $y<256; $y++)
{
if (mt_rand(0,1) === 1)
{
imagesetpixel($img, $x, $y, $farbeWeiss);
}
}
}
imagepng($img);
imagedestroy($img);
?>
Das Script erstellt eine 256×256 Pixel große Grafik. Wobei für jeden Pixel eine Zufallszahl zwischen 0 und 1 generiert wird. Bei einer 1 wird der Pixel weiß, bei einer 0 bleibt der Pixel schwarz.
dog.net führte diese Funktion einmal mit mt_rand() und einmal mit rand() aus und erhielt folgende zwei Grafiken (zum Vergrößern bitte anklicken):
Hier wird ersichtlich was viele an der rand() Funktion anprangern. Auf dem Bild, das mit der rand() Funktion erstellt wurde ist ganz klar ein Muster erkennbar. Das hieße, dass die Zufallszahlen von rand() nicht wirklich zufällig sind. Aber…
..an diesem Punkt möchte ich meine Beobachtungen entgegenstellen. Ich sagte vorhin schon, dass die meisten anprangernden Artikel schon etwas älter seien. Es ist also genug Zeit vergangen die rand() Funktion zu verbessern. Deshalb habe ich es mir nicht nehmen lassen, das Script von dog.net nachzubauen und selber mal zu schauen, was passiert. Und siehe da…
(mit rand() erstelltes Bild)
(mit mt_rand() erstelltes Bild)
…wie durch ein Wunder scheinen beide Funktionen, rand() sowie mt_rand() hervorragend zu funktionieren.
Nun bleibt nur noch zu überprüfen, ob mt_rand() denn wenigstens schneller ist als rand(), wie es behauptet wurde. Hierzu habe ich ein weiteres kleines Script geschrieben.
<?php
$start = microtime(true);
for ($i=0; $i<1000000; $i++)
{
$zzahl = mt_rand(0,1);
}
$ende = microtime(true);
$zeitmtrand= $ende - $start;
$start = microtime(true);
for ($i=0; $i<1000000; $i++)
{
$zzahl = rand(0,1);
}
$ende = microtime(true);
$zeitrand= $ende - $start;
echo "Laufzeit mt_rand(): ".$zeitmtrand." Sekunden!";
echo "Laufzeit rand(): ".$zeitrand." Sekunden!";
?>
Und an dieser Stelle, folgt dann auch gleich die zweite Überraschung. Das Script lieferte folgendes Ergebnis zurück:
Laufzeit mt_rand(): 1.033802986145 Sekunden! Laufzeit rand(): 1.1012179851532 Sekunden!
Nach der vierfachen Geschwindigkeit sieht das für mich aber nicht aus. In meinen Augen gibt es von daher keinen Grund, von der rand() Funktion auf die mt_rand() Funktion umzusteigen, denn auch der Maximalwert für die größte zu erstellende Zahl mit rand(), der standardmäßig kleiner eingestellt ist, kann in der Größe angehoben werden, sofern dies nötig ist.
Wie seht ihr das? Konnte ich euch überzeugen?
Viele Grüße,
Raffi






