Typehinting through Zend_Registry::get() - how to make navigation to declaration understandable to PhpStorm?

僤鯓⒐⒋嵵緔 提交于 2019-12-23 17:25:29

问题


You can pass anything to Zend_Registry::set('myWidget', $someWidget), so that it's available later on.

However, when you retrieve it elsewhere, PhpStorm IDE has no clues to the type of 'myWidget'.

<?php
class AwesomeWidget {
   public function doBazFlurgle() {
      // doesn't matter what exactly happens here
      return mt_rand();
   }
}
?>

<?php 
class FooController {

    public function init() {
        $someWidget = new AwesomeWidget();
        Zend_Registry::set('awesome', $someWidget);
    }

    public function barAction() {
        $this->init();
        $awesome = Zend_Registry::get('awesome');
        $awesomeNumber = $awesome->doBazFlurgle();
    }

}

Navigate to declaration on the ->doBazFlurgle() call gets me a "Cannot find declaration to go to".

  • I could add a /** @var AwesomeWidget $awesome */ annotation, but that would require editing in many places in a sizable codebase
  • I could also add a return type annotation to Zend_Registry, but that does not look very maintainable (there are many instances of different classes stored this way).
  • I could search for the string doBazFlurgle through Find In Path..., but that is not entirely convenient (many keystrokes as opposed to a single Ctrl+click)

I noticed that NetBeans is capable of jumping to the method definition in this exact situation; is there a simple way of doing the same in PHPStorm without going through "search the entire codebase for doBazFlurgle"? I have searched available IDE actions, plugins, and fora; all in vain.


回答1:


There is a way: as pointed out by @LazyOne, making a list of "what is returned from where" helps the IDE make sense of such code; this is somewhat documented on Jetbrains' website:

<?php
/** @link https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata */
// note that this is not valid PHP code, just a stub for the IDE
namespace PHPSTORM_META {
    $STATIC_METHOD_TYPES = [
        \Zend_Registry::get('') => [
            'awesome' instanceof \AwesomeWidget, // this is the class as seen in the question
            'fooSetting' instanceof \Zend_Config, // this came in from application settings
            'quuxData' instanceof \ArrayAccess, // an arraylike object
        ]
    ];
}

Including this file (named .phpstorm.meta.php by convention) in the project has resolved the issue. This file is not valid PHP - PhpStorm only uses it for typehinting. That way, Zend_Registry::get('awesome')->doBazFlurgle() is correctly resolved as calling the method on an instance of \AwesomeWidget.




回答2:


There is a workaround:

  • Position cursor into doBazFlurgle method call (click or cursor movement)
  • Select word (Ctrl+W)
  • Navigate to symbol (Ctrl+Alt+Shift+N)
  • method will be offered in dropdown
  • Select method (Enter)

Although this is not quite as clumsy as a generic string search, it is still not quite as convenient as the usual navigate to declaration.



来源:https://stackoverflow.com/questions/34317265/typehinting-through-zend-registryget-how-to-make-navigation-to-declaration

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!