lua获取php返回值,Lua中实现php序列化及反序列化函数

--[[ @file Lua port of PHP serialization functions. Port based on PHPSerialize and PHPUnserialize by Scott Hurring http://hurring.com/scott/code/python/serialize/v0.4 @version v0.1 BETA @author Fernando P. García; fernando at develcuy dot com @copyright Copyright (c) 2009 Fernando P. García @license http://opensource.org/licenses/gpl-license.php GNU Public License $Id$ ]] local _serialize_key, _read_chars, _read_until, _unknown_type function _serialize_key(data) --[[ Serialize a key, which follows different rules than when serializing values. Many thanks to Todd DeLuca for pointing out that keys are serialized differently than values! From http://us2.php.net/manual/en/language.types.array.php A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as int 8, while "08" will be interpreted as "08"). Floats in key are truncated to integer. ]] -- Integer, Long, Float if type(data) == 'number' then return 'i:' .. tonumber(data) .. ';' -- Boolean => integer elseif type(data) == 'boolean' then if data then return 'i:1;' else return 'i:0;' end -- String => string or String => int (if string looks like int) elseif type(data) == 'string' then if tonumber(data) == nil then return 's:' .. string.len(data) .. ':"' .. data .. '";' else return 'i:' .. tonumber(data) .. ';' end -- None / NULL => empty string elseif type(data) == 'nil' then return 's:0:"";' -- I dont know how to serialize this else error('Unknown / Unhandled key type (' .. type(data) .. ')!') end end function serialize(data) --[[ Serialize a value. ]] local i, out, key, value -- Numbers if type(data) == 'number' then -- Integer => integer if math.floor(data) == data then return 'i:' .. data .. ';' -- Float, Long => double else return 'd:' .. data .. ';' end -- String => string or String => int (if string looks like int) -- Thanks to Todd DeLuca for noticing that PHP strings that -- look like integers are serialized as ints by PHP elseif type(data) == 'string' then if tonumber(data) == nil then return 's:' .. string.len(data) .. ':"' .. data .. '";' else return 'i:' .. tonumber(data) .. ';' end -- Nil / NULL elseif type(data) == 'nil' then return 'N;' -- Tuple and List => array -- The 'a' array type is the only kind of list supported by PHP. -- array keys are automagically numbered up from 0 elseif type(data) == 'table' then i = 0 out = {} -- All arrays must have keys for key, value in pairs(data) do table.insert(out, _serialize_key(key)) table.insert(out, serialize(value)) i = i + 1 end return 'a:' .. i .. ':{' .. table.concat(out) .. '}' -- Boolean => bool elseif type(data) == 'boolean' then if data then return 'b:1;' else return 'b:0;' end --~ TODO: --~ -- Table + Functions => stdClass --~ elseif type(data) == 'function' then --~ # I dont know how to serialize this else error('Unknown / Unhandled data type (' .. type(data) .. ')!') end end function _read_until(data, offset, stopchar) --[[ Read from data[offset] until you encounter some char 'stopchar'. ]] local buf = {} local char = string.sub(data, offset + 1, offset + 1) local i = 2 while not (char == stopchar) do -- Consumed all the characters and havent found ';' if i + offset > string.len(data) then error('Invalid') end table.insert(buf, char) char = string.sub(data, offset + i, offset + i) i = i + 1 end -- (chars_read, data) return i - 2, table.concat(buf) end function _read_chars(data, offset, length) --[[ Read 'length' number of chars from data[offset]. ]] local buf = {}, char -- Account for the starting quote char -- offset += 1 for i = 0, length -1 do char = string.sub(data, offset + i, offset + i) table.insert(buf, char) end -- (chars_read, data) return length, table.concat(buf) end function unserialize(data, offset) offset = offset or 0 --[[ Find the next token and unserialize it. Recurse on array. offset = raw offset from start of data --]] local buf, dtype, dataoffset, typeconvert, datalength, chars, readdata, i, key, value, keys, properties, otchars, otype, property buf = {} dtype = string.lower(string.sub(data, offset + 1, offset + 1)) -- 't:' = 2 chars dataoffset = offset + 2 typeconvert = function(x) return x end datalength = 0 chars = datalength -- int or double => Number if dtype == 'i' or dtype == 'd' then typeconvert = function(x) return tonumber(x) end chars, readdata = _read_until(data, dataoffset, ';') -- +1 for end semicolon dataoffset = dataoffset + chars + 1 -- bool => Boolean elseif dtype == 'b' then typeconvert = function(x) return tonumber(x) == 1 end chars, readdata = _read_until(data, dataoffset, ';') -- +1 for end semicolon dataoffset = dataoffset + chars + 1 -- n => None elseif dtype == 'n' then readdata = nil -- s => String elseif dtype == 's' then chars, stringlength = _read_until(data, dataoffset, ':') -- +2 for colons around length field dataoffset = dataoffset + chars + 2 -- +1 for start quote chars, readdata = _read_chars(data, dataoffset + 1, tonumber(stringlength)) -- +2 for endquote semicolon dataoffset = dataoffset + chars + 2 --[[ TODO review original: if chars != int(stringlength) != int(readdata): ]] if not (chars == tonumber(stringlength)) then error('String length mismatch') end -- array => Table -- If you originally serialized a Tuple or List, it will -- be unserialized as a Dict. PHP doesn't have tuples or lists, -- only arrays - so everything has to get converted into an array -- when serializing and the original type of the array is lost elseif dtype == 'a' then readdata = {} -- How many keys does this list have? chars, keys = _read_until(data, dataoffset, ':') -- +2 for colons around length field dataoffset = dataoffset + chars + 2 -- Loop through and fetch this number of key/value pairs for i = 0, tonumber(keys) - 1 do -- Read the key key, ktype, kchars = unserialize(data, dataoffset) dataoffset = dataoffset + kchars -- Read value of the key value, vtype, vchars = unserialize(data, dataoffset) -- Cound ending bracket of nested array if vtype == 'a' then vchars = vchars + 1 end dataoffset = dataoffset + vchars -- Set the list element readdata[key] = value end -- object => Table elseif dtype == 'o' then readdata = {} -- How log is the type of this object? chars, otchars = _read_until(data, dataoffset, ':') dataoffset = dataoffset + chars + 2 -- Which type is this object? otype = string.sub(data, dataoffset + 1, dataoffset + otchars) dataoffset = dataoffset + otchars + 2 if otype == 'stdClass' then -- How many properties does this list have? chars, properties = _read_until(data, dataoffset, ':') -- +2 for colons around length field dataoffset = dataoffset + chars + 2 -- Loop through and fetch this number of key/value pairs for i = 0, tonumber(properties) - 1 do -- Read the key property, ktype, kchars = unserialize(data, dataoffset) dataoffset = dataoffset + kchars -- Read value of the key value, vtype, vchars = unserialize(data, dataoffset) -- Cound ending bracket of nested array if vtype == 'a' then vchars = vchars + 1 end dataoffset = dataoffset + vchars -- Set the list element readdata[property] = value end else _unknown_type(dtype) end else _unknown_type(dtype) end --~ return (dtype, dataoffset-offset, typeconvert(readdata)) return typeconvert(readdata), dtype, dataoffset - offset end -- I don't know how to unserialize this function _unknown_type(type_) error('Unknown / Unhandled data type (' .. type_ .. ')!', 2) end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值