PHPStorm强大的代码提示技巧

熟练掌握代码提示技巧可以事半功倍

作者 Fandy 日期 2017-03-23
PHPStorm强大的代码提示技巧

PHPStorm强大的代码提示技巧

PHPStorm作为PHP界的第一IDE,一直被奉为神作。合理利用IDE,不仅能够让你写出来的代码易读,更易于别人维护。今天我们就来聊聊编写代码过程中,合理利用代码提示的一些技巧。合理利用代码提示,不仅能加快编码速度,更是能减少大量低级错误,增加阅读代码时的连贯性。

常规代码提示

在PHP代码中,常规的写法是可以自动被IDE识别,并且生成代码提示的。常见的代码提示主要有:

  • 引入文件提示
  • 类名提示
  • 类成员提示
  • 函数参数提示
  • 等等

常规的写法,只要不是动态的构造类和函数名,就可以正常使用代码提示。那么动态构造的类名如何处理呢?

动态变量代码提示

在代码中,经常会遇到这种情况,比如如下代码:

1
2
3
$className = 'Demo';
$obj = new $className;
$obj->callFunc();

这段代码,在IDE中就无法实现callFunc的代码提示,这个时候只要增加一段注释,就可以让IDE识别到该变量类型,达到自动代码提示的目的,代码如下:

1
2
3
4
$className = 'Demo';
/** @var $obj Demo */
$obj = new $className;
$obj->callFunc();

PHPStorm有个全局查找引用的功能,操作方式是选中类名或者函数名,按快捷键Alt + F7,如果是动态调用到的类和函数,在IDE中是无法自动识别引用的,这个时候,如果通过合理的注释向IDE申明引用,便可以将动态调用的类与项目关联起来,查找引用时更加全面。

工厂模式代码提示

程序中经常会有工厂模式的存在,假如现在有DB类,工厂模式从设计角度将就是使用一个工厂类来管理DB类的实例,那么这个设计模式就会将DB类的实例存入工厂类的一个成员变量,外部调用工厂类来获取DB类的实例。这种方式是为了减少DB类的实例化次数,减少性能开销。这种工厂类的简单实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** DB 工厂类 */
class DBFactory {

private static $dbs = array();

public static function factory($dbname)
{
if(!isset(self::$dbs[$dbname])) {
self::$dbs[$dbname] = new DB($dbname);
}
return self::$dbs[$dbname];
}
}
/** DB类 */
class DB {
public function __construct($dbname)
{
// return a DB object
}
public function query()
{
}
}

$db = DBFactory::factory('demo');
$db->query();

这里最后一行的调用在IDE里是无法实现代码提示的,这里依然可以使用动态变量代码提示 一节提到的技巧来实现,如下:

1
2
/** @var $db DB */
$db = DBFactory::factory('demo');

还可以使用另一种方法,就是在工厂类的函数里指定返回类型,如下:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 返回DB类的实例
* @param $dbname string 数据库名
* @return DB
*/
public static function factory($dbname)
{
if(!isset(self::$dbs[$dbname])) {
self::$dbs[$dbname] = new DB($dbname);
}
return self::$dbs[$dbname];
}

这个时候在IDE中,依然可以实现代码提示。

单例模式代码提示

单例模式和注册树模式常常是结合在一起使用的,注册树模式能够合理的管理对象,增加对象的复用性,减少性能损耗,使用注册树模式,可以非常方便的实现一个单例对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class RegisterTree {
protected static $_instances = array();
public static function getInstance($className)
{
if(!isset($_instances[$className])) {
$_instances[$className] = new $className;
}
return $_instances[$className];
}

public static function A()
{
}
}

class Demo extends RegisterTree {
public static function getInstance()
{
return parent::getInstance(__CLASS__);
}
public static function B()
{
}
}

以上两个类,分别是一个注册树的基类,以及一个单例类。现在需要调用B函数如下:

1
$demo = Demo::getInstance()->B();// 这里无代码提示

以上调用在IDE里是无法出现代码提示的,这个时候我们可以在单例类的构造器里加入返回类型申明,即可解决,如下:

1
2
3
4
5
6
7
8
9
10
11
12
class Demo extends RegisterTree {
/**
* @return self
*/
public static function getInstance()
{
return parent::getInstance(__CLASS);
}
public static function B()
{
}
}

加入@return self 之后,IDE便能成功提示B函数了,但是无法提示A函数,这个时候需要在RegisterTree 函数的构造器中加入类型申明,即可实现代码提示,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class RegisterTree {
protected static $_instances = array();
/**
* @return static
*/
public static function getInstance($className)
{
if(!isset($_instances[$className])) {
$_instances[$className] = new $className;
}
return $_instances[$className];
}

public static function A()
{
}
}

这个时候,再来调用

1
2
$demo = Demo::getInstance()->B();// 有代码提示
$demo = Demo::getInstance()->A();// 有代码提示

结语

之前动态变量调用的代码提示,让我纠结了很久,这个之前一直不知道改如何解决,今天google一下发现别人早就已经发现并解决了这些问题

PHPStorm强大之处远不止于此,以后慢慢挖掘!