Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In the end I wrote the following class which performs the task using unserializing a fabricated string. It uses reflection to determine what the access-type of properties is and what the name of the constructor is (if any).</p> <p>The heart of the class is the following line:</p> <pre><code>$object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1)); </code></pre> <p>which serializes the property-array and renames the serialized to the desired class_name.</p> <pre><code>class ObjectFactory { private $properties; private $constructors; public function __construct() { $this-&gt;properties = array(); $this-&gt;constructors = array(); } private function setClass($class_name) { $class = new ReflectionClass($class_name); $this-&gt;properties[$class_name] = array(); foreach($class-&gt;getProperties() as $property) { $name = $property-&gt;getName(); $modifier = $property-&gt;getModifiers(); if($modifier &amp; ReflectionProperty::IS_STATIC) { continue; } else if($modifier &amp; ReflectionProperty::IS_PUBLIC) { $this-&gt;properties[$class_name][$name] = $name; } else if($modifier &amp; ReflectionProperty::IS_PROTECTED) { $this-&gt;properties[$class_name][$name] = "\0*\0".$name; // prefix * with \0's unserializes to protected property } else if($modifier &amp; ReflectionProperty::IS_PRIVATE) { $this-&gt;properties[$class_name][$name] = "\0".$class_name."\0".$name; // prefix class_name with \0's unserializes to private property } } if($constructor = $class-&gt;getConstructor()) { $this-&gt;constructors[$class_name] = $constructor-&gt;getName(); } } private function hasClassSet($class_name) { return array_key_exists($class_name, $this-&gt;properties); } private function hasClassProperty($class_name, $property_name) { if(!$this-&gt;hasClassSet($class_name)) $this-&gt;setClass($class_name); return array_key_exists($property_name, $this-&gt;properties[$class_name]); } private function getClassProperty($class_name, $property_name) { if(!$this-&gt;hasClassProperty($class_name, $property_name)) return false; return $this-&gt;properties[$class_name][$property_name]; } private function hasClassConstructor($class_name) { if(!$this-&gt;hasClassSet($class_name)) $this-&gt;setClass($class_name); return $this-&gt;constructors[$class_name] !== false; } private function getClassConstructor($class_name) { if(!$this-&gt;hasClassConstructor($class_name)) return false; return $this-&gt;constructors[$class_name]; } public function fetch_object(array $assoc, $class_name = 'stdClass', array $params = array()) { $properties = array(); foreach($assoc as $key =&gt; $value) { if($property = $this-&gt;getClassProperty($class_name, $key)) { $properties[$property] = $value; } } $object = unserialize('O:'.strlen($class_name).':"'.$class_name.'"'.substr(serialize($properties), 1)); if($constructor = $this-&gt;getClassConstructor($class_name)) { call_user_func_array(array($object, $constructor), $params); } return $object; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload