<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>hatsuseno&#039;s blog &#187; PHP</title>
	<atom:link href="http://blog.hatsuseno.org/index.php/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.hatsuseno.org</link>
	<description>rantings on tech</description>
	<lastBuildDate>Tue, 03 Aug 2010 12:58:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Custom order sorting in PHP</title>
		<link>http://blog.hatsuseno.org/index.php/custom-order-sorting-in-php/</link>
		<comments>http://blog.hatsuseno.org/index.php/custom-order-sorting-in-php/#comments</comments>
		<pubDate>Sun, 02 May 2010 14:46:56 +0000</pubDate>
		<dc:creator>hatsuseno</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[quicksort]]></category>

		<guid isPermaLink="false">http://blog.hatsuseno.org/?p=139</guid>
		<description><![CDATA[Every once in a while you find your self in need of a generic sorting function that orders in a very specific, and non-machine understandable way. Like sorting items from &#8216;one&#8217; to &#8216;four&#8217;. Instead of building a small subset of those kind of sort operations into the language PHP has usort family (short for user-defined [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while you find your self in need of a generic sorting function that orders in a very specific, and non-machine understandable way. Like sorting items from &#8216;one&#8217; to &#8216;four&#8217;. Instead of building a small subset of those kind of sort operations into the language PHP has usort family (short for user-defined sort). In the background this sort still works as a <a href="http://en.wikipedia.org/wiki/Quicksort">quicksort</a>, but the developer is tasked with making a function that does the comparison between different elements of the array. It&#8217;s up to him to define whether a value is smaller, equal or bigger than another.</p>
<p>So, keeping the &#8216;one&#8217; to &#8216;four&#8217; example, I present you with a very simple custom sort function.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> customCompare<span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #339933;">,</span> <span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// We flip the array to get the positional indices </span>
  <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'one'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'two'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'three'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'four'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Sanity check, $a and $b must exist in the order array</span>
  <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #339933;">,</span> <span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$arg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;`<span style="color: #006699; font-weight: bold;">$arg</span>' is not a sortable key&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// The positions in the order array dictate if $a is bigger</span>
  <span style="color: #666666; font-style: italic;">// than $b, as such we can simply subtract the integers</span>
  <span style="color: #666666; font-style: italic;">// from the flipper order array to get an integer value</span>
  <span style="color: #666666; font-style: italic;">// which is smaller, equal or bigger than 0 depending on</span>
  <span style="color: #666666; font-style: italic;">// $a and $b's relative position in the array.</span>
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$a</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$b</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// An example array to be sorted</span>
<span style="color: #000088;">$example</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'four'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'one'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'three'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'two'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Do the actual sort</span>
<span style="color: #990000;">uksort</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$example</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'customCompare'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Dump results</span>
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$example</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The dumped array will look like this</p>
<pre>
Array
(
    [one] => 1
    [two] => 2
    [three] => 3
    [four] => 4
)
</pre>
<p>If you, like me, like closures and are running PHP 5.3, we can make the compare function a lot nicer and easier to maintain.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> createSorter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_flip</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #339933;">,</span> <span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span> use <span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Sanity check, again</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$a</span><span style="color: #339933;">,</span> <span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$arg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;`<span style="color: #006699; font-weight: bold;">$arg</span>' is not a sortable key&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$a</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$b</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Sort array $array in the 'one' to 'four' order.</span>
<span style="color: #990000;">uksort</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> createSorter<span style="color: #009900;">&#40;</span>
  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'one'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'two'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'three'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'four'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.hatsuseno.org/index.php/custom-order-sorting-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP and XML manipulation</title>
		<link>http://blog.hatsuseno.org/index.php/php-and-xml-manipulation/</link>
		<comments>http://blog.hatsuseno.org/index.php/php-and-xml-manipulation/#comments</comments>
		<pubDate>Thu, 28 May 2009 23:19:30 +0000</pubDate>
		<dc:creator>hatsuseno</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[SimpleXML]]></category>

		<guid isPermaLink="false">http://blog.hatsuseno.org/?p=32</guid>
		<description><![CDATA[Recently I&#8217;ve been fiddeling around with an old project of mine, and decided to extend it into a full-blown framework, just for kicks. Born from GDO, a ORM layer for PHP, it&#8217;s supposed to serve no real purpose but personal gratification.
Anyway, parallel with the framework I am building a website to showcase it. I also [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been fiddeling around with an old project of mine, and decided to extend it into a full-blown framework, just for kicks. Born from <acronym title='Generic Database Object'>GDO</acronym>, a <acronym title='Object-relational mapping'>ORM</acronym> layer for PHP, it&#8217;s supposed to serve no real purpose but personal gratification.</p>
<p>Anyway, parallel with the framework I am building a website to showcase it. I also decided that in this specific case all the HTML documents should be built from either PHPs DOM or SimpleXML libraries, I personally dislike having HTML strewn across the project, so I&#8217;ve seperated structures like forms and tables into classes and the idea is that I can simply append them to the current page at a specific node and it&#8217;ll render the HTML when everything is added. </p>
<h3>The problem</h3>
<p>Here in lies the problem, PHPs XML libraries (at least the ones that I tried) require you to drag the top node to which you want to append whatever around in all helper classes and such, allow me to demonstrate.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$document</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$table</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMElement<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMElement<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DOMElement<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'td'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'test element'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$table</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$document</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$table</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>One would expect this all to work out fine and produce the following XML document;</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">'1.0'</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">'utf-8'</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;tr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;td<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test element<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/td<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/tr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/table<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>In fact, it won&#8217;t. It won&#8217;t even run. PHP bails out during run time with the error &#8220;<code>DOMException: No Modification Allowed Error</code>&#8220;. This is because every <code>DOMElement</code> object not created with <a href='http://php.net/manual/en/domdocument.createelement.php'><code>DOMDocument::createElement()</code></a> is by default <i>read-only</i>, as you can read in the description of <a href='http://php.net/manual/en/domelement.construct.php'><code>DOMDocument::__construct()</code></a>.</p>
<p>Besides begging the PHP developers to make every <code>DOMElement</code> not read-only on construction, the obvious solution would be to add the <code>DOMElement</code> in question to the <code>DOMDocument</code> and continue building from there, but that&#8217;s the problem. It seems counter-intuitive to pass the <code>DOMElement</code> or <code>DOMDocument</code> that you want to append your seperate structure to to every constructor of every XML producing class (or via normal methods of course).</p>
<p>I&#8217;ve taken the literal example of PHPs DOM classes, but I&#8217;ve tested SimpleXML as well, which provides even less flexibilty regarding node reuse and other fancy stuff one could want to do with XML documents.</p>
<h3>Workarounds</h3>
<p>There are several solutions to this problem, to name a few:</p>
<ul>
<li>Create a singleton class that holds one instance of <code>DOMDocument</code>, and use a wrapper method somewhere to either get a valid <code>DOMElement</code></li>
<li>Have all classes that produce XML nodes use a fake <code>DOMDocument</code>, and then use <a href='http://php.net/manual/en/domdocument.importnode.php'><code>DOMDocument::importNode()</code></a> at the return-point to import the nodes (very inefficient, especially when using a deep-copy).</li>
<li>Have the classes that produce XML nodes return nested arrays containing all name -> content relations of the nodes and run through them when it&#8217;s sensible to do so.</li>
</ul>
<p>I&#8217;ll leave it as an exercise to the reader to pick out the best method. I haven&#8217;t found a solution yet, but I hope to contact the DOM XML module maintainer and discuss this with him/her.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hatsuseno.org/index.php/php-and-xml-manipulation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
