Note that there are some explanatory texts on larger screens.

plurals
  1. POOOP approach for wrapping subclasses of database rows
    primarykey
    data
    text
    <p>Let's say I want to store dogs in a database table with each dog having its own subclass in PHP.</p> <p>Basically I want to avoid storing/listing the subclass names in different places in the code. What would be a good OOP approach for that?</p> <pre><code>abstract class Dog { protected $data; public function __construct($data) { $this-&gt;data = $data; } public function name() { return $this-&gt;data["name"]; } abstract public function breed(); } class GermanShepherd extends Dog { public function breed() { return _("German Shepherd"); } } class BullDog extends Dog { public function breed() { return _("Bulldog"); } } </code></pre> <p>Now I have this class that handles groups of objects (i.e. dogs):</p> <pre><code>class Dogs { public static function getDogs() { // ... $ret = array(); while ($row = mysql_fetch_assoc()) { switch ($row["type"]) { // I could do this using a lookup array case "shepherd": $dog = "GermanShepherd"; break; case "bulldog": $dog = "Bulldog"; break; } $ret[] = new $dog($row); } return $ret; } } </code></pre> <p>And I would like to use this class to get the dog types in my view (especially for an <strong>add dog</strong> form), instead of listing the class names:</p> <pre><code>?&gt;&lt;form&gt;&lt;select name="type"&gt;&lt;?php foreach (array("GermanShepherd", "Bulldog") as $dog) { // here I would like to do avoid listing the class names again ?&gt;&lt;option value="&lt;?=$dog ?&gt;"&gt;&lt;?php $d = new $dog; // actually I can't instantiate the class here because I don't have any data at this point echo $d-&gt;name(); ?&gt;&lt;/option&gt;&lt;?php } ?&gt;&lt;/select&gt;&lt;/form&gt;&lt;?php </code></pre> <p>I would like to incorporate this into the <code>Dogs</code> class, something along the lines of this:</p> <pre><code>class Dogs { private static $dogs = array( "shepherd" =&gt; "GermanShepherd", "bulldog" =&gt; "Bulldog", ); public static function getDogs() { // ... $ret = array(); while ($row = mysql_fetch_assoc()) { $dog = self::$dogs[$row["type"]]; $ret[] = new $dog($row); } return $ret; } public static function getDogTypes() { return array_values(self::$dogs); } } ?&gt;&lt;form&gt;&lt;select name="type"&gt;&lt;?php foreach (Dogs::getDogTypes() as $dog) { ?&gt;&lt;option value="&lt;?=$dog ?&gt;"&gt;&lt;?php $d = new $dog; // here I still need to instantiate the class and I don't have any data to provide it with echo $d-&gt;name(); ?&gt;&lt;/option&gt;&lt;?php } ?&gt;&lt;/select&gt;&lt;/form&gt;&lt;?php </code></pre> <p>This would somewhat work so far, but what if I need more class specific information, for example when I have more fields specific to a dog type?</p> <pre><code>foreach (Dogs::getDogTypes() as $dog) { $d = new $dog; // instantiate again? foreach ($d-&gt;formFields() as $f) { // I wouldn't do it like this, just putting this here for demonstrative purposes echo $f; } } </code></pre> <p>I think part of the problem lies in the fact that I need to be able to use my classes with and without database data: Everything seems very reasonable when I have the data from the database table, but I also need the data when I generate the form when creating a new dog.</p> <p>Thanks for your ideas!</p>
    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. 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