Ich habe ein persönliches Framework von mir erstellt, das als Weg zum Erlernen des MVC-Musters begann und sich nun zu etwas entwickelt hat, das mir mehr gefällt als die meisten anderen Frameworks (wahrscheinlich, weil ich hinzufüge, was mir gefällt, und ändere, was ich anziehe nicht wie aber trotzdem) und zum Guten oder Schlechten benutze ich es in einigen Projekten.
Das Problem, das ich jetzt habe, ist, dass ich keinen vernünftigen Weg finden kann, um auf meine i18n-Funktionalität zuzugreifen (es ist nicht wirklich i18n, es sind nur Übersetzungen, es enthält keine vollständige i18n-Unterstützung, zumindest noch nicht).
Die Art und Weise, wie es funktioniert, ist, dass ich Konfigurationsdateien als Sprachdateien verwende, da ich dachte, es wäre ziemlich praktisch, die Config
Klasse zum Laden zu verwenden, da in meinem Framework Konfigurationsdateien dynamisch geladen werden - nicht geladen, es sei denn, dies wird benötigt. Sie können hier einen Blick darauf werfen
class Config {
private static $settings = array();
private function __construct() {
}
public static function load($file) {
$path = PROJECT_PATH . '/config/' . $file . '.php';
if (is_file($path)) {
$settings = require($path);
} else {
throw new Exception('Configuration file [' . $file . '] doesn\'t exist', 500);
}
self::$settings[$file] = $settings;
return true;
}
public static function get($file = null) {
if ($file === null) {
return self::$settings;
} elseif (isset(self::$settings[$file]) || self::load($file)) {
return self::$settings[$file];
}
}
}
Wo eine einzelne Konfigurationsdatei ungefähr so aussehen würde
<?php return array(
'setting0' => 'value',
'setting1' => 'value',
....
);
Dadurch kann PHP diese Dateien zwischenspeichern und das Laden wird sehr schnell.
Nun zu den Übersetzungen, wie gesagt, es handelt sich um Konfigurationsdateien in einem anderen Verzeichnis mit dem Namen lang
, aber ich kann nicht Config::get('lang/en/myLangFile')
jedes Mal aufrufen, wenn ich auf eine Übersetzung zugreifen muss, also habe ich die Translations
Klasse erfunden (erfunden, huh) , die a darstellt einzelne Übersetzungsdatei
class Translations {
protected $data = [];
public function __construct(array $translations) {
$this->data = $translations;
}
public function __get($name) {
return isset($this->data[$name]) ? $this->data[$name] : $name;
}
}
Jetzt ist es super bequem und schön, auf Übersetzungen zuzugreifen
$t = new Translations([...]);
echo $t->translationKey;
Ich habe eine Lang
Klasse, die verwendet wird, um unter anderem die bevorzugte Sprache des Benutzers einzurichten, also dachte ich mir, ich würde das als Fabrik für meine Translations
Klassen verwenden
class Lang {
public static function get($file) {
return new Translations(Config::get('lang/' . self::$lang . '/' . $file));
}
}
Jetzt muss ich nur noch ein paar Übersetzungen machen, um sie zu bekommen
$t = Lang::get('myLangFile');
echo $t->translationKey;
Falls Sie sich fragen, warum ich so viel statisches Material habe, liegt es daran, dass diese Klassen keinen Sinn machen, instanziiert zu werden, und ich das Singleton-Entwurfsmuster nicht mag. Ich bevorzuge "statische Klassen", obwohl sie in PHP nicht unterstützt werden (noch?).
So weit so gut, ich habe die Übersetzungen in Gang gebracht, aber kommen wir (endlich) zum Problem.
Wenn eine Ansicht gerendert wird, wird sie höchstwahrscheinlich Text an den Benutzer ausdrucken. Dafür muss ein Übersetzungsobjekt verfügbar sein, aber es ist ziemlich unpraktisch, dies vom Controller übergeben zu müssen, da ich gehen und gehen müsste Setzen Sie das auf jede Methode und das wäre die Hölle. Wenn ich das mache, ruft ein anderer Controller dieselbe Ansicht auf, ohne dass die richtigen Übersetzungsobjekte beschädigt werden. Dies ist sinnvoll, erhöht jedoch die Komplexität des Programms.
Was ich bis zu diesem Punkt getan habe, steht oben in jeder Ansicht, in der ich mein Übersetzungsobjekt konstruiere
<?php $t = Lang::get('myLangFile') ?>
<div><?= $t->helloWorld ?></div>
Dies funktioniert und garantiert mir, dass meine Ansichten unabhängig davon funktionieren, wer sie aufruft, und im Grunde genommen fast nichts an Leistung kosten, da durch das Instanziieren von a Translations
das Array mit den Informationen nur kopiert wird, wenn eine Änderung vorgenommen wird, da der Code im Konstruktor nur eine Zuweisung ist. Ich denke, das ist kein Problem, aber es nervt mich nur aus irgendeinem Grund, dass es nicht das Richtige ist.
Außerdem muss ich Translations
gelegentlich eine Klasse in einem Modell oder Validator verwenden und sie auch dort instanziieren, sodass ich in einer einzelnen Ausführung möglicherweise dasselbe Translations
Objekt mehrmals instanziieren kann . Um dieses Problem zu lösen, müsste ich anfangen, diese Objekte in die Registrierung aufzunehmen, und ich denke, dies würde zu weit gehen.
Ich würde gerne sehen, was einige Gedanken zu diesem Ansatz sind, da ich von meinen eigenen geblendet werden könnte und möglicherweise einige nützliche Ratschläge und Dinge bekommen könnte. Vielen Dank im Voraus an alle, die sich entschieden haben, ihre Zeit mit meinem Problem zu verbringen!