使用plpgsql序列化/反序列化

时间:2015-03-25 13:39:02

标签: php postgresql serialization deserialization plpgsql

我想使用plpgsql来执行php序列化字符串或数组的序列化和反序列化。

有人可以告诉我,如果有人之前尝试过这个吗?

这个功能的链接非常感谢!

2 个答案:

答案 0 :(得分:1)

我参加派对有点晚了,但是我创建了一个postgresql函数来实现这个目的:

https://gist.github.com/storeman/cecb10bab249f43562cddabc1d9dd7c9

/**
Decode a php serialized value to json. This function only supports basic 
data types:
- arrays (will always become a json object)
- booleans
- integers
- floats
- strings
- NULL

The php_unserialize(text) function is a helper function which extracts the first value
found in the string and returns a ROW( vartype, varval, serializedlength)

The php_unserialize_to_json(text) function returns the json value extracted from
the serialized string. 

Examples:
SELECT php_unserialize_to_json('a:5:{i:0;d:1;s:1:"k";a:3:{i:0;s:1:"a";i:1;s:1:"b";s:3:"sub";a:3:{i:0;s:1:"a";i:1;s:1:"b";i:2;s:1:"c";}}i:1;N;i:2;b:1;i:3;b:0;}')#>>'{k,sub,2}';
SELECT php_unserialize_to_json('s:8:"a string";');
SELECT php_unserialize_to_json('s:0:"";');
SELECT php_unserialize_to_json('i:1337;');
SELECT php_unserialize_to_json('d:1.234;');
SELECT php_unserialize_to_json('b:1;')::TEXT;
SELECT php_unserialize_to_json('b:0;')::TEXT;
SELECT php_unserialize_to_json('N;')::TEXT;
SELECT php_unserialize_to_json('a:0:{}')::TEXT;
SELECT php_unserialize_to_json('a:1:{i:0;s:5:"array";}')::TEXT;

SELECT php_unserialize_to_json('a:1:{i:0;i:1;}')::TEXT;
SELECT php_unserialize_to_json('a:2:{i:0;i:1;i:1;s:1:"b";}')::TEXT;
SELECT php_unserialize_to_json('a:2:{i:0;d:1;s:1:"k";s:1:"b";}')::TEXT;
SELECT php_unserialize_to_json('a:2:{i:0;d:1;s:1:"k";a:2:{i:0;s:1:"a";i:1;s:1:"b";}}')::TEXT;
*/

---
--- This function is the helper function
---

CREATE OR REPLACE FUNCTION php_unserialize(str text)
  RETURNS json AS
$BODY$
DECLARE
  vartype CHAR;
  varlength INT;
  jsonstr TEXT;
  varcount INT;
  jsonval JSONB;
  arrkey JSON;
  arrval JSON;
  -- String length of the serialized data
  serialized_string_length INT;
BEGIN
  CASE substring(str, 1, 1)
    WHEN 'a' THEN -- array
      -- init object
      jsonval := '{}'::jsonb;

      -- remove the "a" and ":" characters
      str := substring(str, 3);

      -- Detect number of values in array
      varlength := substring(str, 1, position(':' IN str) - 1)::INT;

      -- Base size of array is 5 (a:[size]:{})
      serialized_string_length := 5 + char_length(varlength::TEXT);

      -- If no values, return empty object, as this always returns objects
      IF varlength = 0 THEN 
    return json_build_array('array', jsonval, serialized_var_size)::JSON;
      END IF;

      -- remove the array size and ":{"
      str := substring(str, char_length(varlength::TEXT) + 3);

      -- Find the number of variables specified
      FOR varcount IN 1 .. varlength LOOP
    -- Find the value of the key and remove it from base string
    arrkey := php_unserialize(str);
    str := substring(str, (arrkey->>2)::INT + 1);

    -- Find the value of the value and remove it from base string
    arrval := php_unserialize(str);
    str := substring(str, (arrval->>2)::INT + 1);

    serialized_string_length := serialized_string_length + (arrkey->>2)::INT + (arrval->>2)::INT;

    -- Append value
    jsonval := jsonval || jsonb_build_object(arrkey->>1, arrval->1);
      END LOOP;

      return json_build_array('array', jsonval, serialized_string_length);
    WHEN 'b' THEN -- boolean
      return json_build_array('bool',(CASE substring(str, 3, 1) WHEN '1' THEN TRUE ELSE FALSE END)::TEXT, 4);
    WHEN 'd' THEN -- float
      return json_build_array('float', substring(str, 3, position(';' IN str) - 3)::TEXT, position(';' IN str));
    WHEN 'i' THEN -- int
      return json_build_array('int', substring(str, 3, position(';' IN str) - 3)::TEXT, position(';' IN str));
    WHEN 'N' THEN -- null
      return json_build_array('null', 'null'::TEXT, 2);
    WHEN 's' THEN -- string
      varlength := substring(str, 3, position(':' IN str) - 1)::INT;

      return json_build_array('string', substring(str, char_length(varlength::TEXT) + 5, varlength)::TEXT, position(';' IN str));
    ELSE
      RAISE EXCEPTION 'Unable to decode serialized value, unsupported type: %', substr(str, 1, 1);
  END CASE;
END;
$BODY$
  LANGUAGE plpgsql IMMUTABLE
  COST 10;

---
--- The main function
---
CREATE OR REPLACE FUNCTION php_unserialize_to_json(str text)
  RETURNS json AS
$BODY$
DECLARE
  varlength INT;
BEGIN
  CASE substring(str, 1, 1)
    WHEN 'a' THEN
      return php_unserialize(str)->1;
    WHEN 'b' THEN
      return php_unserialize(str)->1;
    WHEN 'd' THEN
      return php_unserialize(str)->1;
    WHEN 'i' THEN
      return php_unserialize(str)->1;
    WHEN 'N' THEN
      return php_unserialize(str)->1;
    WHEN 's' THEN
      return php_unserialize(str)->1;
    ELSE
      RETURN NULL;
  END CASE;
END;
$BODY$
  LANGUAGE plpgsql IMMUTABLE
  COST 10;

答案 1 :(得分:0)

postgre不存在专用的PHP函数Serialize / Unserialize。看看:PostgreSQL Functions

至于数据库是唯一的可能性json,但它没有在PHP中支持postgres。有关这方面的更多信息:JSON Functions and Operators

我的解决方案:

我在PHP中使用了serializeunserialize

$array = array('t1' => 1,'t2' => 2,'t3' => 3,'t4' => 4);

$arraySerialize = serialize($array);

print_r($arraySerialize); //a:4:{s:2:"t1";i:1;s:2:"t2";i:2;s:2:"t3";i:3;s:2:"t4";i:4;}
  1. 将$ arraySerialize保存在text

  2. 类型的数据库列中
  3. 从数据库中获取$ arraySerialize并解压缩($ stringUnserialize)

    $ stringUnserialize = unserialize($ arraySerialize); //数组([t1] => 1 [t2] => 2 [t3] => 3 [t4] => 4)