-
-
Save beberlei/d9fac02e7309e692b0467ae89cda9e64 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class DatabaseMapper | |
{ | |
public function map(array $row, string $class) | |
{ | |
// these lines until the foreach ($row) loop only need to be done once per class | |
$reflection = new ReflectionClass($class); | |
$properties = []; | |
$columnPrefixes = []; | |
$associationClasses = []; | |
foreach ($reflection->getProperties() as $property) { | |
$properties[strtolower($property->getName())] = $property; | |
$association = $property->getAttributes(AssocationColumnPrefix::class); | |
if (count($association) > 0) { | |
$assocationAttribute = $association[0]->getAsObject(); | |
$columnPrefixes[$property->getName()] = $assocationAttribute->prefix; | |
$associationClasses[$property->getName()] = $associationClasses->class; | |
} | |
} | |
// this needs to be done per row | |
$object = $reflection->newInstance(); | |
$associationColumns = []; | |
foreach ($row as $column => $value) { | |
$property = str_replace("_", "", $column); | |
if (!isset($properties[$property])) { | |
continue; | |
} | |
if (!isset($columnPrefixes[$property])) { | |
// no column prefix? We assume its a regular field | |
$reflection->getMethod("set" . $property)->invoke($object, $value); | |
} else { | |
// we check if it matches a column prefix and store it for each | |
// assocation | |
foreach ($columnPrefixes as $associationProperty => $columnPrefix) { | |
if (strpos($column, $columnPrefix) === 0) { | |
// column prefix matched, such as "category_" | |
$associationColumn = str_replace($columnPrefix, "", $column); | |
$associationColumns[$associationProperty][$associationColumn] = $value; | |
break 2; | |
} | |
} | |
} | |
} | |
// now iterate all the associations we found, map and assign them | |
foreach ($associationColumns as $associationProperty => $row) { | |
$relatedObject = $this->map($row, $associationClasses[$associationProperty]); | |
$reflection->getMethod("set" . $associationProperty)->invoke($object, $relatedObject); | |
} | |
return $object; | |
} | |
} | |
class AssocationColumnPrefix implements \Php\Attribute | |
{ | |
public $prefix; | |
public $class; | |
public function __construct(string $prefix, string $class) { | |
$this->prefix = $prefix; | |
$this->class = $class; | |
} | |
} | |
class Post | |
{ | |
private $id; | |
private $name; | |
private $slug; | |
private $content; | |
<<AssocationColumnPrefix("category_", Category::class)>> | |
private $category; | |
} | |
$sql = 'SELECT p.id, p.name, p.slug, p.content, p.category_id, p.cateogry_name FROM post p JOIN category c ON c.id = p.category_id WHERE p.id = ?'; | |
$stmt = $pdo->prepare($sql); | |
$stmt->bindParam(1, $_GET['id']); | |
$stmt->execute(); | |
$mapper = new DatabaseMapper(); | |
$post = $mapper->map($stmt->fetch(), Post::class); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment