Ejemplo n.º 1
0
 /**
  * Freezes an object.
  *
  * If the object has not been frozen before, the attribute
  * __php_object_freezer_uuid will be added to it.
  *
  * In the example below, we freeze an object of class A. As this object
  * aggregates an object of class B, the object freezer has to freeze two
  * objects in total.
  *
  * <code>
  * <?php
  * require_once 'Object/Freezer.php';
  *
  * class A
  * {
  *     protected $b;
  *
  *     public function __construct()
  *     {
  *         $this->b = new B;
  *     }
  * }
  *
  * class B
  * {
  *     protected $foo = 'bar';
  * }
  *
  * $freezer = new Object_Freezer;
  * var_dump($freezer->freeze(new A));
  * ?>
  * </code>
  *
  * Below is the output of the code example above.
  *
  * <code>
  * array(2) {
  *   ["root"]=>
  *   string(36) "32246c35-f47b-4fbc-a2ad-ed14e520865e"
  *   ["objects"]=>
  *   array(2) {
  *     ["32246c35-f47b-4fbc-a2ad-ed14e520865e"]=>
  *     array(3) {
  *       ["className"]=>
  *       string(1) "A"
  *       ["isDirty"]=>
  *       bool(true)
  *       ["state"]=>
  *       array(2) {
  *         ["b"]=>
  *         string(57)
  *         "__php_object_freezer_3cd682bf-8eba-4fec-90e2-ebe98aa07ab7"
  *         ["__php_object_freezer_hash"]=>
  *         string(40) "8b80da9c38c0c41c829cbbefbca9b18aa67ff607"
  *       }
  *     }
  *     ["3cd682bf-8eba-4fec-90e2-ebe98aa07ab7"]=>
  *     array(3) {
  *       ["className"]=>
  *       string(1) "B"
  *       ["isDirty"]=>
  *       bool(true)
  *       ["state"]=>
  *       array(2) {
  *         ["foo"]=>
  *         string(3) "bar"
  *         ["__php_object_freezer_hash"]=>
  *         string(40) "e04e935f09f2d526258d8a16613c5bce31e84e87"
  *       }
  *     }
  *   }
  * }
  * </code>
  *
  * The reference to the object of class B that the object of class A had
  * before it was frozen has been replaced with the UUID of the frozen
  * object of class B
  * (__php_object_freezer_3cd682bf-8eba-4fec-90e2-ebe98aa07ab7).
  *
  * The result array's "root" element contains the UUID for the now frozen
  * object of class A (32246c35-f47b-4fbc-a2ad-ed14e520865e).
  *
  * @param object $object  The object that is to be frozen.
  * @param array  $objects Only used internally.
  *
  * @return array The frozen object(s).
  *
  * @throws InvalidArgumentException
  */
 public function freeze($object, array &$objects = [])
 {
     // Bail out if a non-object was passed.
     if (!is_object($object)) {
         throw Object_Freezer_Util::getInvalidArgumentException(1, 'object');
     }
     // The object has not been frozen before, generate a new UUID and
     // store it in the "special" __php_object_freezer_uuid attribute.
     if (!isset($object->__php_object_freezer_uuid)) {
         $object->__php_object_freezer_uuid = $this->idGenerator->getId();
     }
     $isDirty = $this->isDirty($object, true);
     $uuid = $object->__php_object_freezer_uuid;
     if (!isset($objects[$uuid])) {
         $objects[$uuid] = ['className' => get_class($object), 'isDirty' => $isDirty, 'state' => []];
         // Iterate over the attributes of the object.
         foreach (Object_Freezer_Util::readAttributes($object) as $k => $v) {
             if ($k !== '__php_object_freezer_uuid') {
                 if (is_array($v)) {
                     $this->freezeArray($v, $objects);
                 } elseif (is_object($v) && !in_array(get_class($v), $this->blacklist)) {
                     // Freeze the aggregated object.
                     $this->freeze($v, $objects);
                     // Replace $v with the aggregated object's UUID.
                     $v = '__php_object_freezer_' . $v->__php_object_freezer_uuid;
                 } elseif (is_resource($v)) {
                     $v = null;
                 }
                 // Store the attribute in the object's state array.
                 $objects[$uuid]['state'][$k] = $v;
             }
         }
     }
     return ['root' => $uuid, 'objects' => $objects];
 }
Ejemplo n.º 2
0
 /**
  * Implementation of Object_Freezer_HashGenerator that uses the SHA1
  * hashing function on the attribute values of an object without recursing
  * into aggregated arrays or objects.
  *
  * @param object $object The object that is to be hashed.
  *
  * @return string
  *
  * @throws InvalidArgumentException
  */
 public function getHash($object)
 {
     // Bail out if a non-object was passed.
     if (!is_object($object)) {
         throw Object_Freezer_Util::getInvalidArgumentException(1, 'object');
     }
     $attributes = Object_Freezer_Util::readAttributes($object);
     ksort($attributes);
     if (isset($attributes['__php_object_freezer_hash'])) {
         unset($attributes['__php_object_freezer_hash']);
     }
     foreach ($attributes as $key => $value) {
         if (is_array($value)) {
             $attributes[$key] = '<array>';
         } elseif (is_object($value)) {
             if (!isset($value->__php_object_freezer_uuid)) {
                 $value->__php_object_freezer_uuid = $this->idGenerator->getId();
             }
             $attributes[$key] = $value->__php_object_freezer_uuid;
         } elseif (is_resource($value)) {
             $attributes[$key] = null;
         }
     }
     return sha1(get_class($object) . implode(':', $attributes));
 }