Ankündigung

Einklappen
Keine Ankündigung bisher.

Collator Klasse erweitern und create überschreiben

Einklappen

Neue Werbung 2019

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

  • Collator Klasse erweitern und create überschreiben

    Hallo,
    ich möchte gerne die Collator-Klasse erweitern und auch create benutzen/überschreiben.

    PHP-Code:
    class CollatorExt extends Collator {

      public static function 
    create(string $locale)
      {
        return new 
    self($locale);
      }

    }

    $coll Collator::create('de_DE'); //object(Collator)
    $collExt CollatorExt::create('de_DE'); //object(CollatorExt) 
    Es werden die richtigen Objekte erzeugt, nur der Type hint für den Return macht Probleme (PHP 7.4).
    Code:
    Warning: Declaration of CollatorExt::create(string $locale) should be compatible with Collator::create($arg1)
    Setze ich dort einen Typ ?Collator wie in der Basismethode Collator::create ein kommt folgende Warnung
    Code:
    Declaration of CollatorExt::create(string $locale): ?Collator should be compatible with Collator::create($arg1)
    und mit ?CollatorExt
    Code:
    Warning: Declaration of CollatorExt::create(string $locale): ?CollatorExt should be compatible with Collator::create($arg1)
    Nun kann ich eine neue Methode createExt definieren welche create nicht überschreibt. Ich muss diese Methode dann aber zwingend nutzen um eine Instanz der Erweiterungsklasse zu bekommen,
    denn mit CollatorExt::create('de_DE'); erhalte ich dann nur eine Instanz der Basisklasse.

    Lasse ich die create-Methode in CollatorExt weg wird ja auf create der Basisklasse zurückgegriffen. Mit
    PHP-Code:
    $collExt CollatorExt::create('de_DE'); //object(Collator) 
    erhalte ich leider auch nur ein Objekt des Basisklasse.

    Gibt eine Lösung für das Problem?

  • #2
    PHP-Code:
    public static function create($locale

    Kommentar


    • #3
      Tatsache, wenn ich den Type hint komplett weglasse ist es ok. Danke hellbringer .

      Kommentar


      • #4
        Zitat von jspit Beitrag anzeigen
        Tatsache, wenn ich den Type hint komplett weglasse ist es ok. Danke hellbringer .
        Durch den Type hint hast du die Methodensignatur verändert, was dir die erste Warnung bereits mitgeteilt hat : "Declaration of CollatorExt::create(string $locale) should be compatible with Collator::create($arg1)"
        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

        Kommentar


        • #5
          Mir ist schon klar was die Warnungen besagen. Ich darf einerseits die Methodensignatur zur Basisklasse nicht verändern, wenn ich diese jedoch übernehme dann passt es es nicht zum Name der Erweiterungsklasse.
          Es hilft hier nur auf den Type hint Krams zu verzichten.
          Am Rande: Mit einem return new static im create der Basisklasse bräuchte man create gar nicht zu überschreiben und bekommt trotzdem die gewünschte Instanz. Das und/oder fehlende Type hints werden dann aber wieder von einigen PHP Static Analysis Tools angemeckert.

          Zum Hintergrund: Die Collator-Klasse kennt kein Natsort.
          PHP-Code:
          $arr = ['b4','b14','b3','ba4','bo4','bö4','bu4','bü4','bz','bä243','ba4x','bä6'];

          CollatorExt::create('de_DE')->natsort($arr);

          echo 
          implode(', ',$arr)."<br>\n";
          //b3, b4, b14, ba4, ba4x, bä6, bä243, bo4, bö4, bu4, bü4, bz 

          Kommentar


          • #6
            PHP-Code:
            $collator->setAttribute(Collator::NUMERIC_COLLATIONCollator::ON); 

            Kommentar


            • #7
              Habe schon mit den Flags ohne Erfolg experimentiert. Das sieht richtig gut aus erc . Da kann ich mein CollatorExt Ansatz ja entsorgen .

              PHP-Code:
              $arr2 $arr = ['b4','b14','b3','ba4','bo4','bö4','bu4','bü4','bz','bä243','ba4x','bä6'];

              CollatorExt::create('de_DE')->natsort($arr2);
              echo 
              implode(', ',$arr2)."<br>\n";

              $c = new Collator('de_DE');
              $r $c->setAttribute(Collator::NUMERIC_COLLATIONCollator::ON); 
              $c->sort($arr);
              echo 
              implode(', ',$arr)."<br>\n";

              var_dump($arr === $arr2); //bool(true) 
              Code:
              b3, b4, b14, ba4, ba4x, bä6, bä243, bo4, bö4, bu4, bü4, bz
              b3, b4, b14, ba4, ba4x, bä6, bä243, bo4, bö4, bu4, bü4, bz
              bool(true)

              Kommentar


              • #8
                Weiss jemand, warum man den Fatal Error in PHP 8 auch nicht catchen kann?

                PHP-Code:
                class CollatorExt extends Collator {

                    public static function 
                create()
                    {
                      return new 
                self($locale);
                    }

                  }

                  try {
                    
                $collExt CollatorExt::create('de_DE'); //object(CollatorExt)  
                  
                } catch (\Throwable | \Error) {
                    echo 
                'an error occured';    
                  }
                // Fatal error: Declaration of CollatorExt::create() must be compatible with Collator::create(string $locale) statt "an error occured" 
                sorry, shift-taste kaputt

                Kommentar


                • #9
                  Meister1900 Kann ich nicht so richtig nachvollziehen (Tippfehler catch ?) https://3v4l.org/29E2p

                  Kommentar


                  • #10
                    Zitat von jspit Beitrag anzeigen
                    Meister1900 Kann ich nicht so richtig nachvollziehen (Tippfehler catch ?) https://3v4l.org/29E2p
                    Lass mal das $locale komplett weg, dann wird der Fehler nicht mehr abgefangen.
                    Weil du catchst in deinem Beispiel nur einen ArgumentCountError und nicht den Declaration of CollatorExt::create() must be compatible with...
                    sorry, shift-taste kaputt

                    Kommentar


                    • #11
                      Alles klar - https://3v4l.org/0fFNo.
                      Habe mal am Skriptanfang ein "echo start" eingefügt. Mit PHP8 wird dieser Fehler als Fatal Error geworfen. Diese Fehler werden bereits im Vorfeld geworfen und es kommt gar nicht erst zum Skriptstart. Es ist unter PHP8 deshalb auch kein "start skript" zu sehen. Mit Try Catch können aber nur Fehler gefangen werden die während des Skriptlaufes auftreten. Denke in Verbindung mit dem geänderten Beispiel wird das klar.

                      Kommentar


                      • #12
                        IMHO weil es ein Programmierfehler ist und kein Fehler, der zur Laufzeit auftritt. Ein try-catch macht bei sowas kein Sinn, weil der Fehler IMMER auftreten wird. Also kann man sich das try-catch auch gleich komplett sparen.

                        Aus einem ähnlichen Grund kann auch kein Syntax-Error gefangen werden, weil der Code ja gar nicht ausgeführt wird.

                        Kommentar


                        • #13
                          Naja, bei uns hatte es sich eingeschlichen, weil wir eine Methode einer Vendor-Klasse überschreiben und nach dem letzten "composer up" sich dann die ursprüngliche Methodensignatur geändert hat.
                          Also muss man wohl immer alles komplett testen und durchschauen, selbst wenn nur minor versions (vermeintlich) ohne breaking changes aktualisiert werden :-/
                          sorry, shift-taste kaputt

                          Kommentar


                          • #14
                            Ich persönlich würde davon Abstand nehmen von PHP-internen Klassen abzuleiten, und eher das Decorator-Pattern verwenden. Diese PHP-internen Klassen haben teilweise sehr eigenartige Verhalten, die bei "richtigen" PHP-Klassen nicht auftreten können.

                            Kommentar

                            Lädt...
                            X