当试图从Laravel的Redis中获取不存在的键时,会返回null值的情况

这是一个让人开心的世界,会返回false或者null。

假设

行动环境

    • Laradock

Laravel 6.12
Redis 5.0.3
phpredis 5.1.1

数据库的内容

假设 Redis 中只有一个键名为 key1 的键存在。

127.0.0.1:6379> SET key1 value1
OK
127.0.0.1:6379> KEYS *
1) "key1"

请简洁总结。

Redis 可以被描述为一种内存数据结构存储系统。

当在Redis中指定一个不存在的键时,会返回nil。

127.0.0.1:6379> GET key1
"value1"
127.0.0.1:6379> GET key2
(nil)

PhpRedis: PHP扩展之一

在PhpRedis中,返回的是布尔类型的false。

$redis = new Redis();
$redis->connect('redis', 6379);
$value = $redis->get('key2');
var_dump($value);
string(6) "value1"
bool(false)

Laravel 框架

如果在 Laravel 中使用 PhpRedis 连接到 Redis 时,会返回 null 类型的 null。

use Illuminate\Support\Facades\Redis;

Redis::set('key1', 'value1');
$value = Redis::get('key1');  //--> "value1"
$value = Redis::get('key2');  //--> null

解释

Redis (中文:缓存数据库)

当使用 Redis 的 GET 或 MGET 命令获取不存在的键时,将返回 nil。

可以将字符串”nil”设置为SET,但不能设置特殊值nil。

127.0.0.1:6379> GET key2
(nil)
127.0.0.1:6379> SET key3 nil
OK
127.0.0.1:6379> GET key3
"nil"

PhpRedis是一个用于PHP的Redis扩展。

使用PhpRedis的get或mget方法尝试获取不存在的键时,将返回布尔类型的false。

这一点也在官方文件中明确指出。

返回值

字符串或布尔型:如果键不存在,则返回 FALSE。否则,返回与该键关联的值。

然而,请务必在这里记住的是,在PHP中,”0″或空字符串与false被视为相等的。

// 値として "0" をセットしてみる。
$redis->set('key4', 0);
$val4 = $redis->get('key4');

// キーの存在チェックのつもり...
if (!$val4) {
    echo "key4は存在しない";
}

// 値として空文字をセットしてみる。
$redis->set('key5', "");
$val5 = $redis->get('key5');

// これもキーの存在チェックのつもり...
if (!$val5) {
    echo "key5は存在しない";
}

那么,结果怎么样呢?

key4は存在しない
key5は存在しない

要阻止这种情况发生,只有使用严格比较运算符。

// 正しいキーの存在チェック
if ($val4 === false) {
    echo "key4は存在しない";
}

Laravel是一个原生的PHP框架。

好了,终于进入正题了。

在Laravel中,可以使用PhpRedis来访问Redis。

由于使用了PhpRedis,所以get()和mget()可能会返回false,但实际上返回的是null。

该原因可以在Illuminate\Redis\Connections\PhpRedisConnection.php文件中找到。

public function get($key)
{
    $result = $this->command('get', [$key]);

    return $result !== false ? $result : null;
}

public function mget(array $keys)
{
    return array_map(function ($value) {
        return $value !== false ? $value : null;
    }, $this->command('mget', [$keys]));
}

我们可以明显看出,它在专门检查获取的值是否为false,如果为false则返回null。

为什么要做这么麻烦的事情呢?

以前,由于使用PhpRedis返回false而导致缓存相关的错误发生。因此,似乎已经修改为返回null。

印象

仅使用Laravel访问Redis并使用PhpRedis,并不意味着会得到与PhpRedis相同的结果。

如果用一位開發者的評論來擬仿時,當修正錯誤時可能會這樣說:

我们使用 Laravel,而不是直接使用 PhpRedis。

那大概就是这样了吧。

请参考

    • Laravel 公式ドキュメント

Redis

PHP 公式ドキュメント

型の比較表

PhpRedis

Why does GET/MGET return false instead of null for non-existent keys?
同様の違和感を感じる人は多いみたいですが、破壊的変更になるため却下されたようです。

这个 Redis 的操作非常清晰,从松散的 PHP 类型系统中返回后感觉非常舒服(笑)
返回 null 本身并没有关系,但没有在文档中说明这一点让我有点不友好的感觉。如果被告知要看框架的源代码才能明白的话,那就算了吧…
广告
将在 10 秒后关闭
bannerAds