概述
在PHP开发中,为了实现需求或者因为代码质量,难免会出现在一次请求中多次调用同一函数或类方法。如果在这一函数或者类方法中需要查询数据库,多次调用时就会多次查询数据库。如果这多次查询结果还是一样的,就会造成服务器资源浪费,节约这部分被浪费的资源,在并发量大或者服务器配置低的情况下就很有用。
例如,在开发用户相关模块时定义了一个获取用户信息的函数:
function GetUserInfo($id) {
/* 此处省略数据库相关初始化 */
$user_info = $db->getRow($sql);
if (!is_array($user_info)) {
$user_info = array();
}
return $user_info;
}
在请求开始时是初始化文件中,先获取当前登录用户信息:
$current_user = GetUserInfo($_SESSION['user_id']);
if (!$current_user) {
/* ...... */
} else {
/* ...... */
}
在实际处理文件中,可能再次或多次通过GetUserInfo函数获取当前登录用户信息,甚至在模板里面一次或多次通过GetUserInfo函数获取当前登录用户信息。
在这种情况下,用户信息基本上没有变动,也很少出现在一次请求中,开头和结尾的当前用户信息不一样的情况,那调用了GetUserInfo函数几次,就几次打开、查询、关闭数据库。再多定义几个这种类似的函数和多次调用,那就又多次打开、查询、关闭数据库。
如何避免这种情况呢?这就要用到static(静态变量)。
静态变量仅在局部函数域中存在且只被初始化一次,当程序执行离开此作用域时,其值不会消失,会使用上次执行的结果。一般的函数内变量在函数结束后会释放,比如局部变量,但是静态变量却不会。也就是说,下次再调用这个函数的时候,该变量的值会保留下来。
那我们将GetUserInfo函数改一下:
function GetUserInfo($id) {
static $users = array();
if (isset($users[$id])) {
return $users[$id];
}
/* 此处省略数据库相关初始化 */
$user_info = $db->getRow($sql);
if (!is_array($user_info)) {
$user_info = array();
}
$users[$id] = $user_info;
return $user_info;
}
这样的话,在一次请求当中,获取过的用户信息都会保留在内存中,直到本次请求完成或关闭。即使多次调用GetUserInfo函数获取同一用户信息,就会先判断是否已经查询过这个用户,如果已经查询过一次,就直接返回上次查询出来的信息。
上面举的例子看起来有点像面向过程的写法,实际上,面向对象的写法也是差不多的。
比如,定义了这么几个类:
class AClass {
public function __construct() {
$user = $this->GetUserInfo($_SESSION['user_id']);
/* 接下来做了用户数据处理 */
}
protected function GetUserInfo($id) {
/* 此处省略数据库相关初始化 */
$user_info = $db->getRow($sql);
if (!$user_info) {
$user_info = array();
}
return $user_info;
}
}
class BClass extends AClass {
public function __construct() {
parent::__construct();
$user = $this->GetUserInfo($_SESSION['user_id']);
/* 接下来因为需求原因,重新做用户数据处理 */
}
}
class CClass extends BClass {
public function __construct() {
parent::__construct();
$user = $this->GetUserInfo($_SESSION['id']);
/* 接下来因为使用场景,又要重新做用户数据处理 */
}
public function index() {
$user = $this->GetUserInfo($_SESSION['id']);
/* 接下来又做了一次用户数据处理,在模板里面使用 */
$this->display('index.html');
}
}
同样的,我们将AClass中的GetUserInfo方法改一下:
class AClass {
public function __construct() {
$user = $this->GetUserInfo($_SESSION['user_id']);
/* 接下来做了用户数据处理 */
}
protected function GetUserInfo($id) {
static $users = array();
if (isset($users[$id])) {
return $users[$id];
}
/* 此处省略数据库相关初始化 */
$user_info = $db->getRow($sql);
if (!$user_info) {
$user_info = array();
}
$users[$id] = $user_info;
return $user_info;
}
}
也同样解决了重复查询数据库的问题。
各位看官不要觉得这样写很搞笑,在实际开发中是会出现这种情况的,尤其是对于新手来说。本着学习的态度,大家相互讨论,共同进步,欢迎吐槽。
最后
以上就是善良八宝粥为你收集整理的多次调用数据库的PHP代码,PHP防止一次请求多次调用同一函数或方法重复查询数据库的方法...的全部内容,希望文章能够帮你解决多次调用数据库的PHP代码,PHP防止一次请求多次调用同一函数或方法重复查询数据库的方法...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复