<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Clockwerx's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 25 Jul 2008 07:41:28 GMT</pubDate>
    <description>DZone Snippets: Clockwerx's Code Snippets</description>
    <item>
      <title>PEAR::DB, DataObjects, and Joins / Reflection</title>
      <link>http://snippets.dzone.com/posts/show/1510</link>
      <description>PEAR::DB_DataObject is great. I really like it. We don't use it at work, though; having gone for a slightly different route. This pattern should be applicable, however, quite nicely to DB_DataObject.&lt;br /&gt;&lt;br /&gt;First, the database is set to associative fetching - our results come out as neat little arrays with fieldnames, so a $row = $db-&gt;query(/*blah*/)-&gt;fetchRow(); makes $row["id"], $row["field"], etc...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Configuration:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;require_once 'DB.php';&lt;br /&gt;&lt;br /&gt;$db = DB::connect("mysql://blah:blah@server/databaseName"); //Defined elsewhere&lt;br /&gt;$db-&gt;setFetchMode( DB_FETCHMODE_ASSOC );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next, we have our core object.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;class Core {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Process and extract values from an associative array.&lt;br /&gt;     *&lt;br /&gt;     * Improve performance and overload in child classes.&lt;br /&gt;     *&lt;br /&gt;     * @param   mixed[]    $array  Typically an assoc array from a DB::result-&gt;fetchRow.&lt;br /&gt;     * @return  bool&lt;br /&gt;     */&lt;br /&gt;    public function updateFromArray($array) {&lt;br /&gt;                &lt;br /&gt;        if ( is_array($array) ) {&lt;br /&gt;&lt;br /&gt;            $class = new ReflectionObject($this);&lt;br /&gt;            $properties = $class-&gt;getProperties();&lt;br /&gt;&lt;br /&gt;            for ($i = 0; $i &lt; count($properties); $i++) {&lt;br /&gt;                $prop_name = $properties[$i]-&gt;getName();&lt;br /&gt;&lt;br /&gt;                if (array_key_exists($prop_name, $array)) {&lt;br /&gt;                    $this-&gt;$prop_name = @$array[$prop_name];&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So, when we do a query we can mash up everything nicely (assuming we don't have two tables with the same column names):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$sql = "SELECT * FROM table t JOIN table2 t2 ON t.table_id = t2.table_id";&lt;br /&gt;&lt;br /&gt;$result = $db-&gt;query($sql);&lt;br /&gt;&lt;br /&gt;while ($row = $result-&gt;fetchRow()) {&lt;br /&gt;   $t = new Table();&lt;br /&gt;   $t2 = new Table2();&lt;br /&gt;&lt;br /&gt;   $t-&gt;updateFromArray($row);&lt;br /&gt;   $t2-&gt;updateFromArray($row);&lt;br /&gt;&lt;br /&gt;   //Do whatever you like with your objects...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;... and our objects get efficiently populated with data in a single query.&lt;br /&gt;&lt;br /&gt;The behind the scenes magic...&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Table extends DO_Table {&lt;br /&gt;//Business logic&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Table2 extends DO_Table2 {&lt;br /&gt;//Business logic&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class DO_Table extends DB_DataObject {&lt;br /&gt;     public $field;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class DO_Table extends DB_DataObject {&lt;br /&gt;     public $field2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class DB_DataObject extends Core {&lt;br /&gt;     &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now... there's a few gotchas with this; which is why we don't use DB_DataObject - you can accidentally overwrite information you shouldn't from Core::updateFromArray();&lt;br /&gt;&lt;br /&gt;There's no validation - you have to trust the array data you pass to the object.&lt;br /&gt;&lt;br /&gt;You have to watch your 'specialist' doesn't do anything silly like Table::updateFromArray($_REQUEST);&lt;br /&gt;&lt;br /&gt;You are limited to one row, one *type* of object - you couldn't join a table to itself and such.</description>
      <pubDate>Fri, 17 Feb 2006 11:03:27 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1510</guid>
      <author>CloCkWeRX (Daniel O'Connor)</author>
    </item>
    <item>
      <title>All Exceptions Created Equal</title>
      <link>http://snippets.dzone.com/posts/show/1509</link>
      <description>All exceptions are created equal. But what if you have a very good and pressing reason to serialize one to save it in a database? For instance, you had a collection of checks you wanted to run against some data, and save the results?&lt;br /&gt;&lt;br /&gt;Ah, that's easy! serialize() was made for that! So off you trot, you make a few changes to the code, add a blank line here, a blank line there, and suddenly your code can't find the exact matches of the serialized object in the database.&lt;br /&gt;&lt;br /&gt;HUH? What's going on? You're the exact same Exception I just threw three minutes ago, and you've sporadically broken?&lt;br /&gt;&lt;br /&gt;It took me a while to twig. When you create an exception ($e = new Exception("foo");), it's shiny and new and listens when you do equality comparisions (==).&lt;br /&gt;&lt;br /&gt;But things go awry: you throw a new Exception from your filter, catch it, and serialize it. You haven't remembered that...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$a = new Exception("foo");&lt;br /&gt;try {&lt;br /&gt;    throw $a; //Line 1&lt;br /&gt;} catch (Exception $e) {&lt;br /&gt;    throw $a; //Line 10;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;will result in two difference traces. One saying "I was thrown on on line 1", the other "I was thrown on on line 10"...&lt;br /&gt;&lt;br /&gt;Fuck oath, hello stupid coder. You've been wracking your brains wondering why every time you go off and edit a different bit of code it serializes differently; and there you have it.&lt;br /&gt;&lt;br /&gt;How the hell do I fix it? Going to __sleep() on the job actually helps.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;class DumbException extends Exception {&lt;br /&gt;    /**&lt;br /&gt;     * Cleanup anything we need before serialisation&lt;br /&gt;     *&lt;br /&gt;     * @return  string[]    An array of member varible names to serialize&lt;br /&gt;     * @see     http://php.planetmirror.com/manual/en/language.oop5.magic.php&lt;br /&gt;     */&lt;br /&gt;    public function __sleep() {&lt;br /&gt;        return array('string','code');&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Compare against another DumbException for equality.&lt;br /&gt;     *&lt;br /&gt;     * Since two exceptions can be !== because the trace / line / file&lt;br /&gt;     * information is different, we need to do this.&lt;br /&gt;     */&lt;br /&gt;    public function cmp(DumbException $e) {&lt;br /&gt;        return (serialize($e) == serialize($this));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print '&lt;pre&gt;';&lt;br /&gt;$a = new DumbException();&lt;br /&gt;$b = new DumbException();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;try {&lt;br /&gt;    try {&lt;br /&gt;        throw $b;&lt;br /&gt;    } catch (Exception $e) {&lt;br /&gt;        throw $a;&lt;br /&gt;    }&lt;br /&gt;} catch (Exception $e) {&lt;br /&gt;&lt;br /&gt;    var_dump($a === $b);&lt;br /&gt;    var_dump($a == $b);&lt;br /&gt;    var_dump($b === $e);&lt;br /&gt;    var_dump($b == $e);&lt;br /&gt;    var_dump($a === $e);&lt;br /&gt;    var_dump($a == $e);&lt;br /&gt;&lt;br /&gt;    var_dump($b-&gt;cmp($e));&lt;br /&gt;    var_dump($a-&gt;cmp($e));&lt;br /&gt;}&lt;br /&gt;print '&lt;/pre&gt;';&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 17 Feb 2006 10:01:44 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1509</guid>
      <author>CloCkWeRX (Daniel O'Connor)</author>
    </item>
    <item>
      <title>Ninging It</title>
      <link>http://snippets.dzone.com/posts/show/1503</link>
      <description>I love http://www.ning.com/ - and I fell in love with chaining whole bunches of objects together.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Foo {&lt;br /&gt;    function transform() {&lt;br /&gt;         //Some actual code&lt;br /&gt;         return $this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function transform2() {&lt;br /&gt;         //Some actual code&lt;br /&gt;         return $this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$f = new Foo();&lt;br /&gt;$f-&gt;transform()-&gt;transform2()-&gt;transform();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Concise!</description>
      <pubDate>Fri, 17 Feb 2006 09:29:37 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1503</guid>
      <author>CloCkWeRX (Daniel O'Connor)</author>
    </item>
  </channel>
</rss>
