能否通过Redis在PHP/Laravel与Python间直接共享日期时间?
跨Laravel(phpredis)和Python共享Redis中的日期时间类型数据
当然可以实现,但默认的JSON序列化方式会把DateTime对象转成字符串,没法直接还原成对应语言的日期时间对象——得做一点额外处理来保证两边都能拿到可用的日期时间类型数据。
为什么默认不行?
Laravel Eloquent模型里的DateTime对象,经过json_encode后会被序列化为字符串(比如默认是ISO8601格式,或者你通过模型$casts指定的格式)。Python从Redis读取后得到的只是普通字符串,不是datetime对象,所以没法直接当作日期类型使用。
解决方案:统一序列化格式,反序列化时转换
下面是两种最常用的实现方式:
方式1:使用Unix时间戳(最简单直接)
这种方式不需要担心时区问题,两边转换都很方便。
Laravel端存储数据:
// 从数据库查询数据后,将DateTime转成Unix时间戳 $data = MyModel::where('start_date','>', "2018-05-02 10:00:00") ->get() ->map(function($item) { $item->start_date = $item->start_date->getTimestamp(); return $item; }) ->toArray(); // 存入Redis Redis::set("barChannel", json_encode($data));
Python端读取并转换:
import redis import json from datetime import datetime myredis = redis.Redis() raw_data = myredis.get('barChannel') if raw_data: data = json.loads(raw_data) # 遍历数据,将时间戳转成datetime对象 for item in data: item['start_date'] = datetime.fromtimestamp(item['start_date'])
方式2:使用标准日期字符串(可读性更强)
如果需要保留日期的可读格式,可以用ISO8601或者自定义的标准格式。
Laravel端存储数据:
可以利用Laravel模型的$casts属性自动转换日期格式:
class MyModel extends Model { // 自动将start_date字段转为DateTime对象,序列化时转成指定格式的字符串 protected $casts = [ 'start_date' => 'datetime:Y-m-d H:i:s', ]; } // 查询并转成数组后直接序列化 $data = MyModel::where('start_date','>', "2018-05-02 10:00:00")->get()->toArray(); Redis::set("barChannel", json_encode($data));
Python端读取并转换:
import redis import json from datetime import datetime myredis = redis.Redis() raw_data = myredis.get('barChannel') if raw_data: data = json.loads(raw_data) # 按Laravel指定的格式解析字符串为datetime对象 for item in data: item['start_date'] = datetime.strptime(item['start_date'], '%Y-%m-%d %H:%M:%S') # 如果用的是ISO8601格式,可以更简洁:datetime.fromisoformat(item['start_date'])
进阶方式:标记字段类型(扩展性更好)
如果需要处理多种特殊类型(不止日期),可以在序列化时给字段加上类型标记,反序列化时根据标记处理:
Laravel端存储:
$data = MyModel::where('start_date','>', "2018-05-02 10:00:00") ->get() ->map(function($item) { return [ 'id' => $item->id, 'start_date' => [ 'type' => 'datetime', 'value' => $item->start_date->format('Y-m-d H:i:s') ], 'name' => $item->name ]; }) ->toArray(); Redis::set("barChannel", json_encode($data));
Python端读取:
import redis import json from datetime import datetime myredis = redis.Redis() raw_data = myredis.get('barChannel') if raw_data: data = json.loads(raw_data) for item in data: date_info = item['start_date'] if date_info['type'] == 'datetime': item['start_date'] = datetime.strptime(date_info['value'], '%Y-%m-%d %H:%M:%S')
总结
本质上我们没法直接在PHP和Python之间传递日期时间对象,但通过统一序列化格式(时间戳/标准字符串),再在各自语言中反序列化为对应的日期类型,就能实现“共享日期时间类型数据”的效果。根据你的需求选择合适的方式即可~
内容的提问来源于stack exchange,提问作者Sebastien D
相关产品推荐
相关产品推荐

