大部分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]; // } } ?>
效果圖如下:
延伸閱讀: