使用 PHP Redis 客户端,在应用程序的每个 PHP 脚本中创建新的 $connection 对象,还是创建一个 GLOBAL $connection 对象?

Posted

技术标签:

【中文标题】使用 PHP Redis 客户端,在应用程序的每个 PHP 脚本中创建新的 $connection 对象,还是创建一个 GLOBAL $connection 对象?【英文标题】:Using PHP Redis client, create new $connection object in each PHP script in application, or create one GLOBAL $connection object? 【发布时间】:2018-02-19 06:01:15 【问题描述】:

在我的 php 应用程序中,我正在尝试使用 Redis(而不是 Predis,Redis 的 PHP 客户端)进行数据缓存,为此我正在关注 this tutorial.

现在我需要将数据存储在一个 PHP 脚本/页面的缓存中。为此,我将创建一个 Predis 客户端对象 $redis,然后使用此 $redis 对象调用其函数,如 set()expire() 将数据存储为键值对。下面给出一个示例 sn-p。

现在的问题是,在另一个 PHP 脚本/页面中,我需要读取缓存中存储的数据。为此,我需要再次在 $redis 对象上调用 get()exists() 等函数。

现在我的问题是,在第二个 PHP 脚本/页面中,我是否应该像上面提到的 $redis 那样创建一个新的 Predis 客户端对象(然后每次我想访问时都需要创建一个新的 $redis 对象数据存储在新 PHP 脚本/页面的缓存中),还是应该将第一个声明为 GLOBAL,以便可以从我的 Web 应用程序中的所有 PHP 脚本/页面访问它?正确的做法是什么

PHP 第一个脚本示例:

<?php
require "predis/autoload.php";
PredisAutoloader::register();
try 
    $redis = new PredisClient();

catch (Exception $e) 
    die($e->getMessage());

// sets message to contian "Hello world"
$redis->set('message', 'Hello world');
?>

PHP 第二个脚本示例:

<?php
/* THE FOLLOWING PART WHICH CREATES A $redis 
OBJECT SEEMS TO BE AN OVERDO. SHOULDN'T WE BE 
USING THE SAME $redis OBJECT FROM THE ABOVE SNIPPET? */


require "predis/autoload.php";
PredisAutoloader::register();
try 
    $redis = new PredisClient();

catch (Exception $e) 
    die($e->getMessage());


// gets the value of message
$value = $redis->get('message');
?>

【问题讨论】:

创建一个实例并使用 Dependency Injection 将其传递给不同的类。 【参考方案1】:

答案实际上取决于您的 Web 应用程序的复杂性。一种可以轻松实现的简单方法是创建一个单例类并在该类中使用静态变量。

class MyRedis 
    private static $redis;
    static function shared() 
        if ( empty(self::$redis) ) 
            try 
                self::$redis = new PredisClient();
             catch (Exception $e) 
                die($e->getMessage());
            
        
        return self::$redis;
    

现在当你想要你的对象时,你可以这样做:

$myRedisObject = MyRedis::shared();
// or 
$message = MyRedis::shared()->get('message');

如果它还没有这样做,它会制造一个。

【讨论】:

【参考方案2】:

您可能不需要这样做 - 您可以运行一些测试来检查,但根据 Predis docs:

到 Redis 的连接是惰性的,这意味着客户端连接到一个 仅在需要时提供服务器。虽然建议让 客户在后台做自己的事情,有时可能是 仍然希望控制连接何时打开或 关闭:这可以通过调用 $client->connect() 和 $client->disconnect().

这还取决于您建立了多少连接 - 这可能是过度设计的情况,因为连接开销虽然真实,但非常低。

我还假设在您的示例中,两个脚本都包含在一个请求中。您可以拥有某种消息传递/缓存组件,将数据存储在 Redis 中并使其可用于本地脚本环境,这取决于您的数据要求的具体情况。

【讨论】:

以上是关于使用 PHP Redis 客户端,在应用程序的每个 PHP 脚本中创建新的 $connection 对象,还是创建一个 GLOBAL $connection 对象?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel5.5配置使用redis

使用 Redis 在 PHP 和 socket.io/node.js 之间进行通信

redis入门教程3-客户端

PHP操作Redis PHP连接Redis,含Redis密码验证指定某一Redis数据库

php面试题汇总

redis简单应用