PHP: Formatierung via __get()
In ydLinks benutze ich $link->§title, zur maskierten HTML-Ausgabe. Mit $link->title (Raw) und $link->§title (HTML-maskiert) gibt es aber nur zwei Varianten mehr bietet dieses Beispiel.
Das Prinzip ist wie in Link.php nur diesmal steht das '§'
in der Mitte des Attributes und dahinter folgt das gewünschte Format.
__get_format.php: $obj = new Model(); $obj->foo = 'aBcDeF " &'; echo 'raw : ', $obj->foo, "\n"; echo 'uppercase : ', $obj->foo§uppercase, "\n"; echo 'lowercase : ', $obj->foo§lowercase, "\n"; echo 'specialchars: ', $obj->foo§specialchars, "\n"; echo 'noquotes : ', $obj->foo§noquotes, "\n";
In __get($name) wird mit preg_match() der Name
und das Format extrahiert und daraufhin via switch($format)
die gewünschte Ausgabe zurückgegeben.
__get_format.php: public function __get($name) { // $obj->foo§uppercase if(preg_match('#^([^§]+)§([^§]+)$#', $name, $matches)) { $name = $matches[1]; $format = $matches[2]; $value = $this->_values[$name]; switch($format) { case 'lowercase' : return strtolower($value); break; case 'uppercase' : return strtoupper($value); break; case 'specialchars': return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8'); break; case 'noquotes' : return htmlspecialchars($value, ENT_NOQUOTES | ENT_HTML5, 'UTF-8'); break; default: throw new Exception("Unknown format '{$format}'."); break; } } else { return $this->_values[$name]; } }
Callback
Mit einem Callback wie im __get_format_callback.php-Beispiel
wird das Ganze noch flexibler.
$obj->addGetFormat('reverse', function($value) {return strrev($value);});
echo 'reverse : ', $obj->foo§reverse, "\n";
Das $this->_formats-Array enthält formatName => Callback-Paare, wobei die Callbacks in diesem
Fall anonyme Funktionen sind, die in __get($name) ausgewählt und ausgeführt werden.
public function __construct() {
$this->addGetFormat('raw' , function($value) {return $value;});
$this->addGetFormat('lowercase' , function($value) {return strtolower($value);});
...
}
public function addGetFormat($formatName, callable $callback) {
$this->_formats[$formatName] = $callback;
}
public function __get($name) {
// $obj->foo§uppercase
if(preg_match('#^([^§]+)§([^§]+)$#', $name, $matches)) {
$name = $matches[1];
$format = $matches[2];
} else {
$format = 'raw';
}
$value = $this->_values[$name];
return $this->_formats[$format]($value);
}
