Zugriff auf i18n-Objekte aus verschiedenen Bereichen


10

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 ConfigKlasse 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 TranslationsKlasse 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 LangKlasse, 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 TranslationsKlassen 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 Translationsdas 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 Translationsgelegentlich eine Klasse in einem Modell oder Validator verwenden und sie auch dort instanziieren, sodass ich in einer einzelnen Ausführung möglicherweise dasselbe TranslationsObjekt 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!

Antworten:


0

<?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 das Instanziieren einer Übersetzung das Array mit den Informationen nur kopiert, 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.

Ich verstehe, was Sie meinen ...
Ich denke, eine Sache, die Sie nerven könnte, ist, dass Sie durch Hinzufügen der Verantwortung für das Laden der Sprachdateien in der Ansicht das Entwurfsmuster
für die Inversion des Steuerelements brechen. Ihre 'myLangFile' wird zu groß und Sie möchten sie in zwei separate Dateien aufteilen. Sie können dies nicht tun, ohne den Ansichtscode zu ändern.
Was denken Sie?


1
Genau das ist ein absolut gültiger Grund.
php_nub_qq

1
"Ja wirklich?" Die Sprachdatei kann keine anderen Dateien in sich enthalten? Oder aus einer Datenbank lesen?
Svidgen

@vvgengen, das ist extrem schlechtes Design
php_nub_qq
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.