Overview

Namespaces

  • Rundiz
    • Serializer

Classes

  • Rundiz\Serializer\Serializer
  • Rundiz\Serializer\SerializerStatic
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /**
  3:  * Serializer class.
  4:  * 
  5:  * @package Number
  6:  * @version 1.0.1
  7:  * @author Vee W.
  8:  * @license http://opensource.org/licenses/MIT MIT
  9:  */
 10: 
 11: 
 12: namespace Rundiz\Serializer;
 13: 
 14: 
 15: /**
 16:  * Works with serialization such as check if string is serialized.
 17:  *
 18:  * @author Vee W.
 19:  * @since 1.0
 20:  */
 21: class Serializer
 22: {
 23: 
 24: 
 25:     /**
 26:      * Is serialized string.
 27:      * 
 28:      * @link https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/functions.php#L341 Reference from WordPress.
 29:      * @link https://gist.github.com/cs278/217091 Reference from Github cs278/is_serialized.php
 30:      * @param string $string The string to check.
 31:      * @return boolean Return true if serialized, false for otherwise.
 32:      */
 33:     public function isSerialized($string)
 34:     {
 35:         if (!is_string($string)) {
 36:             return false;
 37:         }
 38: 
 39:         $string = trim($string);
 40: 
 41:         if ($string === 'N;') {
 42:             // if serialized string is NULL.
 43:             return true;
 44:         }
 45: 
 46:         $string_encoding = mb_detect_encoding($string);
 47:         $length = mb_strlen($string, $string_encoding);
 48:         $last_char = mb_substr($string, -1, NULL, $string_encoding);
 49:         unset($string_encoding);
 50: 
 51:         if ($length < 4) {
 52:             // if total characters of this string (string length) is less than 4 then it is not serialized except NULL which is verified above.
 53:             unset($last_char, $length);
 54:             return false;
 55:         }
 56: 
 57:         if ($string[1] !== ':') {
 58:             // if character number 2 (offset 1, start at 0) from this string is not colon means it is not serialized string.
 59:             unset($last_char, $length);
 60:             return false;
 61:         }
 62: 
 63:         if (in_array($string[0], ['b', 'i', 'd', 's']) && $last_char !== ';') {
 64:             // if first character maybe boolean, integer, double or float, string but last character is not semicolon means it is not serialized string.
 65:             unset($last_char, $length);
 66:             return false;
 67:         } elseif (in_array($string[0], ['a', 'O']) && $last_char !== '}') {
 68:             // last character of array, object is not right curly bracket means it is not serialized string.
 69:             unset($last_char, $length);
 70:             return false;
 71:         }
 72: 
 73:         // switch to first character of this string.
 74:         switch ($string[0]) {
 75:             case 'b':
 76:                 // this maybe boolean
 77:                 if ($length > 4 || ($string[2] !== '0' && $string[2] !== '1')) {
 78:                     // if string length is more than 4 or character number 3 (offset 2) is not 0 (false) and is not 1 (true) means it is not serialized string.
 79:                     return false;
 80:                 } elseif ($length == 4 && ($string[2] === '0' || $string[2] === '1')) {
 81:                     // if string length is exactly 4 and character number 3 (offset 2) is 0 (false) or 1 (true) means it is serialized string.
 82:                     return true;
 83:                 } else {
 84:                     return false;
 85:                 }
 86:             case 'i':
 87:                 // this maybe integer
 88:                 return (boolean) preg_match('#^'.$string[0].':[0-9\-]+\\'.$last_char.'#', $string);
 89:             case 'd':
 90:                 // this maybe double or float
 91:                 return (boolean) preg_match('#^'.$string[0].':[0-9\.E\-\+]+\\'.$last_char.'#', $string);
 92:             case 's':
 93:                 // this maybe string
 94:                 $exp_string = explode(':', $string);
 95:                 if (isset($exp_string[1]) && isset($exp_string[2])) {
 96:                     // if found number of total characters in serialize, count to make sure that it is matched.
 97:                     unset($last_char, $length);
 98:                     // number in serialized string type seems to use `strlen` because it is not counting the real unicode characters.
 99:                     return (intval($exp_string[1]) === intval(strlen(trim($exp_string[2], ';"'))));
100:                 }
101:                 unset($exp_string, $last_char, $length);
102:                 return false;
103:             case 'a':
104:                 // this maybe array
105:             case 'O':
106:                 // this maybe object
107:                 return (boolean) preg_match('#^'.$string[0].':[0-9]+\:#s', $string);
108:         }// endswitch;
109: 
110:         return false;
111:     }// isSerialized
112: 
113: 
114:     /**
115:      * Check first that data is serialized or not, if not then serialize it otherwise return as is.
116:      * 
117:      * @param mixed $value The data to be serialize.
118:      * @return string Return serialized string.
119:      */
120:     public function maybeSerialize($value)
121:     {
122:         if ($this->isSerialized($value) === true) {
123:             return $value;
124:         }
125:         return @serialize($value);
126:     }// maybeSerialize
127: 
128: 
129:     /**
130:      * Check first that data is serialized or not, if yes then unserialize it otherwise return as is.
131:      * 
132:      * @since 1.0.1
133:      * @param mixed $value The data to be unserialize.
134:      * @return mixed Return unserialized value.
135:      */
136:     public function maybeUnserialize($value)
137:     {
138:         if ($this->isSerialized($value) === false) {
139:             return $value;
140:         }
141:         return @unserialize($value);
142:     }// maybeUnserialize
143: 
144: 
145: }
API documentation generated by ApiGen