Php-redis - Is there a way to save a PHP object in Redis without serializing it?

I am trying to save the user url as a key and the PHP object corresponding to that key as a value in Redis. I tried the following:

$redisClient = new Redis(); $redisClient->connect('localhost', 6379); $redisClient->set($_SERVER['REQUEST_URI'], $this->page); $redisTest = $redisClient->get($_SERVER['REQUEST_URI']); var_dump($redisTest); 

However, with this code, the URL key value that is stored in Redis is a string type with a value of "Object" and not the actual PHP object. Is there a way to save a PHP object without serializing it?

+6
source share
4 answers

As you can see in Redis data types , Redis only supports these 5 data types:

  • Stirng
  • List
  • Set
  • Hash
  • Sorted Set

So, there is no data type of the object, and therefore you cannot store the object directly as a value. You must first serialize (or JSON-encode it using the json_encode function, for example).

Is there a problem with serialization that you insist on saving your objects directly?

Update: According to what you said in the comments, you can use the approach specified in this,

So you can use:

 $xml = $simpleXmlElem->asXML(); 

before serializing and then after unserialize() use the following code:

 $simpleXmlElem = simplexml_load_string($xml); 

This way you do not need to serialize the embedded PHP object like SimpleXmlElement , and there will be no problems.

+5
source

Serialization will be the easiest way.

An alternative is json_encode only the parameters needed to restore the object later. One way to do this is to use the PHP 5.4 JsonSerialize interface. You want to extract various properties using jsonSerialize, and then provide a means to return them to your class when you pull an element from Redis.


 class MyPage implements JsonSerializable { protected $p1; protected $p2; /** * @param mixed $p1 */ public function setP1($p1) { $this->p1 = $p1; } /** * @param mixed $p2 */ public function setP2($p2) { $this->p2 = $p2; } /** * (PHP 5 &gt;= 5.4.0)<br/> * Specify data which should be serialized to JSON * @link http://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by <b>json_encode</b>, * which is a value of any type other than a resource. */ public function jsonSerialize() { return [ 'p1' => $this->p1, 'p2' => $this->p2, ]; } } 

This way you can easily restore JSON. You can add a helper method for this or just call setters.

+2
source

Here is how I do it:

 class Cache extends Predis\Client { protected $prefix = 'myapp:'; public function take($key, $value = null, $ttl = null) { $value = is_object($value) ? serialize($value) : $value; $key = $this->prefix . $key; if (!$this->exists($key)) { if (intval($ttl)) { $this->setEx($key, $ttl, $value); } else { $this->set($key, $value); } } return $this->get($key); } } 

Using:

 $cache = new Cache; $lorem = 'Lorem ipsum dolor sit amet'; $loremLong = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; $cachedLorem = $cache->take('lorem', $lorem); $cachedLoremLong = $cache->take('loremLong', $loremLong); $cachedLoremTtl = $cache->take('loremTtl', $lorem, 30); $cachedLoremGet = $cache->take('lorem'); $cachedLoremObject = $cache->take('loremObject', new stdClass); $cachedLoremObjectTtl = $cache->take('loremObjectTtl', new stdClass, 45); echo $cachedLorem; echo $cachedLoremLong; echo $cachedLoremTtl; echo $cachedLoremGet; echo $cachedLoremObject; echo $cachedLoremObjectTtl; 

Output:

 Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet O:8:"stdClass":0:{} O:8:"stdClass":0:{} 
0
source

Adding to Aliweb is responsible!

Redis supports integers, as well as actions such as INCR, INCRBY, DECR, and DECRBY.

Regarding the question:

Serialize only if not String or Int. Serialization is an expensive operation!

in GET and HGET try to figure out what if it is serialized:

 private function string_unserialize($str){ $data = @unserialize($str); if ($str === 'b:0;'){ return 0; }elseif($data !== false){ return $data; }else { return $str; } } 

0
source

Source: https://habr.com/ru/post/977667/


All Articles