{
    "href": "/post/2006/07/21/solar-021-and-022-released-in-quick-succession/",
    "relId": "2006/07/21/solar-021-and-022-released-in-quick-succession",
    "title": "Solar 0.21 and 0.22 released in quick succession",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/solar/",
            "relId": "solar",
            "title": "Solar",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2006-07-21 22:40:27 UTC",
    "updated": [
        "2006-07-21 22:40:27 UTC"
    ],
    "html": "<p>I released <a href=\"http://solarphp.com\">Solar</a> 0.21.0 yesterday, and a quick followup 0.22.0 today.  The rest of this entry covers highlights for changes in both versions.  The main highlights are three new classes (Solar_Struct, Solar_Sql_Row, and Solar_Sql_Rowset) along with a backwards-compatibility break to how classes store their default configuration values.</p>\n<p><!--more--></p>\n<h3>Changes To $_config Use</h3>\n<p>There is one really big change to the configuration system.  It should not require more than a search-and-replace in your files, but it's still a big deal.</p>\n<p>The change is that you now put the default config values for your class in a property called $_{Class_Name} instead of in $_config.  (Keep using the $_config property for reading configs, but put the defaults in $_{Class_Name}.)  For example ...</p>\n<p>Previously, you would do this to define a default config key and value:</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    </span><span style=\"color: #FF8000\">// parent class\n    </span><span style=\"color: #007700\">class </span><span style=\"color: #0000BB\">Vendor_Foo </span><span style=\"color: #007700\">extends </span><span style=\"color: #0000BB\">Solar_Base </span><span style=\"color: #007700\">{\n        protected </span><span style=\"color: #0000BB\">$_config </span><span style=\"color: #007700\">= array(</span><span style=\"color: #DD0000\">'foo' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'bar'</span><span style=\"color: #007700\">);\n        public function </span><span style=\"color: #0000BB\">getConfig</span><span style=\"color: #007700\">()\n        {\n            </span><span style=\"color: #0000BB\">Solar</span><span style=\"color: #007700\">::</span><span style=\"color: #0000BB\">dump</span><span style=\"color: #007700\">(</span><span style=\"color: #0000BB\">$this</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">_config</span><span style=\"color: #007700\">);\n        }\n    }\n\n    </span><span style=\"color: #FF8000\">// child class\n    </span><span style=\"color: #007700\">class </span><span style=\"color: #0000BB\">Vendor_Foo_Baz </span><span style=\"color: #007700\">extends </span><span style=\"color: #0000BB\">Vendor_Foo </span><span style=\"color: #007700\">{\n        protected </span><span style=\"color: #0000BB\">$_config </span><span style=\"color: #007700\">= array(</span><span style=\"color: #DD0000\">'baz' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'dib'</span><span style=\"color: #007700\">);\n    }\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>This was great for reading from the config file, but it meant that the parent class config keys were not inherited by the child class.  The child $_config overrides the parent $_config entirely; you would have to put some checking code in your parent constructor to make sure all the keys were there.  Thus, a call to Vendor_Foo_Baz::getConfig() would show only the 'baz' key, and not the combination of the parent 'foo' key and the child 'baz' key.</p>\n<p>In this release, we change from $_config to $_{Class_Name} for default config values.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    </span><span style=\"color: #FF8000\">// parent class\n    </span><span style=\"color: #007700\">class </span><span style=\"color: #0000BB\">Vendor_Foo </span><span style=\"color: #007700\">{\n        protected </span><span style=\"color: #0000BB\">$_Vendor_Foo </span><span style=\"color: #007700\">= array(</span><span style=\"color: #DD0000\">'foo' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'bar'</span><span style=\"color: #007700\">);\n        public function </span><span style=\"color: #0000BB\">getConfig</span><span style=\"color: #007700\">()\n        {\n            </span><span style=\"color: #0000BB\">Solar</span><span style=\"color: #007700\">::</span><span style=\"color: #0000BB\">dump</span><span style=\"color: #007700\">(</span><span style=\"color: #0000BB\">$this</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">_config</span><span style=\"color: #007700\">);\n        }\n    }\n\n    </span><span style=\"color: #FF8000\">// child class\n    </span><span style=\"color: #007700\">class </span><span style=\"color: #0000BB\">Vendor_Foo_Baz </span><span style=\"color: #007700\">extends </span><span style=\"color: #0000BB\">Vendor_Foo </span><span style=\"color: #007700\">{\n        protected </span><span style=\"color: #0000BB\">$_Vendor_Foo_Baz </span><span style=\"color: #007700\">= array(</span><span style=\"color: #DD0000\">'baz' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'dib'</span><span style=\"color: #007700\">);\n    }\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>(Note from getConfig() that the $_config property does not go away, you just don't put anything in it yourself.)</p>\n<p>In the new system, Solar_Base collects all the $_{Class_Name} arrays and merges them all into $_config for you.  This means that child classes inherit their parent config keys and values unless you override them in the child class.</p>\n<p>Basically, you should keep reading from $_config when getting config values in your class methods.  But for property definitions, use $_{Class_Name} for the default config keys and values.</p>\n<h3>Solar_Struct</h3>\n<p>The new <a href=\"http://solarphp.com/svn/trunk/Solar/Struct.php\" onclick=\"window.open(this.href, '_blank'); return false;\">Solar_Struct</a> class is an ideological cousin to Matthew Weier O'Phinney's <a href=\"http://weierophinney.net/matthew/archives/113-Phly_Struct-no,-Phly_Hash....html\" onclick=\"window.open(this.href, '_blank'); return false;\">Phly_Hash</a> class (originally <a href=\"http://weierophinney.net/matthew/archives/112-Introducing-Phly_Struct-and-Phly_Config.html\" onclick=\"window.open(this.href, '_blank'); return false;\">Phly_Struct</a>).</p>\n<p>When you build a struct instance, you give it a series of keys and values as an array; those keys become properties in the struct object, and the values are used as the property values.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    $data </span><span style=\"color: #007700\">= array(\n        </span><span style=\"color: #DD0000\">'foo' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'bar'</span><span style=\"color: #007700\">,\n        </span><span style=\"color: #DD0000\">'baz' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'dib'</span><span style=\"color: #007700\">,\n        </span><span style=\"color: #DD0000\">'zim' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #DD0000\">'gir'</span><span style=\"color: #007700\">,\n    );\n\n    </span><span style=\"color: #0000BB\">$struct </span><span style=\"color: #007700\">= </span><span style=\"color: #0000BB\">Solar</span><span style=\"color: #007700\">::</span><span style=\"color: #0000BB\">factory</span><span style=\"color: #007700\">(\n        </span><span style=\"color: #DD0000\">'Solar_Struct'</span><span style=\"color: #007700\">,\n        array(</span><span style=\"color: #DD0000\">'data' </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #0000BB\">$data</span><span style=\"color: #007700\">)\n    );\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>Using this class, you can access data using both array notation ($foo['bar']) and object notation ($foo-&gt;bar).  This helps with moving data among form objects, view helpers, SQL objects, etc.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    </span><span style=\"color: #007700\">echo </span><span style=\"color: #0000BB\">$struct</span><span style=\"color: #007700\">[</span><span style=\"color: #DD0000\">'foo'</span><span style=\"color: #007700\">]; </span><span style=\"color: #FF8000\">// 'bar'\n    </span><span style=\"color: #007700\">echo </span><span style=\"color: #0000BB\">$struct</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">foo</span><span style=\"color: #007700\">;   </span><span style=\"color: #FF8000\">// 'bar'\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>The struct object implements ArrayAccess, Countable, and Iterator, so you can treat it just like an array in many cases.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    </span><span style=\"color: #007700\">echo </span><span style=\"color: #0000BB\">count</span><span style=\"color: #007700\">(</span><span style=\"color: #0000BB\">$struct</span><span style=\"color: #007700\">); </span><span style=\"color: #FF8000\">// 3\n\n    </span><span style=\"color: #007700\">foreach (</span><span style=\"color: #0000BB\">$struct </span><span style=\"color: #007700\">as </span><span style=\"color: #0000BB\">$key </span><span style=\"color: #007700\">=&gt; </span><span style=\"color: #0000BB\">$val</span><span style=\"color: #007700\">) {\n        echo </span><span style=\"color: #DD0000\">\"$key=$val \"</span><span style=\"color: #007700\">;\n    } </span><span style=\"color: #FF8000\">// foo=bar  baz=dib zim=gir\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>One problem with Solar_Struct is that casting the object to an array will not reveal the data; you'll get an empty array.  Instead, you should use the toArray() method to get a copy of the object data.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    $array </span><span style=\"color: #007700\">= (array) </span><span style=\"color: #0000BB\">$struct</span><span style=\"color: #007700\">;    </span><span style=\"color: #FF8000\">// $struct = array();\n    </span><span style=\"color: #0000BB\">$array </span><span style=\"color: #007700\">= </span><span style=\"color: #0000BB\">$struct</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">toArray</span><span style=\"color: #007700\">(); </span><span style=\"color: #FF8000\">// $struct = array(\n                                 //     'foo' =&gt; 'bar',\n                                 //     'baz' =&gt; 'dib',\n                                 //     'zim' =&gt; 'gir',\n                                 // );\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>One other problem is that double-quote interpolation isn't as intuitive.  If you want to use a struct property in double-quotes, you should wrap it in curly braces.</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    </span><span style=\"color: #FF8000\">// won't work right, will show \"Object #23-&gt;foo\"\n    </span><span style=\"color: #007700\">echo </span><span style=\"color: #DD0000\">\"Struct foo is $struct-&gt;foo\"</span><span style=\"color: #007700\">;\n\n    </span><span style=\"color: #FF8000\">// will work as expected\n    </span><span style=\"color: #007700\">echo </span><span style=\"color: #DD0000\">\"Struct foo is {$struct-&gt;foo}\"</span><span style=\"color: #007700\">;\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<h3>Solar_Sql_Row</h3>\n<p>The new <a href=\"http://solarphp.com/svn/trunk/Solar/Sql/Row.php\" onclick=\"window.open(this.href, '_blank'); return false;\">Solar_Sql_Row</a> class is extended from Solar_Struct, and adds a new method called save().</p>\n<p>From now on, any time you call select('row') or fetch() from an SQL class, you're going to get a Solar_Sql_Row object instead of an array.  Because Solar_Struct acts like both an array and an object, you shouldn't have to change any of your code to use the new return type.</p>\n<p>If you want to, you can start using object notation with rows.  For example, instead of $row['id'] you can use $row-&gt;id (which is a lot easier to read in most cases).</p>\n<p>An additional benefit is that Solar_Sql_Row has a save() method that can be tied back to a table object.  Previously, if you wanted to insert or update a row, you had to pass it as an array into its related table object:</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    $row</span><span style=\"color: #007700\">[</span><span style=\"color: #DD0000\">'foo'</span><span style=\"color: #007700\">] = </span><span style=\"color: #DD0000\">\"bar\"</span><span style=\"color: #007700\">;\n    </span><span style=\"color: #0000BB\">$row</span><span style=\"color: #007700\">[</span><span style=\"color: #DD0000\">'baz'</span><span style=\"color: #007700\">] = </span><span style=\"color: #DD0000\">\"dib\"</span><span style=\"color: #007700\">;\n    </span><span style=\"color: #0000BB\">$table</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">save</span><span style=\"color: #007700\">(</span><span style=\"color: #0000BB\">$row</span><span style=\"color: #007700\">);\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>Now you can save the row directly:</p>\n<pre><code><span style=\"color: #000000\">\n</span><span style=\"color: #0000BB\">&lt;?php\n    $row</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">foo </span><span style=\"color: #007700\">= </span><span style=\"color: #DD0000\">\"bar\"</span><span style=\"color: #007700\">;\n    </span><span style=\"color: #0000BB\">$row</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">baz </span><span style=\"color: #007700\">= </span><span style=\"color: #DD0000\">\"dib\"</span><span style=\"color: #007700\">;\n    </span><span style=\"color: #0000BB\">$row</span><span style=\"color: #007700\">-&gt;</span><span style=\"color: #0000BB\">save</span><span style=\"color: #007700\">();\n</span><span style=\"color: #0000BB\">?&gt;</span>\n</code></pre>\n<p>Because it is tied back to the source table object, it follows all the validation and insert/update rules of that object, so you don't need to duplicate them just for the row object.</p>\n<h3>Solar_Sql_Rowset</h3>\n<p>The new <a href=\"http://solarphp.com/svn/trunk/Solar/Sql/Rowset.php\" onclick=\"window.open(this.href, '_blank'); return false;\">Solar_Sql_Rowset</a> class also extends from Solar_Struct, but it works as a collection of Solar_Sql_Row objects.  You can iterate through it with foreach() and get one row at a time, working with each and calling save() as you go.</p>\n<p>From now on, any time you call select('all') or fetchAll() from an SQL class, you're going to get a Solar_Sql_Rowset object instead of an array.  Because Solar_Struct acts like both an array and an object, you shouldn't have to change any of your code to use the new return type.</p>\n<h3>User-Defined Row Classes</h3>\n<p>With Solar_Sql_Row and Solar_Sql_Rowset in place, Solar_Sql_Table now returns these when you call fetch() and fetchAll().  Even better, you can set the new properties $_row_class and $_all_class to a custom class descended from a Row or Rowset; if you do, the fetch*() methods will use those classes as the return objects.  This paves the way for the beginning of something like a formal ActiveRecord pattern as described by Martin Fowler (as opposed to the one popularized by Rails.)</p>\n"
}
