Variablen aus PHP per JSON in JavaScript übergeben

Es passiert mir recht oft, dass ich in einer Applikation im JavaScript-Layer auf die Werte von Variablen zugreifen muss, die eigentlich nur in PHP existieren. Meist habe ich mir in PHP ein Wörterbuch angelegt, welches Standardbegriffe enthält, die an vereinzelten Stellen in der Applikation verwendet werden. Zum Beispiel werden Fehlermeldungen (“konnte nicht gespeichert werden”, “bitte Feld %s ausfüllen”) in einer einzigen Datei zusammengefasst und zum notwendigen Zeitpunkt abgerufen und angezeigt. Das ermöglicht mir unter anderem später eine Lokalisierung der Applikation.Ich beginne im Normalfall immer mit dem Backend (PHP) und setze erst später den Client-Layer (JavaScript) um. Das meiste JavaScript ist dann eine Verbesserung der Usability. Nicht selten brauche ich an manchen Stellen im JavaScript auch eine Fehlermeldung, die aber nur in PHP existiert.

Der Holzhammer

Die einfachste Methode ist der print() der Variable direkt in das JavaScript:

<?php
$error = 'Es ist ein Fehler aufgetreten';
?><!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript">
    var error = '<?php echo $error; ?>';
    alert(error);
</script>

Die Methode ist effektiv, hat aber gehörige Nachteile:

  1. Ich habe manchmal nicht die Möglichkeit, mit PHP noch im HTML/DOM rumzuwerkeln. Manchmal will ich sie auch gar nicht haben.
  2. Diese Lösung verursacht eine Sprach-Suppe, die nur sehr schwer zu betreuen ist.
  3. Bei grösseren Wörterbüchern kommt man hier ganz schön ans Schwitzen.

Etwas eleganter: Ein bisschen JSON

Die JavaScript-Objekt-Notation, kurz JSON genannt, bietet einen etwas eleganteren Weg, auch grössere Mengen von Variablen von PHP in JavaScript zu transferieren:

<?php
$errors = array(
    'errnosave' => 'Speichern fehlgeschlagen',
    'errunknown' => 'Unbekannter Fehler'
);
?><!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript">
    var errors = '<?php echo json_encode($errors); ?>';
    alert(errors.errunknown);
</script>

Diese Methode hat schon einige Vorteile, aber immer noch ein paar Nachteile:

  1. Ich kann schon einige Daten an JavaScript übertragen. Das JSON-Format ist genial kurz und erzeugt für diese Aufgabe fast keinen Overhead.
  2. Nachteil: Ich muss immer noch direkt ins Dokument schreiben.

Erzeugen einer eigenen dictionary.js

Diese dritte Variante bemüht sich, einfach, aber so abstrakt wie möglich den Variablentransfer durchzuführen. Wir brauchen dafür drei Dateien und – wenn möglich – einen Cron, der regelmässig das Wörterbuch erzeugt.

Datei Nr. 1: Die dictionary.ini

In der dictionary.ini werden die Variablen abgelegt. Eine ini-Datei, weil man sie aus PHP heraus mit der Funktion parse_ini_file() so schön lesen und weiterverarbeiten kann. Eine ini-Datei ist ein einfaches Textdokument und kann so aussehen:

; Statische Meldungen
[authentication]
variable = "Wert"
variable2 = "Wert2"

[errors]
errnosave = "Es wurde nicht gespeichert"
errunknown = "Unbekannter Fehler"

Den Aufbau kennt man z. B. von den Smarty-Config-Dateien.

Datei Nr. 2: Der Parser create_dictionary.php

Ich kann meinen Parser in der Datei create_dictionary.php nun anweisen, die ini-Datei einzulesen und dabei die Sektionen (in den eckigen Klammern) zu berücksichtigen:

<?php
$dictionary = parse_ini_file('dictionary.ini', true);
$errors = $dictionary['errors']; // Sektion 'errors' ermitteln
?> 

Die dritte Datei: dictionary.js

Nun kann ich den Array $errors im JSON-Format in eine Datei namens dictionary.js schreiben:

<?php
$data = sprintf('var DICT = %s', json_encode($errors));
$h = fopen('dictionary.js', 'w');
fwrite($h, $data);
fclose($h);
?>

Diese dictionary.js-Datei kann ich nun ganz normal im <head>-Bereich meiner HTML-Seite einbinden und habe Zugriff auf das DICT-Objekt:

<!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript" src="dictionary.js"></script>
<script type="text/javascript">alert(DICT.errunknown);</script>

Auch diese Methode kommt nicht ganz ohne Nachteile daher:

  1. Ich muss aus PHP in eine dictionary.js schreiben können, manchmal will man das aus Sicherheitsgründen nicht.
  2. Ich will eine solche Schreiboperation nicht bei jedem Request auf die Applikation durchführen. Ich muss das also per Cronjob oder immer in einem Build machen.

Dennoch ist die Variante “schön” genug, um in einzelnen Fällen und gerade in Web-Applikationen die Übermittlung von Variablen von PHP zu JavaScript zur Leichtigkeit werden zu lassen.

Dieser Beitrag wurde unter JavaScript, PHP, Tipps & Tricks, Web-Entwicklung abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

3 Antworten auf Variablen aus PHP per JSON in JavaScript übergeben

  1. Kai Fett sagt:

    Habe ich gerade ein Brett vor dem Kopf? Was spricht denn gegen eine dictionary.js.php, die erstmal per header() vorgibt, Javascript zu sein, und dann das Dictionary ausgibt?Die könnte man dann ja als src=dictionary.js einbinden, Apache mit Content Negotiation würde dann die php-Datei ausführen.Und lokalisieren kann man dann in der dictionary.js.php aufgrund des Accept-Headers, oder direkt ganz vernünftig mit GNU Gettext.

  2. Oliver sagt:

    Hm, natürlich: Ich kann meine JS-Datei durch PHP laufen lassen – wenn ich das will. Mir persönlich gefallen diese Mix-Dateien mit mehreren Sprachen allerdings nicht. Ich mag (normalerweise) auch keinen HTML-PHP-Mix, nutze da lieber Smarty oder andere Template Engines.Theoretisch könnte ich den Apache auch anweisen, die *.js-Dateien durch PHP zu schleusen:<IfModule mod_mime.c>AddType application/x-httpd-php .php .js</IfModule>Das kann aber zu einiger Überlast führen.

  3. Operaiter sagt:

    Hallo Oliver,

    tolle, einfache(!), möglichkeit Arrays von PHP an JS zu übergeben!
    Sehr verständlich formuliert und (wie ich es mag!) einfach heruntergebrochene Codebeispiele!

    BTW: Bin durch Google hier gelandet!
    Weiter so! :)

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>