Ankündigung

Einklappen
Keine Ankündigung bisher.

PHPStan : Unsafe usage of new static()

Einklappen

Neue Werbung 2019

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

  • PHPStan : Unsafe usage of new static()

    Erhalte in mehreren Klassen den Hinweis von PHPStan
    Unsafe usage of new static()
    Dazu der stark vereinfachte Code:
    PHP-Code:
    class c1{}

    class 
    c2 extends c1
     public static function 
    create(){
        return new static;
      } 
    }

    var_dump(c2::create());
    //object(c2)#2 (0) { } 
    Verhält sich genau so wie ich es möchte. Habe die Hinweise zur obigen Meldung gelesen, verstehe aber nur Bahnhof. Ich möchte das c2 ebenfalls erweitert werden kann und dort dann folgendes möglich ist
    PHP-Code:
    class c3 extends c2{}
    var_dump(c3::create());
    //object(c3)#2 (0) { } 
    Warum soll new static unsicher benutzt worden sein?

  • #2
    https://phpstan.org/blog/solving-php...-of-new-static

    Kommentar


    • #3
      Zitat von jspit Beitrag anzeigen
      Warum soll new static unsicher benutzt worden sein?
      Wenn du eine Klasse vererbst, kannst du die Signatur des Konstuktors ändern.

      PHP-Code:
      class c1 {
          public static function 
      create(){
              return new static;
          }
      }

      class 
      c2 extends c1 {
          public function 
      __construct(foobar $foo) {}

      c2::create() würde zu einem Fehler führen.

      Kommentar


      • #4
        Die selbe Meldung bekam ich übrigens auch bei Psalm bei einer meiner Klasse.
        Doch dies kann man doch nicht anders lösen, oder?

        Habe den Link übersehen und nun gelesen, die Lösung: Make the constructor final

        Kommentar


        • #5
          erc Danke, darauf wäre ich nicht so schnell gekommen. Dies sollte es richten oder ?
          PHP-Code:
          class c1 {
              public static function 
          create(...$par){
                  return new static(...
          $par);
              }
          }

          class 
          c2 extends c1 {
              public function 
          __construct(foobar $foo) {}
          }

          class 
          foobar{}
          $foo = new foobar;

          $c2 c2::create($foo);
          var_dump($c2);  //object(c2)#3 (0) { } 
          Läuft fehlerfrei. Der Hinweis unter PHPStan bleibt jedoch.

          Kommentar


          • #6
            Zitat von strub Beitrag anzeigen
            Habe den Link übersehen und nun gelesen, die Lösung: Make the constructor final
            Habe ich auch gelesen. Ist für mich keine Lösung zu verbieten das die Erweiterungsklasse einen Konstruktor haben darf.

            Kommentar


            • #7
              Zitat von jspit Beitrag anzeigen
              Habe ich auch gelesen. Ist für mich keine Lösung zu verbieten das die Erweiterungsklasse einen Konstruktor haben darf.
              Na dann kann ja new static() gar nicht funktionieren, wenn sich der Konstruktor unterscheidet.

              Kommentar


              • #8
                Das ist generell ein Problem bei einer statischen Code-Analyse. Da kommt ebend auch viel quatsch zum vorscheinen. Sehs als Hinweis und mach kein Dogma draus. Wenn dir eine oder mehrere Regeln nicht passen, dann nimm sie raus. Wenn du der Meinung bist, das geht besser, kannst du auch ein Bug oder Patch bei PHPStan einreichen.

                Kommentar


                • #9
                  Zitat von erc Beitrag anzeigen
                  Das ist generell ein Problem bei einer statischen Code-Analyse. Da kommt ebend auch viel quatsch zum vorscheinen. Sehs als Hinweis und mach kein Dogma draus.
                  Ja, so sollte man es sehen. Es könnte an der Stelle zu Fehlern kommen. Anfangs war ich sehr geschockt was zum Teil bei Level 5 schon alles kommt. Beim genauen Hinschauen erwies sich dann 80% als falsch.
                  Der Rest waren zur Masse "Schönheitsfehler". Es kommen auch richtige Hinweise wie z.B. falsche Kommentare die kein Test zeigt. Zusammenfassend jedoch eine gute und nützliche Ergänzung.

                  Kommentar


                  • #10
                    Naja, es ist schon ein Problem, wenn man sich nicht darauf verlassen kann, was eine ableitende Klasse für eine Constructor-Signatur hat, wenn man das selbst nicht festschreiben kann. Der tatsächlich richtige Weg wäre btw. ein Interface zu definieren, dass die Methodensignatur von einem Constructor vorgibt.

                    Zitat von jspit Beitrag anzeigen
                    Beim genauen Hinschauen erwies sich dann 80% als falsch.
                    Wahrscheinlich nicht. Ich habe in größeren Projekten 0 Fehler auf Level 6 und bei einigen kleineren Projekten 0 Fehler auf max. Teilweise muss man Kompromisse eingehen, aber die vorgeschlagenen Änderungen ergeben fast immer Sinn.

                    Kommentar


                    • #11
                      Zitat von rkr Beitrag anzeigen
                      Ich habe in größeren Projekten 0 Fehler auf Level 6 und bei einigen kleineren Projekten 0 Fehler auf max.
                      Na ja für die neueren Projekte mit einer PHP-Version die auch fast auf max. steht. Ich muss jedoch teilweise auf abwärtskompatibilität zu PHP 5.6 achten. Dort bekomme ich dann bereits auf Level 6 massenhaft Hinweise "..has no typehint specified.", da PHPStan solche typehints möchte. Ähnliche Fehler bekommst auch du auch mit älteren Klassen von dir.

                      Zitat von rkr Beitrag anzeigen
                      Teilweise muss man Kompromisse eingehen, aber die vorgeschlagenen Änderungen ergeben fast immer Sinn.
                      Nun nicht immer. Ich liefere dazu gerne Beispiele:
                      PHP-Code:
                      $str date_create()->format('d.m.Y'); 
                      liefert
                      Cannot call method format() on DateTime|false.
                      So wie das geschrieben ist kann date_create() niemals false liefern. So etwas in der Art zu machen
                      PHP-Code:
                      $dt date_create();
                      $str $dt $dt->format('d.m.Y') : ""
                      damit so ein Tool seine Ruhe hat da sträubt sich bei mir alles.

                      2. Beispiel
                      PHP-Code:
                      $objectId function_exists('spl_object_id')
                              ? 
                      "#".spl_object_id($obj)
                              : 
                      ""
                            

                      Da meckert PHPstan für PHP 7.1 :
                      Function spl_object_id not found.
                      Bin da ganz bei erc . Solche Analyse-Tools können eine große Hilfe sein, haben aber auch ihre Grenzen.



                      Kommentar


                      • #12
                        Zitat von jspit Beitrag anzeigen
                        Nun nicht immer. Ich liefere dazu gerne Beispiele:
                        PHP-Code:
                        $str date_create()->format('d.m.Y'); 
                        liefert

                        So wie das geschrieben ist kann date_create() niemals false liefern. So etwas in der Art zu machen
                        PHP-Code:
                        $dt date_create();
                        $str $dt $dt->format('d.m.Y') : ""
                        damit so ein Tool seine Ruhe hat da sträubt sich bei mir alles.

                        2. Beispiel
                        PHP-Code:
                        $objectId function_exists('spl_object_id')
                        "#".spl_object_id($obj)
                        ""

                        Da meckert PHPstan für PHP 7.1 :

                        Bin da ganz bei erc . Solche Analyse-Tools können eine große Hilfe sein, haben aber auch ihre Grenzen.


                        Ja, das sind eigentlich ganz gute Beispiele.
                        Die Frage ist jetzt, ob du lieber die Warnungen ignorierst, oder ob du den Drops schluckst und darauf setzt, dass PHPStan dir auch mal richtige Probleme zeigt? Level 5 wird für die meisten Belange sicherlich ausreichend sein.

                        Hier noch ein paar schnelle Fixes:

                        Zitat von jspit Beitrag anzeigen
                        PHP-Code:
                        $str date_create()->format('d.m.Y'); 
                        könnte man ersetzen mit:

                        PHP-Code:
                        $str = (new DateTime)->format('d.m.Y');
                        $str date('d.m.Y'); 

                        Zitat von jspit Beitrag anzeigen
                        PHP-Code:
                        $objectId function_exists('spl_object_id') ? "#".spl_object_id($obj) : ""
                        https://github.com/symfony/polyfill-...ap.php#L46-L48

                        Kommentar


                        • #13
                          Zitat von hellbringer Beitrag anzeigen

                          Na dann kann ja new static() gar nicht funktionieren, wenn sich der Konstruktor unterscheidet.
                          Kann schon mit Tricks, macht jedoch wenig Sinn.

                          rkr Der von PHPStan angemeckerte Code läuft fehlerfrei und macht keinerlei Probleme. Sehe nicht ein, warum ich das umschreiben sollte.

                          Kommentar


                          • #14
                            Wenn du der Meinung bist das der Fehler unberechtigt ist, dann kannst du auch ein Kommentar drüber setzen welcher der Code Analyse sagt dass es die Zeile ignorieren soll.
                            Ignoring Errors | PHPStan

                            Kommentar


                            • #15
                              Zitat von Zeichen32 Beitrag anzeigen
                              Wenn du der Meinung bist das der Fehler unberechtigt ist, dann kannst du auch ein Kommentar drüber setzen welcher der Code Analyse sagt dass es die Zeile ignorieren soll.
                              Ignoring Errors | PHPStan
                              Würde ich in dem Fall nicht machen.
                              Falls der Code mit PHP9 nicht mehr funktioniert, dann wird PHPStan da ggf. früh drauf hinweisen.

                              Kommentar

                              Lädt...
                              X