title: PHP Serialized Object Explanation
body: <p>My project communicates with an API that returns a string with a PHP serialized object. Normally, the response is a serialized array &amp; there's no issue unserializing it. However, we just encountered an endpoint where it returns an object we had not encountered before and I'm not sure how to create a Class that can be used to unserialize the object.</p>
  
  <p>This is what comes back from the API (just showing the part that is confusing):</p>
  
  <pre><code>s:8:" * _data";a:1:{
      i:4057353;C:25:"Transfer_Sales_Order_Item":201:{
          a:5:{
              s:8:"quantity";i:1;
              s:19:"id_sales_order_item";s:7:"4057353";
              s:4:"name";s:44:"Empacadora Selladora FoodSaver al Alto Vacio";
              s:10:"paid_price";d:796.13999999999999;
              s:3:"sku";s:15:"LI200HL37WWCLMX";
          }
      }
  }
  </code></pre>
  
  <p>Full serialized string:</p>
  
  <pre><code>O:16:"Service_Response":8:{s:11:" * _success";b:1;s:17:" * _errorMessages";a:0:{}s:19:" * _successMessages";a:0:{}s:22:" * _validationMessages";a:0:{}s:18:" * _noticeMessages";a:0:{}s:14:" * redirectUrl";N;s:23:" Service_Abstract _type";N;s:14:" * _resultData";a:1:{s:24:"NotAvailablesForTracking";O:40:"Transfer_Sales_Order_ItemCollection_test":6:{s:19:" * _objectClassName";s:25:"Transfer_Sales_Order_Item";s:15:" * _idAttribute";s:19:"id_sales_order_item";s:47:" Vendor_Transfer_AbstractCollection _indexDirty";b:0;s:8:" * _data";a:1:{i:4057353;C:25:"Transfer_Sales_Order_Item":201:{a:5:{s:8:"quantity";i:1;s:19:"id_sales_order_item";s:7:"4057353";s:4:"name";s:44:"Empacadora Selladora FoodSaver al Alto Vacio";s:10:"paid_price";d:796.13999999999999;s:3:"sku";s:15:"LI200HL37WWCLMX";}}}s:17:" * _setDataStrict";b:1;s:9:" * locale";N;}}}
  </code></pre>
  
  <p>It seems like it's an array of Objects / Classes (?) that just has an array? I've tried to look for what the <code>C</code> symbol means, but no success. Any idea of what the structure of <code>Transfer_Sales_Order_Item</code> should look like?</p>
  
  <p>My guess is because the original class implements <code>ArrayAccess</code>, but I tried that &amp; unserialized still complained it didn't have a target to unserialize to.</p>
  
  <p>For the moment we solved it by implementing <code>Serializable</code> on the class &amp; the <code>unserialize()</code> method which gets the contents of the class as a serialized string. This then unserializes normally to an array &amp; we went from there.</p>
  
  <p>This is the code we're using to unserialize the string:</p>
  
  <pre><code>class Transformer
  {
      public static function debugUnserialize($className)
      {
          throw new \RuntimeException(sprintf('Cannot unserialize object %s', $className, 500);
      }
  
      public function transform($value)
      {
          $previousCallback = ini_get('unserialize_callback_func');
          ini_set('unserialize_callback_func', self::class . '::debugUnserialzie');
          $data = unserialize($value);
          ini_set('unserialize_callback_func', $previousCallback);
          return $data;
      }
  }
  </code></pre>
  
  <p>After adding an empty class <code>Transfer_Sales_Order_Item</code>, PHP throws </p>
  
  <pre><code>Warning: Class Transfer_Sales_Order_Item has no unserializer
  </code></pre>
  
  <p>Note that this is not the exception from the <code>unserialize_callback_func</code> callback. So it doesn't even get there.</p>