大部分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延迟静态绑定”知识点的介绍,先前早就看到过这个概念,但一直没有仔细去研究,查了下资料,汇总如下:
父类方法返回子类实例: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];
// }
}
?>
效果图如下:
延伸阅读:
父类方法返回子类实例:PHP延迟静态绑定
PHP的继承方法如何获取子类名?get_class() 和 get_called_class() |