Overview

Packages

  • Serialize

Classes

  • Horde_Serialize
  • Horde_Serialize_Exception
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Serialize:: class provides various methods of encapsulating data.
  4:  *
  5:  * Copyright 2001-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (LGPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  9:  *
 10:  * @author   Stephane Huther <shuther1@free.fr>
 11:  * @author   Michael Slusarz <slusarz@horde.org>
 12:  * @package  Serialize
 13:  * @category Horde
 14:  */
 15: class Horde_Serialize
 16: {
 17:     /* Type constants */
 18:     const UNKNOWN = -1;
 19:     const NONE = 0;
 20:     const WDDX = 1;
 21:     const BZIP = 2;
 22:     const IMAP8 = 3;
 23:     const IMAPUTF7 = 4;
 24:     const IMAPUTF8 = 5;
 25:     const BASIC = 6;
 26:     const GZ_DEFLATE = 7;
 27:     const GZ_COMPRESS = 8;
 28:     const GZ_ENCODE = 9;
 29:     const BASE64 = 10;
 30:     const RAW = 12;
 31:     const URL = 13;
 32:     const UTF7 = 14;
 33:     const UTF7_BASIC = 15;
 34:     const JSON = 16;
 35:     const LZF = 17;
 36: 
 37:     /**
 38:      * Serialize a value.
 39:      *
 40:      * See the list of constants at the top of the file for the serializing
 41:      * techniques that can be used.
 42:      *
 43:      * @param mixed $data    The data to be serialized.
 44:      * @param mixed $mode    The mode of serialization. Can be either a single
 45:      *                       mode or array of modes.  If array, will be
 46:      *                       serialized in the order provided.
 47:      * @param mixed $params  Any additional parameters the serialization method
 48:      *                       requires.
 49:      *
 50:      * @return string  The serialized data.
 51:      * @throws Horde_Serialize_Exception
 52:      */
 53:     static public function serialize($data, $mode = array(self::BASIC),
 54:                                      $params = null)
 55:     {
 56:         if (!is_array($mode)) {
 57:             $mode = array($mode);
 58:         }
 59: 
 60:         /* Parse through the list of serializing modes. */
 61:         foreach ($mode as $val) {
 62:             /* Check to make sure the mode is supported. */
 63:             if (!self::hasCapability($val)) {
 64:                 throw new Horde_Serialize_Exception('Unsupported serialization type');
 65:             }
 66:             $data = self::_serialize($data, $val, $params);
 67:         }
 68: 
 69:         return $data;
 70:     }
 71: 
 72:     /**
 73:      * Unserialize a value.
 74:      *
 75:      * See the list of constants at the top of the file for the serializing
 76:      * techniques that can be used.
 77:      *
 78:      * @param mixed $data    The data to be unserialized.
 79:      * @param mixed $mode    The mode of unserialization.  Can be either a
 80:      *                       single mode or array of modes.  If array, will be
 81:      *                       unserialized in the order provided.
 82:      * @param mixed $params  Any additional parameters the unserialization
 83:      *                       method requires.
 84:      *
 85:      * @return string  The unserialized data.
 86:      * @throws Horde_Serialize_Exception
 87:      */
 88:     static public function unserialize($data, $mode = self::BASIC,
 89:                                        $params = null)
 90:     {
 91:         if (!is_array($mode)) {
 92:             $mode = array($mode);
 93:         }
 94: 
 95:         /* Parse through the list of unserializing modes. */
 96:         foreach ($mode as $val) {
 97:             /* Check to make sure the mode is supported. */
 98:             if (!self::hasCapability($val)) {
 99:                 throw new Horde_Serialize_Exception('Unsupported unserialization type');
100:             }
101:             $data = self::_unserialize($data, $val, $params);
102:         }
103: 
104:         return $data;
105:     }
106: 
107:     /**
108:      * Check whether or not a serialization method is supported.
109:      *
110:      * @param integer $mode  The serialization method.
111:      *
112:      * @return boolean  True if supported, false if not.
113:      */
114:     static public function hasCapability($mode)
115:     {
116:         switch ($mode) {
117:         case self::BZIP:
118:             return Horde_Util::extensionExists('bz2');
119: 
120:         case self::WDDX:
121:             return Horde_Util::extensionExists('wddx');
122: 
123:         case self::IMAPUTF7:
124:             return class_exists('Horde_Imap_Client');
125: 
126:         case self::IMAP8:
127:         case self::IMAPUTF8:
128:             return class_exists('Horde_Mime');
129: 
130:         case self::GZ_DEFLATE:
131:         case self::GZ_COMPRESS:
132:         case self::GZ_ENCODE:
133:             return Horde_Util::extensionExists('zlib');
134: 
135:         case self::LZF:
136:             return Horde_Util::extensionExists('lzf');
137: 
138:         case self::NONE:
139:         case self::BASIC:
140:         case self::BASE64:
141:         case self::RAW:
142:         case self::URL:
143:         case self::UTF7:
144:         case self::UTF7_BASIC:
145:         case self::JSON:
146:             return true;
147: 
148:         default:
149:             return false;
150:         }
151:     }
152: 
153:     /**
154:      * Serialize data.
155:      *
156:      * @param mixed $data    The data to be serialized.
157:      * @param mixed $mode    The mode of serialization. Can be
158:      *                       either a single mode or array of modes.
159:      *                       If array, will be serialized in the
160:      *                       order provided.
161:      * @param mixed $params  Any additional parameters the serialization method
162:      *                       requires.
163:      *
164:      * @return string  A serialized string.
165:      * @throws Horde_Serialize_Exception
166:      */
167:     static protected function _serialize($data, $mode, $params = null)
168:     {
169:         switch ($mode) {
170:         case self::NONE:
171:             break;
172: 
173:         // $params['level'] = Level of compression (default: 3)
174:         // $params['workfactor'] = How does compression phase behave when given
175:         //                         worst case, highly repetitive, input data
176:         //                         (default: 30)
177:         case self::BZIP:
178:             $data = bzcompress($data, isset($params['level']) ? $params['level'] : 3, isset($params['workfactor']) ? $params['workfactor'] : 30);
179:             if (is_integer($data)) {
180:                 $data = false;
181:             }
182:             break;
183: 
184:         case self::WDDX:
185:             $data = wddx_serialize_value($data);
186:             break;
187: 
188:         case self::IMAP8:
189:             $data = Horde_Mime::quotedPrintableEncode($data);
190:             break;
191: 
192:         case self::IMAPUTF7:
193:             $data = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap(Horde_String::convertCharset($data, 'ISO-8859-1', 'UTF-8'));
194:             break;
195: 
196:         case self::IMAPUTF8:
197:             $data = Horde_Mime::decode($data, 'UTF-8');
198:             break;
199: 
200:         // $params['level'] = Level of compression (default: 3)
201:         case self::GZ_DEFLATE:
202:             $data = gzdeflate($data, isset($params['level']) ? $params['level'] : 3);
203:             break;
204: 
205:         case self::BASIC:
206:             $data = serialize($data);
207:             break;
208: 
209:         // $params['level'] = Level of compression (default: 3)
210:         case self::GZ_COMPRESS:
211:             $data = gzcompress($data, isset($params['level']) ? $params['level'] : 3);
212:             break;
213: 
214:         case self::BASE64:
215:             $data = base64_encode($data);
216:             break;
217: 
218:         // $params['level'] = Level of compression (default: 3)
219:         case self::GZ_ENCODE:
220:             $data = gzencode($data, isset($params['level']) ? $params['level'] : 3);
221:             break;
222: 
223:         case self::RAW:
224:             $data = rawurlencode($data);
225:             break;
226: 
227:         case self::URL:
228:             $data = urlencode($data);
229:             break;
230: 
231:         // $params = Source character set
232:         case self::UTF7:
233:             $data = Horde_String::convertCharset($data, $params, 'UTF-7');
234:             break;
235: 
236:         // $params = Source character set
237:         case self::UTF7_BASIC:
238:             $data = self::serialize($data, array(self::UTF7, self::BASIC), $params);
239:             break;
240: 
241:         case self::JSON:
242:             $tmp = json_encode($data);
243: 
244:             /* Basic error handling attempts. Requires PHP 5.3+.
245:              * Error code 5, although not documented, indicates non UTF-8
246:              * data. */
247:             if (function_exists('json_last_error') &&
248:                 (json_last_error() == 5)) {
249:                 $data = json_encode(Horde_String::convertCharset($data, $params, 'UTF-8', true));
250:             } else {
251:                 $data = $tmp;
252:             }
253:             break;
254: 
255:         case self::LZF:
256:             $data = lzf_compress($data);
257:             break;
258:         }
259: 
260:         if ($data === false) {
261:             throw new Horde_Serialize_Exception('Serialization failed.');
262:         }
263:         return $data;
264:     }
265: 
266:     /**
267:      * Unserialize data.
268:      *
269:      * @param mixed $data    The data to be unserialized.
270:      * @param mixed $mode    The mode of unserialization. Can be either a
271:      *                       single mode or array of modes.  If array, will be
272:      *                       unserialized in the order provided.
273:      * @param mixed $params  Any additional parameters the unserialization
274:      *                       method requires.
275:      *
276:      * @return mixed  Unserialized data.
277:      * @throws Horde_Serialize_Exception
278:      */
279:     static protected function _unserialize(&$data, $mode, $params = null)
280:     {
281:         switch ($mode) {
282:         case self::NONE:
283:             break;
284: 
285:         case self::RAW:
286:             $data = rawurldecode($data);
287:             break;
288: 
289:         case self::URL:
290:             $data = urldecode($data);
291:             break;
292: 
293:         case self::WDDX:
294:             $data = wddx_deserialize($data);
295:             break;
296: 
297:         case self::BZIP:
298:             // $params['small'] = Use bzip2 'small memory' mode?
299:             $data = bzdecompress($data, isset($params['small']) ? $params['small'] : false);
300:             break;
301: 
302:         case self::IMAP8:
303:             $data = quoted_printable_decode($data);
304:             break;
305: 
306:         case self::IMAPUTF7:
307:             $data = Horde_String::convertCharset(Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($data), 'UTF-8', 'ISO-8859-1');
308:             break;
309: 
310:         case self::IMAPUTF8:
311:             $data = Horde_Mime::encode($data, 'UTF-8');
312:             break;
313: 
314:         case self::BASIC:
315:             $data2 = @unserialize($data);
316:             // Unserialize can return false both on error and if $data is the
317:             // false value.
318:             if (($data2 === false) && ($data == serialize(false))) {
319:                 return $data2;
320:             }
321:             $data = $data2;
322:             break;
323: 
324:         case self::GZ_DEFLATE:
325:             $data = gzinflate($data);
326:             break;
327: 
328:         case self::BASE64:
329:             $data = base64_decode($data);
330:             break;
331: 
332:         case self::GZ_COMPRESS:
333:             $data = gzuncompress($data);
334:             break;
335: 
336:         // $params = Output character set
337:         case self::UTF7:
338:             $data = Horde_String::convertCharset($data, 'utf-7', $params);
339:             break;
340: 
341:         // $params = Output character set
342:         case self::UTF7_BASIC:
343:             $data = self::unserialize($data, array(self::BASIC, self::UTF7), $params);
344:             break;
345: 
346:         case self::JSON:
347:             $out = json_decode($data);
348:             if (!is_null($out) || (strcasecmp($data, 'null') === 0)) {
349:                 return $out;
350:             }
351:             break;
352: 
353:         case self::LZF:
354:             $data = @lzf_decompress($data);
355:             break;
356:         }
357: 
358:         if ($data === false) {
359:             throw new Horde_Serialize_Exception('Unserialization failed.');
360:         }
361: 
362:         return $data;
363:     }
364: 
365: }
366: 
API documentation generated by ApiGen