2

Is there some reliable way to find out whether a string variable is just a string or a string representation of a serialized object/array?

hakre
  • 193,403
  • 52
  • 435
  • 836
Richard Knop
  • 81,041
  • 149
  • 392
  • 552
  • possible duplicate of [PHP - Check to see if a string is serialized?](http://stackoverflow.com/questions/1369936/php-check-to-see-if-a-string-is-serialized) – karim79 Jan 20 '11 at 15:19

2 Answers2

7

You can call unserialize(string $str) function: it returns false, if string cannot be unserialized.

hakre
  • 193,403
  • 52
  • 435
  • 836
Kel
  • 7,680
  • 3
  • 29
  • 39
  • 1
    have fun: `PHP Warning: Class __PHP_Incomplete_Class has no unserializer in /root/hacked.php on line 5 object(__PHP_Incomplete_Class)#1 (1) { ["__PHP_Incomplete_Class_Name"]=> string(8) "Poreikis" }` – holms Jun 09 '13 at 23:03
  • Use an ampersand in front to suppress the error messages (ie. @unserialize) – Andrew May 05 '14 at 05:56
  • 1
    @Andrew `@` is not called ampersand. Ampersand is `&` – brettwhiteman Jan 13 '16 at 01:38
  • What if the string is `b:0;`? `unserialize` will return `false` but it is a valid serialized value. – brettwhiteman Jan 13 '16 at 01:41
  • Whoops! Thanks @developerbmw – Andrew Jan 13 '16 at 07:39
  • 1
    IMPORTANT: Never ever unserialize raw user data since it can be used as an attack vector. [OWASP:PHP_Object_Injection](https://www.owasp.org/index.php/PHP_Object_Injection) – ArtBIT Sep 01 '17 at 18:55
6

Well, you can tell by looking at the format. When you serialize an array, you get a string that looks like a:1:{i:0;s:3:"foo"} And if you serialize an object, you get: o:7:"myclass":1:{s:3:"foo";s:3:"bar";}.

So if you want to test rudimentary, you can do these two regexes:

^a:\d+:{.*?}$

And

^o:\d+:"[a-z0-9_]+":\d+:{.*?}$

for arrays and objects respectively.

Note that this just checks for the generic form. To tell if it's a valid serialized string, you need to run it through unserialize() and test the return is_array($result) and is_object($result)...

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
  • 2
    @andre: Yes, seriously. Sometimes you may not want to unserialize for several reasons (for example, if the class name is not defined, or if it's expensive, etc). It could be just a sanity check before storing the serialized string. There are lots of reasons. And if you know of a better one than regex without calling `unserialize`, I'm all ears... – ircmaxell Jan 20 '11 at 15:21
  • if your string is that big that unserialize might be an heavy operation, don't you think the regex match will also be expensive? Anyways, thanks for explaining you reasons. :-) – acm Jan 20 '11 at 16:01
  • 1
    @andre: it won't be nearly as expensive as the double-allocation of memory needed to unserialize (since you need to keep both the string and the new object/array in memory). Sure, it'll be somewhat slow to walk, but those regex's are fairly efficient, so I wouldn't worry too much about them (there's virtually no backtracking necessary)... But fair enough... – ircmaxell Jan 20 '11 at 16:18