Ankündigung

Einklappen
Keine Ankündigung bisher.

PHP Storm, PHP 5.4+ und Closure Binding

Einklappen

Neue Werbung 2019

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

  • PHP Storm, PHP 5.4+ und Closure Binding

    Hallo zusammen,

    Bisher hab ich den ( vermeintlich ) Mangelnden Support für die Closure-Klasse in PHPStorm einfach ignoriert. Dennoch würde mich interessieren in wie weit ihr die II ( Inspection Intelligence ) davon überzeugt das eine Variable eine Closure-Instanz ( und kein Closure ) ist.

    Worum es konkret geht:

    PHP-Code:
    <?php

    $foo 
    = function() {
       return 
    'bar';
    };

    // folgende Anweisung ist für PHPStorm maximal ein Lambda, 
    // aber keine Closure-Instanz, was dazu führt dass das Closure
    // keine Methode bindTo() hat und ein Marker mit einer Warnung
    // dort angezeigt wird.
    $foo->bindTo(new StdClass'stdClass');
    Ignoriert ihr das auch, oder hat sich da schon mal jemand dran gehangen und eine Lösung fabriziert ?

    tr0y
    [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

  • #2
    Beim Googeln habe ich diesen Thread als erstes Ergebnis gefunden. Aber sonst nichts hilfreiches.

    Einen Bug Report gibt es offensichtlich schon länger (1 Jahr) http://youtrack.jetbrains.com/issue/WI-16785

    Ich denke abwarten und Tee trinken wäre das beste. Ansonsten…

    … bleibt nur noch dekompilieren, anpassen und rekompilieren.

    Da gäbe es diese Klasse: com.jetbrains.php.lang.psi.elements.impl.PhpExpres sionImpl in der man in der getType Methode folgendes findet:

    Code:
        if (getNode().getElementType() == CLOSURE) {
          return PhpType.CALLABLE;
        }
    D.h. PHPStorm behandelt eine Closure intern als Callable zum Typechecken (außer für Typehints).

    Diese Methode wird von der com.jetbrains.php.lang.inspections.PhpUndefinedMethod Inspection Klasse in der buildVisitor Methode aufgerufen, wo du jetzt einen Ausnahmefall für classReference.getNode().getElementType() == CLOSURE hinzufügen kannst...

    Ich habe jetzt nichts von dem da oben ausprobiert, nur in den Output vom JD-GUI Programm geschaut... An dir es auszuprobieren.

    (EDIT: Die Forensoftware rendert irgendwie Leerzeichen in die Klassennamen rein, warum?)

    Kommentar


    • #3
      Dank dir bwoebi,

      ja Google hatte mich soweit nicht vorwärts gebracht. Ich werde mal schauen ob ich den Source modifiziere, mal sehen. Ist etwas problematischer wenn PHPStorm automatisch updated, denke ich.
      [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

      Kommentar


      • #4
        Ja, das ist das einzige Problem, aber du kannst halt auch manuell updaten oder die zwei Zeilen manuell ändern dann. Ansonsten führt da kein Weg vorbei, fürchte ich.

        Du kannst immer noch darauf hinweisen in deren Bugtracker, vielleicht hilft es was...

        Kommentar


        • #5
          Zitat von bwoebi Beitrag anzeigen
          Ja, das ist das einzige Problem, aber du kannst halt auch manuell updaten oder die zwei Zeilen manuell ändern dann. Ansonsten führt da kein Weg vorbei, fürchte ich.

          Du kannst immer noch darauf hinweisen in deren Bugtracker, vielleicht hilft es was...
          Ich denke ich werde im BT vorbeischauen.
          Zitat von bwoebi Beitrag anzeigen
          P.s.: Ich bin versucht tr0y darauf hinzuweisen, dass links unten bei jedem Post eine schöne Waage ist...
          Done.
          [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

          Kommentar


          • #6
            zur not kann man phpStorm noch ein bisschen austricksen.

            irgendwo im project eine klasse anlegen, die die funktionsrümpfe der Closure beinhaltet und sie anders als die klasse Closure benennen.
            edit: oder dort wo phpStorm noch nach klassendefinitionen schaut. glaub das kann man noch konfigurieren

            PHP-Code:
            /**
             * Class used to represent anonymous functions.
             * <p>Anonymous functions, implemented in PHP 5.3, yield objects of this type.
             * This fact used to be considered an implementation detail, but it can now be relied upon.
             * Starting with PHP 5.4, this class has methods that allow further control of the anonymous function after it has been created.
             * <p>Besides the methods listed here, this class also has an __invoke method.
             * This is for consistency with other classes that implement calling magic, as this method is not used for calling the function.
             */
            final class MyClosure {

                
            /**
                 * This method exists only to disallow instantiation of the Closure class.
                 * Objects of this class are created in the fashion described on the anonymous functions page.
                 * @link http://www.php.net/manual/en/closure.construct.php
                 */
                
            private function __construct() { }

                public function 
            __invoke() { }

                
            /**
                 * Closure::bindTo � Duplicates the closure with a new bound object and class scope
                 * @link http://www.php.net/manual/en/closure.bindto.php
                 * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound.
                 * @param mixed $newscope The class scope to which associate the closure is to be associated, or 'static' to keep the current one.
                 * If an object is given, the type of the object will be used instead.
                 * This determines the visibility of protected and private methods of the bound object.
                 * @return Closure Returns the newly created Closure object or FALSE on failure
                 */
                
            function bindTo($newthis$newscope 'static') { }

                
            /**
                 * This method is a static version of Closure::bindTo().
                 * See the documentation of that method for more information.
                 * @static
                 * @link http://www.php.net/manual/en/closure.bind.php
                 * @param Closure $closure The anonymous functions to bind.
                 * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound.
                 * @param mixed $newscope The class scope to which associate the closure is to be associated, or 'static' to keep the current one.
                 * If an object is given, the type of the object will be used instead.
                 * This determines the visibility of protected and private methods of the bound object.
                 * @return Closure Returns the newly created Closure object or FALSE on failure
                 */
                
            static function bind(Closure $closure$newthis$newscope 'static') { }

            hier heißt sie nun einfach MyClosure. hab die klasse direkt aus der internen core_c.php von phpStorm rauskopiert.

            PHP-Code:
             <?php
            $foo 
            = function() {
               return 
            'bar';
            };

            /** @var MyClosure $foo */


            // hier meckert phpStorm nicht mehr
            $foo->bindTo(new StdClass'stdClass');
            nicht schön die Lösung. aber falls die lösung von bwoebi nicht funktioniert und man wirklich kein gemecker von phpStorm haben möchte, wär das so möglich

            Edit2: die lösung ist blöd. jetzt meckert phpStorm natürlich wenn man $foo irgendwo als callable überbegeben möchte

            edit3: so funktioniert:
            PHP-Code:
            /** @var MyClosure|Closure $foo */ 
            macht alles noch unschöner aber kein gemecker
            liebe Grüße
            Fräulein Dingsda

            Kommentar


            • #7
              Das ist eine Idee.. Aber ich möchte ungern Blind-Dateien in meinen Projekten rumliegen haben die nur einen Fehler in der IDE ausbügeln und sonst nichts tun.
              [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

              Kommentar


              • #8
                eventuell gibts noch nen weg phpstorm woanders nach klassendefinitionen schauen zu lassen als in seinen eigenen definitionsdateien.
                mir würde jetzt auch nur einfallen die datei als external library einzubinden um sie nicht im project zu haben.
                liebe Grüße
                Fräulein Dingsda

                Kommentar

                Lädt...
                X