Hallo,
ich hab mal wieder ein kleines schönes Standardprojekt. Neues sauberes Datenbankmodell mit überschaubaren ~10 Entitäten plus Beziehungen untereinander.
Ich ziehe das ganze mit dem Zend Framework auf und mache es immer so, dass ich mir selbst OR-Mapper schreibe:
datenbank.tabelle (mit z.B. id, name, ..)
class Tabelle {
setId(), getId(),
setName(), getName(),
fromArray(), toArray()
}
class Tabelle_List extends ArrayObject (bildet einen Array dieser Objekte ab)
class Tabelle_Model_Abstract
class Tabelle_Model_Database
class Tabelle_Model_Interface
class Tabelle_Form_Add extends Zend_Form
class Tabelle_Form_Edit extends Tabelle_Form_Add
(mal etwas vereinfacht)
Jetzt geht mir die blöde Tipperei auf die Nerven, das für alle 10 Entitäten zu erstellen, da eigentlich alle dasselbe machen (und jetzt schon dabei bin, Code zu kopieren und Namen zu ersetzen). Ich möchte aber keine generischen Objekte ala
$abstract->setProperty("id", $id)
weil ich dieses total generische schwer zu debuggen finde und ein Workaround für Ausnahmen schlecht einzufügen ist (overwrite setProperty mit switch-case). Ein Freund magischer Methoden bin ich auch nicht, da machen die wenigsten Auto-Complete-Funktionen der IDEs nicht mit, es Performance-Vorbehalte gibt und es außerdem vielleicht deprecated in PHP 6 ist, wer weiß.
Einen Generator anwerfen finde ich auch doof, weil ich nämlich einen selber schreiben müsste und bei meinen Ansprüchen dauert das wieder ne Woche.
Jetzt kam mir gerade diese blöde aber ziemlich fix funktionierende Lösung:
Irgendwie auch nicht so das wahre, aber es funktioniert. Ich weiß, ich sollte den Skill haben zu wissen, dass das Code auf eval()-Niveau ist. Zugegeben es ist auch nur das Ziel erreicht, dass ich Tabelle_List erstellt habe und damit sicherstelle, dass in Tabelle_List auch nur Objekte vom Typ Tabelle stehen habe. Aber immerhin. Wie gesagt, ich könnte auch 10x (oder bei anderen Projekte 50x) eine <Datenbanktabelle>_List erstellen, aber es ärgert mich irgendwie, dass es kein MeineKlasse<Klasse>() Konstrukte wie in Java gibt und ich würde das gerne nachbauen.
Gibt es denn eine PHP-Extension, die soetwas wie MeineKlassenListe<KlassenName>() unterstützt?
Wie macht ihr das, wenn ihr soviel Gleiches zu tun habt, Doctrine benutzen?
ich hab mal wieder ein kleines schönes Standardprojekt. Neues sauberes Datenbankmodell mit überschaubaren ~10 Entitäten plus Beziehungen untereinander.
Ich ziehe das ganze mit dem Zend Framework auf und mache es immer so, dass ich mir selbst OR-Mapper schreibe:
datenbank.tabelle (mit z.B. id, name, ..)
class Tabelle {
setId(), getId(),
setName(), getName(),
fromArray(), toArray()
}
class Tabelle_List extends ArrayObject (bildet einen Array dieser Objekte ab)
class Tabelle_Model_Abstract
class Tabelle_Model_Database
class Tabelle_Model_Interface
class Tabelle_Form_Add extends Zend_Form
class Tabelle_Form_Edit extends Tabelle_Form_Add
(mal etwas vereinfacht)
Jetzt geht mir die blöde Tipperei auf die Nerven, das für alle 10 Entitäten zu erstellen, da eigentlich alle dasselbe machen (und jetzt schon dabei bin, Code zu kopieren und Namen zu ersetzen). Ich möchte aber keine generischen Objekte ala
$abstract->setProperty("id", $id)
weil ich dieses total generische schwer zu debuggen finde und ein Workaround für Ausnahmen schlecht einzufügen ist (overwrite setProperty mit switch-case). Ein Freund magischer Methoden bin ich auch nicht, da machen die wenigsten Auto-Complete-Funktionen der IDEs nicht mit, es Performance-Vorbehalte gibt und es außerdem vielleicht deprecated in PHP 6 ist, wer weiß.
Einen Generator anwerfen finde ich auch doof, weil ich nämlich einen selber schreiben müsste und bei meinen Ansprüchen dauert das wieder ne Woche.
Jetzt kam mir gerade diese blöde aber ziemlich fix funktionierende Lösung:
PHP-Code:
<?php
abstract class ObjectList
{
public static function build($class)
{
if (!class_exists($class)) {
throw new Exception("class [$class] not found");
}
$listClass = $class . "List";
if (class_exists($listClass, false)) {
return new $listClass();
}
$php = self::_generateListClass($listClass, $class);
$tempFile = tempnam(sys_get_temp_dir(), "php");
file_put_contents($tempFile, $php);
include $tempFile;
unlink($tempFile);
return new $listClass;
}
protected static function _generateListClass($listClass, $singleClass)
{
// nowdoc syntax:
$php = <<<'PHP_CLASS_DECLARATION'
<?php
class %__listClass__% extends ArrayObject
{
public function offsetSet($offset, $element)
{
if (!$element instanceof %__singleClass__%) {
$type = gettype($element);
if ($type === "object") {
$type .= "::" . get_class($element);
}
throw new InvalidArgumentException("invalid element provided [$type], must be an instance of %__singleClass__%");
}
if (!($offset === null || (ctype_digit((string)$offset) && $offset >= 0))) {
throw new InvalidArgumentException("invalid element offset provided, must be NULL or unsigned integer");
}
return parent::offsetSet($offset, $element);
}
public function append($element)
{
return $this->offsetSet(null, $element);
}
}
PHP_CLASS_DECLARATION;
$php = strtr($php, array(
"%__listClass__%" => $listClass,
"%__singleClass__%" => $singleClass
));
return $php;
}
}
class Test
{
public function getName() {
return spl_object_hash($this);
}
}
class NotTest
{
}
$testList = ObjectList::build("Test");
$testList = ObjectList::build("Test");
$testList[] = new Test();
$testList[] = new Test();
foreach ($testList as $test) {
echo $test->getName(), "<br />";
}
$testList[] = new NotTest(); // Exception
Gibt es denn eine PHP-Extension, die soetwas wie MeineKlassenListe<KlassenName>() unterstützt?
Wie macht ihr das, wenn ihr soviel Gleiches zu tun habt, Doctrine benutzen?

Kommentar