Ankündigung

Einklappen
Keine Ankündigung bisher.

Gettext, Silex und Lazy initialization

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Gettext, Silex und Lazy initialization

    Hallo zusammen,

    ich mache gerade meine ersten Schritte mit Silex und habe noch nicht genau verstanden was konkret bei meinem folgenden "Problem" passiert.

    Ich verwende Gettext und stelle die Funktion per ServiceProvider bereit. Damit Gettext ordnungsgemäß funktioniert verwende ich setlocal. Ein Fallstrick ist in der PHP Dokumentation beschrieben. Zwischen den einzelnen Seitenaufrufen wechselt die Sprache. Das passiert sobald mehrere Anfragen hintereinander eingehen.

    Zitat von PHP.net
    Die Locale-Informationen wirken auf den Prozess, nicht auf den Thread. Sofern Sie PHP mit einer Multithreaded Server API wie IIS oder Apache unter Windows einsetzen, rechnen Sie mit unerwarteten Änderungen der Locale-Einstellungen zur Laufzeit des Skripts, auch wenn das Skript selbst keinen setlocale()-Aufruf durchführt. Dies passiert, da andere Skripte in verschiedenen Threads des selben Prozesses zur selben Zeit prozessweit die Locale-Einstellungen mittels setlocale() ändern.
    Genau dieses Verhalten bekomme ich sobald ich die Lazy initialization Methode von Silex verwende. Instanziere ich direkt bekomme ich dieses Problem nicht.

    Meine Frage ist nun warum das Problem bei Lazy initialization aufritt? Tritt das bei direkter Instanzierung auch auf und ich bemerke es gerade nicht?

    Man sollte best practice alles Lazy initalisieren ist das hier möglich? Ausserdem kann ich ohne share nicht auf Parameter zugreifen die ich dem ServiceProvider übergeben habe.
    PHP-Code:
    $app->register(new LanguageProvider(), array(
            
    'language.default' => 'de_DE.utf8',
            
    'language.domain' => 'messages',
            
    'language.path' => __DIR__.'/locale',


    PHP-Code:
    class LanguageProvider implements ServiceProviderInterface {
    //...
    public function register(Application $app)
        {
                   
    /**
                    * Gewünschtes Verhalten jedoch kein $app['language.default'] möglich
                    */
                   
    $app['language'] = new LanguageController(/**/);


                   
    /**
                    * Falsches Verhalten bei Lazy initialization
                    */
                   
    $app['language'] = $app->share(function ($app) {
                                  return new 
    LanguageController(/**/);
                   });
        } 
    PHP-Code:
    class LanguageController {
    //...

        
    public function __construct(/**/) {
            
    //...
            
    putenv("LANG=$language");
            
    setlocale(LC_ALL$language);
        } 


  • #2
    PHP-Code:
    class LanguageController {
    //...

        
    public function __construct(/**/) {
            
    //...
            
    putenv("LANG=$language");
            
    setlocale(LC_ALL$language);
        } 
    wie wärs, wenn du statt den constructor eine methode setLocale benutzt
    und später bei lazy initialisation
    PHP-Code:
    $app['language']->setLocale($request->get('language')); 
    bezüglich deiner frage, constructor wird nur dann aufgerufen wenn du $app['language'] aufrufst und irgendwas damit tust, davor wird der construktor nicht aufgerufen, ohne lazy initialisierung wird bei dir aber schon beim registrieren des service providers der constructor aufgerufen.

    sprich
    PHP-Code:
       /**
                    * Falsches Verhalten bei Lazy initialization
                    */
                   
    $app['language'] = $app->share(function ($app) {
                                  return new 
    LanguageController(/**/);
                   }); 
    das wird nur eine closure in ein array geschoben, keine instanz angelegt, constructor wird nicht aufgerufen
    apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp | Mein Youtube PHP Kanal: https://www.youtube.com/c/VitalijMik

    Kommentar


    • #3
      Danke. Das werde ich probieren und berichten.

      Falls mir jemand erklären kann warum das einen Unterschied (für Silex?) macht würde ich das gerne erfahren. Auch um das Verhalten besser zu verstehen.

      Der Apache Server läuft übrigends auf einer VM Debian und nicht unter Windows wie im Hinweistext von php.net genannt. Auch ist es ein Testsystem mit nur dieser Anwendung und mich als einzigsten Benutzer.

      Zitat von BlackScorp Beitrag anzeigen
      bezüglich deiner frage, constructor wird nur dann aufgerufen wenn du $app['language'] aufrufst und irgendwas damit tust, davor wird der construktor nicht aufgerufen, ohne lazy initialisierung wird bei dir aber schon beim registrieren des service providers der constructor aufgerufen.
      Habe mich undeutlich ausgedrückt. Mir ist klar wie Lazy initialization funktioniert. Mein Frage zielte auf den Hintergrund ab, warum das für setlocal eine Rolle spielen könnte.

      Kommentar


      • #4
        Zitat von cnc_darklord Beitrag anzeigen

        Habe mich undeutlich ausgedrückt. Mir ist klar wie Lazy initialization funktioniert. Mein Frage zielte auf den Hintergrund ab, warum das für setlocal eine Rolle spielen könnte.
        hat nichts mit setlocale zu tun, hat mit dem Aufruf von deinem Construktor zutun. Der wird eben nicht sofort aufgerufen beim Registrieren deines Providers
        apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp | Mein Youtube PHP Kanal: https://www.youtube.com/c/VitalijMik

        Kommentar


        • #5
          Ok, dann ist das eigentliche Problem, dass die Ausgabe vor dem setlocal Aufruf passieren kann. Mit der extra Methode wird das Instantieren erzwungen. Danke!

          So einfach war es doch nicht. Der Aufruf
          PHP-Code:
          $app['language']->setLocale($app['session']->get('language')); 
          ist innerhalb register nicht möglich. Wenn ich den Aufruf unter boot reinschreibe besteht das Problem weiterhin. Selbst ein Aufruf in der index an erster Stelle behebt das nicht.

          Kommentar

          Lädt...
          X