PHP-Daten in JavaScript einschleusen

DIY – Jsonifice

Der in meinen Augen größte Nachteil an wp_localize_script ist der, dass diese Funktion nicht json_encode() sondern ein foreach verwendet. Dadurch ist es unmöglich multidimensionale (verschachtelte) Arrays oder gar Objekte von PHP an JavaScript zu übergeben. Wie aber hoffentlich im laufe dieses Artikels klar wurde, ist es gar nicht so kompliziert sich seine eigene Funktion zu schreiben die deutlich mehr kann.

class Jsonifice
{
	public $function_todo;
	public $object_name;
	public $output;
	public $json_object;

	public function __construct( $object_name = false, $data = false, $callback = false ){

		if( !$object_name || empty( $data ) )
			return false;

		$this->object_name = $object_name;
		$this->function_todo = $callback;

		if( $this->function_todo  ){
			array_walk( $data, array( $this, 'functionTodo' ) );
		}

		$this->json_object = json_encode( $data );

		// cleanup
		unset( $object_name, $data, $callback );
	}

	private function functionTodo( &$var, $key ){

			$call = '';	

			// typecast
			if( is_object( $var ) ){
				$var = (array) $var;
			}

			if( is_array( $var ) ){
				array_walk( $var, array( $this, 'functionTodo' ) );
			} else {
				$call = $this->function_todo;
				$var = $call( $var );
			}
	}

	public function getJson( $out = false ){

		$this->output  = "<script type='text/javascript'>\n";
		$this->output .= "/* <![CDATA[ */\n";
		$this->output .= "var " . $this->object_name . " =" . $this->json_object . "\n";
		$this->output .= "/* ]]> */\n";
		$this->output .= "</script>\n";

		if( $out)
			echo $this->output;
		else
			return $this->output;
	}

	public function getRawjson( $out = false ){
		if( $out)
			echo $this->json_object;
		else
			return $this->json_object;
	}
}

Dies ist meine kleine Klasse mit der ich die ganze Arbeit recht komfortabel erledige (hier aus Platzgründen ohne jegliche Komentare. Die Downloadversion ist natürlich mit entsprechenden Kommentaren versehen). Diese Klasse hat zwei bis drei Vorteile gegenüber wp_localize_script. Zum einen ist es unerheblich ob man ein Array oder ein Objekt übergibt. wp_localize_script verarbeitet lediglich Arrays und ist damit etwas unflexibler. Auch an multidimensionalen Arrays verschluckt sich Jsonifice nicht, sie werden bei Bedarf rekusriv abgearbeitet. Als Bonus kann man eine Callback-Funktion angeben die auf jedes Element des Arrays bzw. Eigenschaft des Objektes angewendet wird. Dazu gleich noch ein paar Sätze.
Die Verwendung der Klasse ist ganz einfach: Mit new Jsonifice( $object_name, $data, $callback ) erzeugt man eine neue Instanz der Klasse und erzeugt autmatisch ein Json-Objekt. Das Json-Objekt kann man als reines Json (getRawjson()) oder mit einem entsprechenden HTML-Markup versehen (getJson()) abrufen. Als Parameter übergibt man den Namen für das spätere JS-Objekt und das Array bzw. ein Objekt aus dem das JS-Object erzeugt werden soll.
Der dritte Parameter ist eine Callback-Funktion die auf jedes Element angewendet wird. Der Callback ist optional, muss also nicht angegeben werden. Es ist aber äußerst ratsam seine Daten vor der Umwandlung zu filtern. json_encode hat so seine Probleme mit z.B. Umlaute und weiß nicht genau wie es damit umgehen soll.
WordPress bietet zum Glück in seiner Formatting API einen passenden Filter an der diese Aufgabe sehr gut meistert. Mittels esc_js werden eine ganze Reihe an Prüfungen vorgenommen, diese Funktion können wir dankenswerter Weise nutzen ohne uns selber einen Kopf darüber machen zu müssen welche Sonderfälle zu beachten sind.