지연 정적 속박은 어노테이션에서도 사용할 수 있다! PhpStorm에서의 개발을 돕는 사람 궁리

7504 단어 PHPPhalconPhpStorm
주로 PhpStorm7 로 개발해 주시는 분이 대상입니다.
다른 IDE에서는 시도하지 않지만 가능성이있을 수 있습니다.

여기서의 「어노테이션」은, 문서 코멘트로 IDE 에 메타 정보를 제공하기 위한 주석을 가리키고 있습니다. Web Application Framework에 대한 정보가 제공되지 않습니다.
또한 PSR을 준수하는지 여부는 확인하지 않으므로 양해 바랍니다.

지연 정적 바인딩의 정적은 주석에서도 사용할 수 있습니다.



예를 들어, DB 로부터와 같은 Model(Entity) 를 취득하는 공통 메소드가 부모 클래스로 정의되고 있다고 합니다.

Model.php
class Model {

    /*
     * モデル取得メソッド
     *
     * @param array|string|integer $parameters
     * @return Model
     */
    public static function findFirst($parameters=null) { }
}

이것을 상속하고 구상 클래스를 정의하면 ...



기본 클래스에 정의된 findFirst 반환값은 Model이므로 마지막 문장$entry->date에서 Model에 속성$date이 정의되지 않았다는 경고가 표시됩니다.
(실제로는 magic method 로서 액세스 된다고 하는 메세지입니다)

즉, $entryEntry 클래스의 인스턴스로서 취급하고 싶은 장면인데, Model 클래스의 인스턴스로서 인식되어 버린다는 것입니다.

따라서 Model::findFirst 어노테이션을 다음과 같이 수정합니다.

Model.php
class Model {

    /*
     * モデル取得メソッド
     *
     * @param array|string|integer $parameters
     * @return static
     */
    public static function findFirst($parameters=null) { }
}
@return 다음 형식 주석을 Model 대신 static로 변경했습니다.



이제 경고가 취소되고 호출자Entry 클래스의 인스턴스로 인식되었습니다.

예에서는 클래스의 필드를 참조했습니다만, 예를 들어 모처럼 메소드 체인을 연결할 수 있도록(듯이) setter 메소드로 $this 를 반환하고 있어도, 구상 클래스의 인스턴스로서 인식되지 않으면 경고 투성이가 되어 입력 보완이 효과가 없어서 유감스러운 기분이 되네요.
반환되는 인스턴스가 구상 클래스의 것이 되는 것을 알고 있는 경우, 어노테이션에 static 를 지정하면 그런 일도 없어집니다.

정적 지연에 대한 자세한 내용은 공식 매뉴얼 : 지연 정적 바인딩을 참조하십시오.

Phalcon의 이야기



PhpStorm + Phalcon 으로 개발되고 있는 분은 이미 알고 있을 것이라고 생각합니다만, 위의 예를 그대로 Phalcon 문서 라이브러리 에 적용하는 것으로 개발을 가속할 수 있습니다.

ide/1.2.5/Phalcon/Mvc/Model.php#L388

Phalcon/Mvc/Model.php 부분 발췌
<?php 

namespace Phalcon\Mvc {

    abstract class Model implements \Phalcon\Mvc\ModelInterface, \Phalcon\Mvc\Model\ResultInterface, \Phalcon\DI\InjectionAwareInterface, \Serializable {

        /* 省略 */

        /**
         * Allows to query a set of records that match the specified conditions
         *
         * <code>
         *
         * //How many robots are there?
         * $robots = Robots::find();
         * echo "There are ", count($robots), "\n";
         *
         * //How many mechanical robots are there?
         * $robots = Robots::find("type='mechanical'");
         * echo "There are ", count($robots), "\n";
         *
         * //Get and print virtual robots ordered by name
         * $robots = Robots::find(array("type='virtual'", "order" => "name"));
         * foreach ($robots as $robot) {
         *     echo $robot->name, "\n";
         * }
         *
         * //Get first 100 virtual robots ordered by name
         * $robots = Robots::find(array("type='virtual'", "order" => "name", "limit" => 100));
         * foreach ($robots as $robot) {
         *     echo $robot->name, "\n";
         * }
         * </code>
         *
         * @param array|string $parameters
         *              ...配列だけじゃなく文字列も渡せるので修正
         * @return \Phalcon\Mvc\Model\ResultsetInterface|static[]
         *              ...static[] を追加して具象クラスの配列として認識させる
         */
        public static function find($parameters=null){ }


        /**
         * Allows to query the first record that match the specified conditions
         *
         * <code>
         *
         * //What's the first robot in robots table?
         * $robot = Robots::findFirst();
         * echo "The robot name is ", $robot->name;
         *
         * //What's the first mechanical robot in robots table?
         * $robot = Robots::findFirst("type='mechanical'");
         * echo "The first mechanical robot name is ", $robot->name;
         *
         * //Get first virtual robot ordered by name
         * $robot = Robots::findFirst(array("type='virtual'", "order" => "name"));
         * echo "The first virtual robot name is ", $robot->name;
         *
         * </code>
         *
         * @param array|string|integer $parameters
         *              ...文字列も、実は数値(主キー値)も渡せる
         * @return static
         *              ...こちらも同様に具象クラスのインスタンスとして認識させる
         */
        public static function findFirst($parameters=null){ }


        /* 省略 */

    }
}

위와 같이 어노테이션을 4행 재작성합니다.
이것을 눈치채기까지는 구상 클래스측에서 find findFirst 를 오버라이드(override) 해 어노테이션을 할당하고 있었습니다만, 이것으로 그 필요도 없어졌습니다!

문득 Pull Request 를 보내려고도 생각했습니다만, Phalcon 전체로서의 코딩 스타일이나 PSR 와의 충돌도 생각할 수 있으므로, 어디까지나 개인적으로 조정하는 범위라고 생각해 이쪽에 투고했습니다.

좋은 웹페이지 즐겨찾기