多次调用数据库的PHP代码,PHP防止一次请求多次调用同一函数或方法重复查询数据库的方法...

在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;

}

}

也同样解决了重复查询数据库的问题。

各位看官不要觉得这样写很搞笑,在实际开发中是会出现这种情况的,尤其是对于新手来说。本着学习的态度,大家相互讨论,共同进步,欢迎吐槽。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值