PHPDoc标记以禁止有关动态函数调用的警告

时间:2014-08-21 15:58:10

标签: php cakephp dynamic phpstorm phpdoc

我们有一个cakePHP项目,并使用Path - 类进行动态链接创建。

示例:

$this->redirect(Path::action_my_controller_path($id));

将重定向到action - 类的操作MyController并处理参数$id

所以现在我的IDE(PHPStorm)总是在抱怨Path - 类中缺少的函数,因为没有指定的action_my_controller_path($id) - 函数。

是否有人知道用于抑制此消息的PHP-Doc注释?

编辑: 在通过评论与LazyOne“说”之后,我在Path - 类中添加了以下PHPDoc,如其链接(phpDocumentor)中所述:

 /**
 *
 * @method array|string callStatic(string $name, string $args)
 */

class Path extends Object 

但是在调用Path - 类时我仍然会收到警告(参见上面的示例)。这个方法的自动生成的phpDoc(来自我的IDE)是

/**
 * @param $name
 * @param $args
 *
 * @return array|string
 */
public static function __callStatic($name, $args){

如果我写

 /**
 *
 * @method array|string __callStatic(string $name, string $args)
 */

class Path extends Object 

我收到Method with same name already defiend in class - 错误:/

edit2:完整Path - 类

<?php

/**
 * Zentrale Klasse fuer die Pfade, wobei jede Methode eines der akzeptierten
 * Formate von Router#url zurueckgibt, damit Router#url diese dann in eine
 * URL (als String) umwandeln kann.
 *
 * h3. Benutzung im View:
 *
 * <pre>
 *   $url = Path::alliances_path();
 *   $Html->link($url);
 * </pre>
 *
 *
 * h3. Konventionen (ueber __callStatic umgesetzt):
 *
 * <pre>
 * Semantische URL          <- Methoden Aufruf
 * -----------------------------------------------------------
 * /alliances               <- Path::alliances_path()
 * /alliances/add           <- Path::new_alliance_path()
 * /alliances/view/:id      <- Path::show_alliance_path($id)
 * /alliances/edit/:id      <- Path::edit_alliance_path($id)
 * /alliances/delete/:id    <- Path::delete_alliance_path($id)
 * </pre>
 *
 * h4. Allgemein:
 *
 * Wenn wir direkt eine Entitaet (ueber eine id gegeben) ansprechen, so
 * muss der controller im Singular sein.
 *
 * <pre>
 * /:controller/:action/:id <- Path::`:action:`_`:controller:`_path($id)
 * `:controller:` muss im Singular sein
 * </pre>
 *
 * Wenn wir ueber alle Entitaeten reden bzw. keine spezifische Entitaet
 * ansprechen, dann muss der controller im Plural stehen.
 *
 * z.B. die Uebersicht von `alliances`
 * <pre>
 * /alliances               <- Path::alliances_path($id)
 * </pre>
 *
 * z.B. Custom Actions, die noch keine Entitaet kennen
 * <pre>
 * /accounts/register       <- Path::register_accounts_path()
 * </pre>
 *
 * z.B. Custom Actions mit ohne spez. Entitaet und named parameters
 * <pre>
 * /accounts/register/confirmation:done   <- Path::register_accounts_path(array('confirmation' => 'done'))
 * </pre>
 *
 * h4. Custom Actions:
 *
 * z.B. `kick` Action in AlliancesController
 * <pre>
 * /alliances/kick/:id      <- Path::kick_alliance_path($id)
 * </pre>
 *
 * oder
 *
 * z.B. `leave` in AlliancesController
 * <pre>
 * /alliances/leave/:id     <- Path::leave_alliance_path($id)
 * </pre>
 *
 * h4. Named Parameters:
 *
 * <pre>
 * /alliances/sort:user_id/order:asc  <- Path::alliances_path(array('sort' => 'user_id', 'order' => 'asc'))
 * /alliances/kick/:id/user:600001    <- Path::kick_alliance_path($id, array('user' => 600001))
 * </pre>
 *
 * @see http://book.cakephp.org/2.0/en/development/routing.html#named-parameters
 */
class Path extends Object {

  /** @const */
  const LOGIN_PATH  = '/auth/login';
  const LOGOUT_PATH = '/auth/logout';
  const WELCOME_PATH = '/welcome';

  public static $settings = array(
    'signup' => array(
        'singular' => true,
        'plugin' => false,
        'entityActions' => array('disabled', 'world', 'code_expired', 'confirmation', 'disallowed', 'resend') # must be underscored
      ),
    'recover' => array(
        'singular' => true,
        'plugin' => false,
        'entityActions' => array('account', 'verify', 'token_expired')
      ),
    'support' => array(
        'singular' => true,
        'plugin' => false,
        'entityActions' => array('banned')
      ),
    'contact' => array(
        'singular' => true,
        'plugin' => false
      ),
    'about' => array(
        'singular' => true,
        'plugin' => false
      ),
    'auth' => array(
        'singular' => true,
        'plugin' => false,
        'entityActions' => array('counselor')
      ));



  public static function parseUrl($url) {
    $url = Router::normalize($url);
    $request = new CakeRequest($url, false);

    $params = Router::parse($request->url);
    $request->addParams($params);

    return $request;
  }

  protected static function getId($id){
    // ist kein array, muss id sein
    if(!is_array($id)) {
      return $id;
    }

    // id column vorhanden! als id nehmen
    if(isset($id['id'])) {
      return $id['id'];
    }

    trigger_error('Path: missing id column', E_USER_NOTICE);
    return null;
  }

  /* extract first argument to support:
   * - edit_user_path(1);
   * - edit_user_path(array(1));
   * - edit_user_path(array('id' => 1));
   * url will be /users/edit/1
   *
   * to suport named parameters use second array
   * - edit_user_path(1, array('key' => 'value'))
   * url will result as /users/edit/1/key:value
   */
  /**
   * @param      $args
   * @param bool $requires_id
   *
   * @return array
   */
  protected static function extractOptions($args, $requires_id = false){

    // keine argumente vorhanden
    if(!isset($args[0])) {
      return array();
    }

    // setzen von named parameters
    if($requires_id) {
      $named_parameters = isset($args[1]) && is_array($args[1]) ? $args[1] : array();
    } else {
      $named_parameters = is_array($args[0]) ? $args[0] : array();
    }

    // /alliances/index/name:parameter
    // -> hat keinen index, darum nur die
    // named_paramerters zurueck geben
    if(!$requires_id) {
      return $named_parameters;
    }

    // id muss vorhanden sein!, da kein index
    $id = self::getId($args[0]);
    return array_merge($named_parameters, array($id));
  }

  /**
   * @param $name
   * @param $args
   *
   * @return array|string
   */
  public static function __callStatic($name, $args){
    $parts = explode('_', $name);
    $path_or_url = array_pop($parts);

    # convert path into url
    if($path_or_url === 'url') {
      $name = implode('_', $parts) . '_path';

      # custom paths have priority over general
      $url  = call_user_func_array('static::' . $name, $args);
      return h(Router::url($url, true));
    }

    # neither path nor url
    if($path_or_url !== 'path') {
      return parent::__callStatic($name, $args);
    }

    if(count($parts) == 1) {
      # the short syntax
      $action = 'view';
      $controller_raw = $parts[0];
    } else {
      # first part is always the action
      $action = array_shift($parts);
      # for Path::action_complex_controller_path syntax we have to join
      $controller_raw = implode('_', $parts);
    }

    # underscore controller and action
    $action         = Inflector::underscore($action);
    $controller_raw = Inflector::underscore($controller_raw);

    $settings = isset(static::$settings[$controller_raw]) ?
                      static::$settings[$controller_raw] : array();

    # alias for more descriptive actions
    if($action === 'show') {
      $action = 'view';
    }else if($action === 'new') {
      $action = 'add';
    }

    # if the controller is in singular
    if(isset($settings['singular']) && $settings['singular']) {
      $controller = $controller_raw;
      $no_entity_path = true;
    } else {
      $controller = Inflector::pluralize($controller_raw);
      $no_entity_path = $controller == $controller_raw;
    }

    $is_index_path = $action == 'view' && $no_entity_path;

    # if the controller is in plural, then it is no entitiy
    $is_entity_path = (!$no_entity_path && $action != 'add') || in_array($action, (array)$settings['entityActions']);

    $defaults = array(
      'controller' => $controller,
      'action' => $is_index_path ? 'index' : $action,
      'plugin' => (boolean)$settings['plugin']
    );

    $options = static::extractOptions($args, $is_entity_path);

    return array_merge($defaults, $options);
  }
}

1 个答案:

答案 0 :(得分:1)

如果您希望PhpStorm停止抱怨访问action_my_controller_path()方法(或任何其他 SPECIFIC方法),请使用@method进行声明:

<强> BEFORE:

enter image description here

<强> AFTER:

enter image description here

您不必声明每一种方法 - 只有那些您计划直接调用的方法,就像您在此处所做的那样:$this->redirect(Path::action_my_controller_path($id));


如果您希望PhpStorm停止抱怨访问任何不存在的方法,那么您无法对此做任何事情 - 因为您拒绝使用所有当前可用的选项来解决此类问题:

  • 降低严重性以访问不存在的方法当magic __call / __ callStatic可用时 ..或完全禁用该检查(最后一个可能是一个过度杀伤,我同意) ;
  • &#34;禁止声明&#34; 选项以取消该特定地点的警告

很遗憾,没有@method语法,您可以使用通配符,例如: @method static array *(int $id);