2

given this code:

$array = array('1' => 'one',
               '2' => 'two',
               '3' => 'three');
$arrayObject = new ArrayObject($array);
$iterator = $arrayObject->getIterator();
echo serialize($iterator);

I get this string a soutput:

C:13:"ArrayIterator":111:{x:i:16777216;C:11:"ArrayObject":65:{x:i:0;a:3:{i:1;s:3:"one";i:2;s:3:"two";i:3;s:5:"three";};m:a:0:{}};m:a:0:{}}

Now, presuming that this is what I understand from the output:

  • C:13:"ArrayIterator" -> a Class which name length is 13 characters;
  • i:16777216; -> an int (i) which value is 16777216;
  • a:3:{i:1;s:3:"one";i:2;s:3:"two";i:3;s:5:"three";} -> an array of three elements, i:1 is the first num key, s:3:"one" is the value at that key, and so on...;
  • a:0{} -> an empty array;

My questions:

  • What are these bold/highlighted parts in the serialization:

C:13:"ArrayIterator":111:{x:i:16777216;C:11:"ArrayObject":65:{x:i:0;a:3:{i:1;s:3:"one";i:2;s:3:"two";i:3;s:5:"three";};m:a:0:{}};m:a:0:{}}

  • What are those "111" and "65" after "ArrayIterator" and "ArrayObject", respectively, what's their purpose?

  • What is the meaning of "x:i:16777216" and "x:i:0", I mean, I know i refers to an int, 16777216 and 0, respectively, but what about that x? What is it for?

  • What are those empty arrays prefixed with m (m:a:0:{}) inside ArrayObject and ArrayIterator? What's the purpose of the m?

Is there a complete reference or something which covers the topic a little bit deeper than the PHP manual, because I haven't found infos or examples on the PHP man page about such object serialization.

Thank you for the attention!

tonix
  • 6,671
  • 13
  • 75
  • 136
  • what version of php? i'm getting completely different output running your snippet. i get : O:11:"ArrayObject":3:{i:1;s:3:"one";i:2;s:3:"two";i:3;s:5:"three";} – AndreaBogazzi Jan 19 '15 at 09:34
  • Make a var_dump of your var before serializing it, to see what is inside it. so you can understand it better. You didn't extend the class , you run just that snippet right? – AndreaBogazzi Jan 19 '15 at 09:40
  • possible duplicate http://stackoverflow.com/questions/16419542/php-serialize-specification – bitWorking Jan 19 '15 at 09:41
  • @AndreaBogazzi, yes, I didn't extend the class, I just ran that snippet, I am using PHP 5.6.0, why outputs are different? – tonix Jan 19 '15 at 17:42
  • Anyway taht 11 and 65 i suspect are the lenght in char of the serialization, may it be? not present in php 5.3 and 5.4 i just checked. – AndreaBogazzi Jan 19 '15 at 18:07
  • @AndreaBogazzi You are right, they refer to the length of the serialization, but what about those `x:i:16777216`, `x:i:0`, `m:a:0:{}`, `m:a:0:{}`, what is their meaning? – tonix Jan 19 '15 at 19:38
  • 1
    i wrote you what i could find :) at least if you are really interested in finding out you have a start point. Move the array some position and serialize again, check if the "i" part change. – AndreaBogazzi Jan 20 '15 at 09:58
  • Sorry, what do you mean with `Move the array some position and serialize again, check if the "i" part change`, I mean, I have tried to do that, like this: `$iterator->next(); $iterator->next(); var_dump(serialize($iterator));` before serializing, but the "i" part didn't change. Does it changes for you? – tonix Jan 20 '15 at 10:22
  • 1
    i do not have php 5.6 i do not have those things in my serialization outpu. i have just what i wrote in first comment. – AndreaBogazzi Jan 20 '15 at 11:10
  • Understood, I'll give it a try to find it out myself, thank you! – tonix Jan 20 '15 at 17:25

1 Answers1

1

Luckily enough, i could find those x: and m: coupled with the string append, just in one point in the source code. I may be wrong but "x:" looks relative to the last index used in the array ( so in this case serialize is saving even the state of the classe ) "m:" is commented with members, i don't know what it may be.

You can study further at this link: http://lxr.php.net/xref/PHP_5_6/ext/spl/spl_array.c#1703

1676 /* {{{ proto string ArrayObject::serialize()
1677   Serialize the object */
1678 SPL_METHOD(Array, serialize)
1679 {
1680    zval *object = getThis();
1681    spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
1682    HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
1683    zval members, *pmembers;
1684    php_serialize_data_t var_hash;
1685    smart_str buf = {0};
1686    zval *flags;
1687
1688    if (zend_parse_parameters_none() == FAILURE) {
1689        return;
1690    }
1691
1692    if (!aht) {
1693        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and is no longer an array");
1694        return;
1695    }
1696
1697    PHP_VAR_SERIALIZE_INIT(var_hash);
1698
1699    MAKE_STD_ZVAL(flags);
1700    ZVAL_LONG(flags, (intern->ar_flags & SPL_ARRAY_CLONE_MASK));
1701
1702    /* storage */
1703    smart_str_appendl(&buf, "x:", 2);
1704    php_var_serialize(&buf, &flags, &var_hash TSRMLS_CC);
1705    zval_ptr_dtor(&flags);
1706
1707    if (!(intern->ar_flags & SPL_ARRAY_IS_SELF)) {
1708        php_var_serialize(&buf, &intern->array, &var_hash TSRMLS_CC);
1709        smart_str_appendc(&buf, ';');
1710    }
1711
1712    /* members */
1713    smart_str_appendl(&buf, "m:", 2);
1714    INIT_PZVAL(&members);
1715    if (!intern->std.properties) {
1716        rebuild_object_properties(&intern->std);
1717    }
1718    Z_ARRVAL(members) = intern->std.properties;
1719    Z_TYPE(members) = IS_ARRAY;
1720    pmembers = &members;
1721    php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */
1722
1723    /* done */
1724    PHP_VAR_SERIALIZE_DESTROY(var_hash);
1725
1726    if (buf.c) {
1727        RETURN_STRINGL(buf.c, buf.len, 0);
1728    }
1729
1730    RETURN_NULL();
1731 } /* }}} */
AndreaBogazzi
  • 14,323
  • 3
  • 38
  • 63