大部分PHP框架中,為了防止一個類被重復實例化,往往采用“單例模式”實例化類。我們的項目框架是這樣做的:
先寫好一個基類 /framework/Base.class.php,內容如下:
<?php
namespace framework;
defined('SITE_PATH') or die('Access Denied');
/**
* 業務基類
*
* @package framework
*/
class Base
{
/**
* 類實例化(單例模式)
*
* @return mixed
* @throws \Exception
*/
public static function instance()
{
static $_instance = array();
$classFullName = get_called_class();
if (!isset($_instance[$classFullName]))
{
core_load_class($classFullName);
if (!class_exists($classFullName, false))
{
throw new \Exception('"' . $classFullName . '" was not found !');
}
$_instance[$classFullName] = new $classFullName();
}
return $_instance[$classFullName];
}
}
?>
某個 會員模型類 繼承 Base 基類, \common\model\MemberModel.class.php
<?php
namespace common\model;
use framework\Base;
defined('SITE_PATH') or die('Access Denied');
/**
* 會員 模型
*/
class MemberModel extends Base
{
protected $tableName = 'member';
protected $pk = 'memberId';
/**
* 根據memberId獲取記錄
*
* @param string $memberId 會員ID
* @param string $field 要顯示的字段
* @return array
*/
public function getByMemberId($memberId = '', $field = '*')
{
return array(); // 隨便寫下
}
}
?>
其他方法中,使用該 會員模型,參考代碼如下:
MemberModel::instance()->getByMemberId('168');
遇到的問題
本以為很完美,但是在 PhpStorm 中,根本識別不了 MemberModel::instance() 實例化類的方式,它會提示 getByMemberId() 方法不存在。這很讓人崩潰,因為這樣,
1、當敲完代碼 MemberModel::instance()-> 后,PhpStorm 不會自動彈出它的 屬性/方法 下拉提示框;
2、無法通過快捷鍵 重構 MemberModel 類的 getByMemberId() 方法;
如何解決上述 PhpStorm 代碼自動提示功能失效的問題?
我懷疑是 PhpStorm 對基類中的代碼:
$_instance[$classFullName] = new $classFullName();
return $_instance[$classFullName];
不識別導致的!
今天在逛別人的博客時,看到對“PHP延遲靜態綁定”知識點的介紹,先前早就看到過這個概念,但一直沒有仔細去研究,查了下資料,匯總如下:
文章提到,通過 static() 方法,能返回子類的實例。static 正好是 PHP 的關鍵字,相信 PhpStorm 對它一定是很敏感的。
果不出我所料,調整了下基類方法,問題解決:
<?php
namespace framework;
defined('SITE_PATH') or die('Access Denied');
/**
* 業務基類
*
* @package framework
*/
class Base
{
/**
* 類實例化(單例模式)
*/
public static function instance()
{
static $_instance = array();
$classFullName = get_called_class();
if (!isset($_instance[$classFullName]))
{
core_load_class($classFullName);
if (!class_exists($classFullName, false))
{
throw new \Exception('"' . $classFullName . '" was not found !');
}
// $_instance[$classFullName] = new $classFullName();
// 1、先前這樣寫的話,PhpStrom 代碼提示功能失效;
// 2、並且中間變量不能是 數組,如 不能用 return $_instance[$classFullName] 形式返回實例對象,否則 PhpStrom 代碼提示功能失效;
$instance = $_instance[$classFullName] = new static();
return $instance;
}
return $_instance[$classFullName];
}
/**
*【老版本】類實例化(單例模式)
*【缺陷】PhpStorm 的代碼提示功能失效
*
* @return mixed
* @throws \Exception
*/
// public static function instance()
// {
// static $_instance = array();
//
// $classFullName = get_called_class();
// if (!isset($_instance[$classFullName]))
// {
// core_load_class($classFullName);
// if (!class_exists($classFullName, false))
// {
// throw new \Exception('"' . $classFullName . '" was not found !');
// }
// $_instance[$classFullName] = new $classFullName();
// }
//
// return $_instance[$classFullName];
// }
}
?>
效果圖如下:

延伸閱讀:
