<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/css/rss20.xsl" type="text/xsl"?>
<rss xmlns:pheedo="http://www.pheedo.com/namespace/pheedo" 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/">
	<channel>
		<title>SitePoint &#187; PHP</title>
		<atom:link href="http://www.sitepoint.com/blogs/category/php/feed/" rel="self" type="application/rss+xml"/>
		<link>http://www.sitepoint.com/blogs</link>
		<description>News, opinion, and fresh thinking for web developers and designers. The official podcast of sitepoint.com.</description>
		<pubDate>Wed, 07 Jan 2009 02:47:53 +0000</pubDate>
		<generator>http://wordpress.org/?v=2.7</generator>
		<language>en</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
		<item>
			<title>PHP Support in NetBeans 6.5</title>
			<link>http://www.pheedo.com/click.phdo?i=44750a51df5234502944360d455aaf16</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/12/16/php-support-in-netbeans-65/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/12/16/php-support-in-netbeans-65/#comments</comments>
			<pubDate>Tue, 16 Dec 2008 07:44:12 +0000</pubDate>
			<dc:creator>Kevin Yank</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=3337</guid>
			<description><![CDATA[Long dismissed as a "toy Java IDE", NetBeans - Sun's open source Integrated Development Environment (IDE) - has really grown up in recent years. No longer is it just for Java, either: for web developers, NetBeans 6.5 now supports Ruby and PHP out of the box.<br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=44750a51df5234502944360d455aaf16&p=1"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=44750a51df5234502944360d455aaf16&p=1"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=44750a51df5234502944360d455aaf16" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p><strong>Long dismissed as a “toy Java IDE”, <a href="http://www.netbeans.org/">NetBeans</a>—Sun’s open source Integrated Development Evironment (IDE)—has really grown up in recent years. No longer is it just for Java, either: for web developers, NetBeans 6.5 now supports Ruby and PHP out of the box. Surprisingly, that support is so good that it now compares favourably to more established competitors like <a href="http://www.eclipse.org/pdt/">Eclipse</a>, <a href="http://www.activestate.com/Products/komodo_ide/">Komodo IDE</a>, and <a href="http://www.zend.com/en/products/studio/">Zend Studio</a>.</strong></p>
<p>I had become used to writing my PHP code in a simple text editor (<a href="http://jedit.sourceforge.net/">jEdit</a>, if you’re wondering), so it had been awhile since I’d enjoyed the luxuries of project-wide code completion, code refactoring, and a full debugger. All of these and more are available in NetBeans 6.5.</p>
<p>NetBeans includes autocomplete not just for built-in functions…</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-builtin-1.png" alt="Screenshot showing the NetBeans code editor recognizing and autocompleting the str_repeat function built into PHP, along with pop-up documentation" border="0" width="450" height="317" /></p>
<p>but also for functions defined elsewhere in your project and included libraries:</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-custom.png" alt="Screenshot showing the NetBeans code editor recognizing and autocompleting the registerObserver method on a custom PHP class, along with pop-up documentation" border="0" width="450" height="288" /></p>
<p>In both cases, NetBeans picks up on <a href="http://www.phpdoc.org/">phpdoc</a> comments in your code and uses them to display pop-up documentation along with its autocomplete suggestions.</p>
<p>Once you select a code completion for a function or method, NetBeans assists you in filling in each parameter. When you’re done filling in one parameter, hit Enter to automatically move to the next parameter.</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-parameters.png" alt="Screenshot showing the NetBeans code editor with a box around the first parameter of a str_replace function call, to indicate it is selected for editing" border="0" width="450" height="56" /></p>
<p>NetBeans also comes with PHP code templates for developers who like to set coding speed records. For example, type <code>fnc</code> and then hit the Tab key. NetBeans will expand it into a full function declaration, and prompt you to fill in a function name, before placing your cursor in the function body:</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-template.png" alt="Screenshot showing the NetBeans code editor with a box around the function_name portion of a PHP function delcaration" border="0" width="450" height="47" /></p>
<p>Because having complete phpdoc documentation for your code makes coding in NetBeans so much easier, NetBeans will even assist you with writing your documentation! Place your cursor immediately above a function declaration, type <code>/**</code> and hit Enter. NetBeans will automatically generate a phpdoc comment with placeholders for each of the function’s parameters and its return value:</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-phpdoc.png" alt="Screenshot showing the NetBeans code editor having just auto-generated a phpdoc template based on a function declaration" border="0" width="450" height="128" /></p>
<p>NetBeans’s editor has plenty of other nice features, like variable name refactoring. When your text cursor is on a variable name, all other occurrences of that variable are highlighted in yellow. Type Ctrl+R and you can edit every occurrence of that variable name at once, to instantly rename it throughout the file:</p>
<p><img src="http://sitepointstatic.com/blogs/wp-content/uploads/2008/12/nb65php-rename.png" alt="Screenshot showing the NetBeans code editor with boxes around all three occurrences of the $testvalue variable, with the cursor positioned to indicate the second of these occurrences is currently being edited" border="0" width="450" height="59" /></p>
<div id="adz" class="vertical"></div><p>And of course you can ⌘-click (Ctrl-click on Windows) on any variable, function, or class name to jump immediately to the place where it was declared—even if it’s in another file of your project.</p>
<p>NetBeans 6.5 combines all this PHP editing power with full support for server-side debugging with the <a href="http://xdebug.org/">XDebug</a> PHP extension. You can set breakpoints in your scripts and step through your code line-by-line, inspecting the values of variables as you go.</p>
<p>Of course, writing PHP applications is more than just PHP code. You have to write HTML, CSS, and JavaScript code as well. When you do, you’ll be pleasantly surprised to find the same level of support for these languages built into NetBeans too! And when a single file mixes these languages together, NetBeans handles it all seamlessly.</p>
<p>If all those code editing features weren’t enough, NetBeans 6.5’s other core features combine to complete the experience. Built-in support for version control systems including CVS, Subversion, and Mercurial (with others, like Git, available as free plug-ins) is especially welcome, with colored bars along the sides of your code to indicate lines that you have changed since your last commit.</p>
<p>NetBeans isn’t a toy for learning Java anymore. These days, it’s a powerful, multi-language development environment that’s free for the taking. If you work on sizable PHP projects and you’re <em>not</em> using an IDE like NetBeans, you might be surprised at how much time a tool like this can save you!</p>
<p>You can learn about NetBeans’s PHP support and download the IDE from the <a href="http://www.netbeans.org/features/php/index.html">NetBeans PHP Development page</a>. And if you’re interested in following the new PHP-related features that are being worked on for the <em>next</em> version of NetBeans, be sure to follow the <a href="http://blogs.sun.com/netbeansphp/">NetBeans PHP Blog</a>.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script><br clear="both" style="clear: both;"/>
<br clear="both" style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=44750a51df5234502944360d455aaf16&p=1"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=44750a51df5234502944360d455aaf16&p=1"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=44750a51df5234502944360d455aaf16" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/12/16/php-support-in-netbeans-65/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Introducing php-tracer-weaver</title>
			<link>http://www.pheedo.com/click.phdo?i=f3b65874f70f9ad1480d3f2e3f8e30e9</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/12/08/introducing-php-tracer-weaver/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/12/08/introducing-php-tracer-weaver/#comments</comments>
			<pubDate>Sun, 07 Dec 2008 15:31:58 +0000</pubDate>
			<dc:creator>Troels Knak-Nielsen</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=3255</guid>
			<description><![CDATA[php-tracer-weaver is a tool for automatically generating docblock comments, with parameter types.<br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=f3b65874f70f9ad1480d3f2e3f8e30e9&p=1"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=f3b65874f70f9ad1480d3f2e3f8e30e9&p=1"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=f3b65874f70f9ad1480d3f2e3f8e30e9" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p>One of <a href="http://www.xdebug.org">xdebug</a>s lesser known features is its <a href="http://www.xdebug.org/docs/execution_trace">function traces</a>. In case you haven&#8217;t heard of it before, it <em>&#8220;allows you to log all function calls, including parameters and return values to a file&#8221;</em>, to quote the manual. After playing around with it for a while, I realised that this information could be parsed and used to determine parameter types and return types of functions.</p>
<p>So, as a proof on concept, I wrote a script to parse the function traces from xdebug and use this to process a php source-file, and inject docblock comments, with <code>@param</code> and <code>@return</code> tags. I had to combine the dynamic analysis (function traces) with some static analysis, to be able to collate different sub-types into their supertype, which made the whole deal a bit more complicated than first anticipated.</p>
<p>There are still some room for improvement, but last Thursday at the <a href="http://www.meetup.com/copenhagenphp/">local php meetup</a>, I demo&#8217;ed the project and it&#8217;s now available through <a href="http://github.com/troelskn/php-tracer-weaver/tree/master">github</a>.</p>
<p>The usage is split into two steps. First you run the code, using xdebug instrumentation to generate a trace. I&#8217;ve created a wrapper script to make this simpler. Just invoke the php script with <code>trace.sh foo.php</code>, rather than <code>php foo.php</code>. This will run the script as normal, while generating a trace in the file <code>dumpfile.xt</code>.</p>
<div id="adz" class="horizontal"></div><p>The intention is to use the tool together with an existing test-case. If you don&#8217;t use unit tests, you can just put a simple integration test together; The important thing is that the script should get around in all corners of the code, to generate a good basis for the analysis.</p>
<p>The next step is to analyse this data and use it to generate the docblock comments. This is done with the tool <code>weave.php</code>. You&#8217;d likely want to call weave.php multiple times (For each file in your project, that you want to generate documentation for).</p>
<p>Here&#8217;s an example, to show the process:</p>
<p>We&#8217;ll start with a very simple file, without any docblock comments:</p>
<pre><code>
&lt;?php

class Foo {
  function stuff($x) {
    return 42;
  }
}

class Bar {}

$f = new Foo();
$f-&gt;stuff(new Bar());
</code></pre>
<p>The first step is to run the file, using <code>trace.sh</code>:</p>
<pre><code>
$ /path/to/php-tracer/weaver/trace.sh foo.php
Running script with instrumentation: foo.php
TRACE COMPLETE
</code></pre>
<p>Next, we&#8217;ll weave the documentation back into the file:</p>
<pre><code>
$ /path/to/php-tracer/weaver/weave.php foo.php foo.php
</code></pre>
<p>And that&#8217;s it .. Our file now looks like this:</p>
<pre><code>
&lt;?php

class Foo {
  /**
    * @param Bar
    * @return integer
    */
  function stuff($x) {
    return 42;
  }
}

class Bar {}

$f = new Foo();
$f-&gt;stuff(new Bar());
</code></pre>
<p>The implementation is memory-efficient, rather than cpu-efficient, which means that it&#8217;ll work with large code bases, but it will take some time to process.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script><br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=f3b65874f70f9ad1480d3f2e3f8e30e9&p=1"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=f3b65874f70f9ad1480d3f2e3f8e30e9&p=1"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=f3b65874f70f9ad1480d3f2e3f8e30e9" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/12/08/introducing-php-tracer-weaver/feed/</wfw:commentRss>
		</item>
		<item>
			<title>How to Expose PHP&#8217;s Private Parts</title>
			<link>http://www.pheedo.com/click.phdo?i=6b3d4a334f714bb60d13c7ca02220dde</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/11/11/how-to-expose-phps-private-parts/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/11/11/how-to-expose-phps-private-parts/#comments</comments>
			<pubDate>Tue, 11 Nov 2008 06:47:32 +0000</pubDate>
			<dc:creator>Troels Knak-Nielsen</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=3169</guid>
			<description><![CDATA[I’ve been tinkering with dumping PHP objects, and have found myself constantly running into a brick wall. The output from print_r and friends is fine in some contexts, but for larger structures, it would be nice to tidy the output up a bit and wrap it in some HTML.<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=6b3d4a334f714bb60d13c7ca02220dde" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=6b3d4a334f714bb60d13c7ca02220dde" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been tinkering with dumping PHP objects, and have found myself constantly running into a brick wall. The output from <code><a href="http://docs.php.net/manual/en/function.print-r.php">print_r</a></code> and friends is fine in some contexts, but for larger structures, it would be nice to tidy the output up a bit and wrap it in some HTML. </p>
<p>However, these functions have a certain privilege in that they can access private/protected variables. This is not something that can be circumvented in plain PHP (save through some <a href="http://docs.php.net/runkit">exotic extensions</a>, which I&#8217;d rather not rely on). It seems that 5.3.0 may <a href="http://docs.php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionproperty">introduce a functionality</a> in the Reflection API, but nobody knows when 5.3.0 will be out.</p>
<p>So I realised that it is possible to serialize any object to a string, which will include private and protected variables alike. All I had to do was then to parse the serialized string, and I&#8217;d gain that arcane insight. One would perhaps assume that such a parser already exists. Maybe it does, but I couldn&#8217;t find it (I did find a <a href="http://code.google.com/p/serialized-php-parser/">Java implementation</a> though). The format is fairly simple though, so I spend half a Sunday afternoon on it. One very nice bonus, compared to <code>print_r</code> is that the format handles recursion, which is very handy<br />
for dumping the output in a presentable form.</p>
<p>So, without further ado, here&#8217;s the code:</p>
<div id="adz" class="horizontal"></div><pre><code class='php'>< ?php
/**
* Exports variable information, including private/protected variables
and with recursion-protection.
* Since this is built upon PHP serialization functionality,
unserializable objects may cause trouble.
*/
class XrayVision {
  protected $id;
  function export($object) {
    $this->id = 1;
    list($value, $input) = $this->parse(serialize($object));
    return $value;
  }
  protected function parse($input) {
    if (substr($input, 0, 2) === 'N;') {
      return array(array('type' => 'null', 'id' => $this->id++,
'value' => null), substr($input, 2));
    }
    $pos = strpos($input, ':');
    $type = substr($input, 0, $pos);
    $input = substr($input, $pos + 1);
    switch ($type) {
    case 's':
      return $this->s($input);
    case 'i':
      return $this->i($input);
    case 'd':
      return $this->d($input);
    case 'b':
      return $this->b($input);
    case 'O':
      return $this->o($input);
    case 'a':
      return $this->a($input);
    case 'r':
      return $this->r($input);
    }
    throw new Exception("Unhandled type '$type'");
  }
  protected function s($input) {
    $pos = strpos($input, ':');
    $length = substr($input, 0, $pos);
    $input = substr($input, $pos + 1);
    $value = substr($input, 1, $length);
    return array(array('type' => 'string', 'id' => $this->id++,
'value' => $value), substr($input, $length + 3));
  }
  protected function i($input) {
    $pos = strpos($input, ';');
    $value = (integer) substr($input, 0, $pos);
    return array(array('type' => 'integer', 'id' => $this->id++,
'value' => $value), substr($input, $pos + 1));
  }
  protected function d($input) {
    $pos = strpos($input, ';');
    $value = (float) substr($input, 0, $pos);
    return array(array('type' => 'float', 'id' => $this->id++, 'value'
=> $value), substr($input, $pos + 1));
  }
  protected function b($input) {
    $pos = strpos($input, ';');
    $value = substr($input, 0, $pos) === '1';
    return array(array('type' => 'boolean', 'id' => $this->id++,
'value' => $value), substr($input, $pos + 1));
  }
  protected function r($input) {
    $pos = strpos($input, ';');
    $value = (integer) substr($input, 0, $pos);
    return array(array('type' => 'recursion', 'id' => $this->id++,
'value' => $value), substr($input, $pos + 1));
  }
  protected function o($input) {
    $id = $this->id++;
    $pos = strpos($input, ':');
    $name_length = substr($input, 0, $pos);
    $input = substr($input, $pos + 1);
    $name = substr($input, 1, $name_length);
    $input = substr($input, $name_length + 3);
    $pos = strpos($input, ':');
    $length = (int) substr($input, 0, $pos);
    $input = substr($input, $pos + 2);
    $values = array();
    for ($ii=0; $ii < $length; $ii++) {
      list($key, $input) = $this->parse($input);
      $this->id--;
      list($value, $input) = $this->parse($input);
      if (substr($key['value'], 0, 3) === "\000*\000") {
        $values['protected:' . substr($key['value'], 3)] = $value;
      } elseif ($pos = strrpos($key['value'], "\000")) {
        $values['private:' . substr($key['value'], $pos + 1)] = $value;
      } else {
        $values[str_replace("\000", ':', $key['value'])] = $value;
      }
    }
    return array(
      array('type' => 'object', 'id' => $id, 'class' => $name, 'value'
=> $values),
      substr($input, 1));
  }
  protected function a($input) {
    $id = $this->id++;
    $pos = strpos($input, ':');
    $length = (int) substr($input, 0, $pos);
    $input = substr($input, $pos + 2);
    $values = array();
    for ($ii=0; $ii < $length; $ii++) {
      list($key, $input) = $this->parse($input);
      $this->id--;
      list($value, $input) = $this->parse($input);
      $values[$key['value']] = $value;
    }
    return array(
      array('type' => 'array', 'id' => $id, 'value' => $values),
      substr($input, 1));
  }
}
?></code></pre>
<p>There are at least two known issues with this technique. The first is that resources are serialized into integers. For a dump, this doesn&#8217;t really matter, since a resource is meaningless outside the running process. The other problem is with objects that implements <code><a href="http://docs.php.net/manual/en/language.oop.magic-functions.php">__sleep</a></code>. Since this function may have side-effects, you can potentially mess up your program for objects that use this feature. In my experience, it&#8217;s a seldom used functionality anyway, so it doesn&#8217;t really bother me that much.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script><br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=6b3d4a334f714bb60d13c7ca02220dde" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=6b3d4a334f714bb60d13c7ca02220dde" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/11/11/how-to-expose-phps-private-parts/feed/</wfw:commentRss>
		</item>
		<item>
			<title>DOM vs. Template</title>
			<link>http://www.pheedo.com/click.phdo?i=d87d9a59b65950a2cb059df2fc62a756</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/09/25/dom-vs-template/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/09/25/dom-vs-template/#comments</comments>
			<pubDate>Wed, 24 Sep 2008 22:04:07 +0000</pubDate>
			<dc:creator>Troels Knak-Nielsen</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=3025</guid>
			<description><![CDATA[Fredrik Holmström recently posted a small template engine, based on DOM-manipulation. While there are certainly a lot of template engines around, I find this approach interesting. The concept is simple enough; The template is parsed into an object model (DOM), and then values can be assigned to these through PHP code. The main difference to [...]<br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=d87d9a59b65950a2cb059df2fc62a756"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=d87d9a59b65950a2cb059df2fc62a756"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=d87d9a59b65950a2cb059df2fc62a756" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://loveandtheft.org/2008/09/17/pquery-messing-with-the-dom-from-php/">Fredrik Holmström recently posted a small template engine</a>, based on DOM-manipulation. While there are certainly a lot of template engines around, I find this approach interesting. The concept is simple enough; The template is parsed into an object model (<a href="http://en.wikipedia.org/wiki/Document_Object_Model">DOM</a>), and then values can be assigned to these through PHP code. The main difference to traditional template engines (Such as <a href="http://www.smarty.net/">Smarty</a>), is that the template it self doesn&#8217;t have any imperatives within. In fact, the template doesn&#8217;t even have to be written to the template engine, to be used - Any markup can be used as a source.</p>
<p>Since the template can&#8217;t contain any view-logic, it ends up in a separate place (In PHP code). This makes the separation between presentation and logic airtight, which was the main idea of template engines in the first place. Another benefit is that since there is no string-level manipulation, it is virtually impossible to inadvertently get injections-type security breaches.</p>
<p>The template may be unaware of the view-logic, but the opposite can&#8217;t be said. To bind values to the template, the view-logic needs to be aware of the internal structure of the template. This means that if the template changes, so must the view-logic. To decouple this dependency, we need some kind of abstraction.</p>
<p>Luckily it just so happens that there is a very convenient mechanism for that; Element <em>id</em>&#8217;s can be used to address central nodes in the markup. They do however have the rather annoying limitation (For this use), <a href="http://www.w3.org/TR/REC-html40/struct/global.html#adef-id">that they must be globally unique to the document</a>. A better candidate then, is to use classes (The HTML attribute - I&#8217;m not talking of PHP classes) to address elements.</p>
<div id="adz" class="horizontal"></div><p>The really nice thing about using classes is that it&#8217;s very unobtrusive to the markup. One will have to add classes, but since they would have to go on central elements in the markup, they would be prime candidates for reusing as fix points for CSS rules and for Javascript code. Instead of being superfluous markers in the HTML code, they actively help to write better markup.</p>
<p>That sounds good in theory, so to see how it holds out in reality, I mocked together a small prototype. Even with a very limited API, it has a remarkably good expressiveness:</p>
<h4>Simple variable binding</h4>
<pre><code class="php">
$t = new Domling('&lt;p class="hello"&gt;&lt;/p&gt;');
$t-&gt;capture('hello')-&gt;bind("Hello World");
echo $t-&gt;render();
</code></pre>
<pre><code class="html">
&lt;p class="hello"&gt;Hello World&lt;/p&gt;
</code></pre>
<h4>Switching a block out</h4>
<pre><code class='php'>
$t = new Domling('&lt;p&gt;Lorem Ipsum&lt;/p&gt;&lt;p class="message"&gt;Hidden message&lt;/p&gt;');
$t-&gt;capture('message');
echo $t-&gt;render();
</code></pre>
<pre><code class="html">
&lt;p&gt;Lorem Ipsum&lt;/p&gt;
</code></pre>
<h4>Putting it back in</h4>
<pre><code class="php">
$t = new Domling('&lt;p&gt;Lorem Ipsum&lt;/p&gt;&lt;p class="message"&gt;Hidden message&lt;/p&gt;');
$block = $t-&gt;capture('message');
$block-&gt;bind();
echo $t-&gt;render();
</code></pre>
<pre><code class="html">
&lt;p&gt;Lorem Ipsum&lt;/p&gt;
&lt;p class="message"&gt;Hidden message&lt;/p&gt;
</code></pre>
<h4>And looping over a block</h4>
<pre><code class="php">
$t = new Domling('&lt;ul class="links"&gt;&lt;li class="link"&gt;&lt;a class="anchor" href="#"&gt;title&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;');
$links = array(
  'Sitepoint' =&gt; 'http://www.sitepoint.com',
  'Example' =&gt; 'http://www.example.org?foo=bar&amp;ding=dong');
foreach ($links as $title =&gt; $link) {
  $t-&gt;sequence('link', 'links')-&gt;bind(array('anchor:href' =&gt; $link, 'anchor' =&gt; $title));
}
echo $t-&gt;render();
</code></pre>
<pre><code class="html">
&lt;ul class="links"&gt;
&lt;li class="link"&gt;&lt;a class="anchor" href="http://www.sitepoint.com"&gt;Sitepoint&lt;/a&gt;&lt;/li&gt;
&lt;li class="link"&gt;&lt;a class="anchor" href="http://www.example.org?foo=bar&amp;amp;ding=dong"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>If you&#8217;re curious, you can get the full source code for the above examples from here: <a href="http://php.pastebin.com/f76ba8d70">http://php.pastebin.com/f76ba8d70</a></p>
<p>But please mind that this is just a proof-of-concept; There are probably a few quirks that should be ironed out before this could be used in production.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script><br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=d87d9a59b65950a2cb059df2fc62a756"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=d87d9a59b65950a2cb059df2fc62a756"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=d87d9a59b65950a2cb059df2fc62a756" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/09/25/dom-vs-template/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Character Encoding: Issues with Cultural Integration</title>
			<link>http://www.pheedo.com/click.phdo?i=8d25c624a4e588f91c719538ea23d4d8</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/09/10/issues-with-cultural-integration/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/09/10/issues-with-cultural-integration/#comments</comments>
			<pubDate>Tue, 09 Sep 2008 23:23:34 +0000</pubDate>
			<dc:creator>Troels Knak-Nielsen</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2969</guid>
			<description><![CDATA[Ever been stuck trying to shoehorn UTF-8 encoded strings into a Latin1 character set? Troels encountered this problem recently, and this is how he tackled it.<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=8d25c624a4e588f91c719538ea23d4d8" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=8d25c624a4e588f91c719538ea23d4d8" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve run into a classic problem with charsets, in an application I&#8217;m currently working on. As is the standard for PHP, all strings are treated as <a href="http://en.wikipedia.org/wiki/ISO_8859-1">latin1</a>, but we now need to allow a wider range of charsets in a few places.</p>
<p>The gold standard solution is to convert everything to utf-8. Since utf-8 covers the entire <a href="http://www.unicode.org/standard/WhatIsUnicode.html">unicode</a> range, it is capable of representing any character that latin1 can. Unfortunately, that&#8217;s a lot easier to do from the outset, than with a big, running application. And even then, there may be third party code and extensions, which assume latin1. I&#8217;d much rather continue with latin1 being the default, and only jump through hoops at the few places where I actually need full utf-8 capacity.</p>
<p>So after some thinking, another solution dawned on me. To be fair, <em>hack</em> is probably more descriptive than <em>solution</em>, but nonetheless. The idea goes as follows:</p>
<ul>
<li>Use latin1, but serve pages in utf-8, encoding it at output.</li>
<li>Embed utf-8 strings within latin1, and somehow don&#8217;t encode it (But still encode everything else).</li>
</ul>
<div id="adz" class="horizontal"></div><p>Simple, eh?</p>
<h2>Latin1 on the inside, utf-8 on the outside.</h2>
<p>When rendering HTML pages, it is trivial to capture the output with an <a href="http://www.php.net/outcontrol">output buffer</a> and pipe it through <a href="http://www.php.net/manual/en/function.utf8-encode.php">utf8_encode</a>. The page is thus served in utf-8, even though everything internally is latin1. Not much gain in that, since it still restricts us to use the range of characters covered by latin1.<br />
We are actually already doing this, simply to reduce the number of problems for external services communicating with our system. In particular, <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XmlHttpRequest</a> defaults to utf-8, regardless of the page&#8217;s encoding.</p>
<p>In essence, the following snippet exemplifies:</p>
<pre><code>
// declare that the output will be in utf-8
header("Content-Type: text/html; charset=utf-8");
// open an output buffer, capturing all output
ob_start('output_handler');
// when the script ends, the buffer is piped through this functions, encoding it from latin1 to utf-8
function output_handler($buffer) {
  return utf8_encode($buffer);
}
</code></pre>
<h2>Embed utf-8 within latin1.</h2>
<p>This is the tricky part. Instead of simply piping the entire buffer through utf8_encode, the string can be parsed so anything between a set of special tags (Eg. <code>[[charset:utf8]] ... [[/charset:utf8]]</code>) is left as-is, while the rest is assumed to be latin1 and encoded with utf8_encode as before. This ensures full backwards compatibility, while allowing real utf-8.</p>
<p>Let&#8217;s modify our output-handler from before:</p>
<pre><code>
header("Content-Type: text/html; charset=utf-8");
ob_start('output_handler');
function output_handler($buffer) {
  return preg_replace_callback(
    '~\[\[charset:utf8\]\](.*?)\[\[/charset:utf8\]\]~',
    'utf8_decode_first',
    utf8_encode($buffer));
}
function utf8_decode_first($match) {
  return utf8_decode($match[1]);
}
</code></pre>
<p>And that&#8217;s it. We can now embed full utf-8 strings within our otherwise latin1-encoded application, by wrapping it with <code>[[chaset:utf8]]</code>. To make things a bit more readable, I added a helper function:</p>
<pre><code>
function utf8($utf8_encoded_byte_stream) {
  return '[[charset:utf8]]' . $utf8_encoded_byte_stream . '[[/charset:utf8]]';
}
</code></pre>
<p>And we can now construct a string as simple as:</p>
<pre><code>
echo utf8("blÃ¥bÃ¦r") . "grød";
</code></pre>
<p>To produce the output: <strong>blåbærgrød</strong></p>
<p>
<b>note:</b> As pointed out by <a href="#comment-793844">Kore</a>, it would be a problem if the delimiter itself (Eg. <code>[[charset:utf8]]</code>) is part of the data. To remedy this, it would be safer to use a more unique delimiter. You could simply replace <code>charset:utf8</code> with something that is unlikely to ever happen. It&#8217;s still not completely bulletproof, but it&#8217;s good enough for most practical uses.
</p>
<h2>Handling input.</h2>
<p>You may or may not know this, but when submitting a form, browsers send back data in the same encoding as the page was served. Since our application is predominantly latin1, we need user-input to be latin1, to keep <abbr title="Backwards compatibility">BC</abbr>. So all input must be decoded from utf-8 to latin1. This is simple enough; We just have to pipe all user-input ($_GET, $_POST etc.) through <a href="http://www.php.net/manual/en/function.utf8-decode.php">utf8_decode</a>. Since we already run with the latin1-on-the-inside-utf-8-on-the-outside scheme, this was already in place in our case.</p>
<p>This does however give a problem when the user needs to submit utf-8, as our users would need when replying to mails. So in these places, we would have to explicitly access the &#8220;raw&#8221; string, through an alternate mechanism. In our case, we needed to modify our http-request wrapper, but since this is extending the API, there is no BC problems.</p>
<p>With the advent of PHP6, perhaps such hacks won&#8217;t be necessary in the future, but for now this gives a working, unobtrusive solution.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script><br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=8d25c624a4e588f91c719538ea23d4d8" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=8d25c624a4e588f91c719538ea23d4d8" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/09/10/issues-with-cultural-integration/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Rasmus Lerdorf: PHP Frameworks? Think Again.</title>
			<link>http://www.pheedo.com/click.phdo?i=bd69f41062fdfd5362bf5c5295add7ef</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/08/29/rasmus-lerdorf-php-frameworks-think-again/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/08/29/rasmus-lerdorf-php-frameworks-think-again/#comments</comments>
			<pubDate>Thu, 28 Aug 2008 16:10:56 +0000</pubDate>
			<dc:creator>david.seth.p</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2914</guid>
			<description><![CDATA[ This is the fist time I have heard Rasmus Lerdorf speak and it was entertaining to say the least. Refreshing would another way to describe it, I enjoy hearing real opinions and not holding back &#8212; Rasmus doesn&#8217;t hold back. 
Just a short background, Rasmus Lerdorf is the creator of PHP and still continues [...]<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=bd69f41062fdfd5362bf5c5295add7ef" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=bd69f41062fdfd5362bf5c5295add7ef" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p><img style="0px 0px 0px 10px" src="http://szeged2008.drupalcon.org/files/Rasmus.jpg" align="right" /> This is the fist time I have heard <a href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf">Rasmus Lerdorf</a> speak and it was entertaining to say the least. Refreshing would another way to describe it, I enjoy hearing real opinions and not holding back &#8212; Rasmus doesn&#8217;t hold back. </p>
<p>Just a short background, Rasmus Lerdorf is the creator of PHP and still continues as a core developer to the PHP project. </p>
<p><strong>PHP frameworks</strong></p>
<p>In his address he choose to highlight PHP frameworks (Drupal was not spared) and how poor they are at performance. Not only are they slow, but their &quot;jack-of-all-trades&quot; attitude leads developers down the wrong path by not using what is best for the job. He continues on by stating that PHP developers really need to think about performance for not only scalability reasons but for green reasons. If programs were more efficient it would cut the number of data centres and would reduce energy needs as a result. In our newly emerging age of energy awareness this does become an important aspect and I am glad that he is raising awareness.</p>
<div id="adz" class="vertical"></div><p>Back to frameworks, he started by discussing a database heavy Twitter mashup that he created. This does a lot of database calls and a lot of behind the scenes work. By hand-tuning it he was able to get on the order of 280 req/sec. By comparison and simple HTML page with nothing but &quot;Hello World&quot; served by Apache is just over 600 req/sec. Okay, stage is set (by the way, this was tested on his local machine).</p>
<p><strong>Hello World</strong></p>
<p>How do PHP frameworks score on the &quot;Hello World&quot; test? No database calls, just the framework being used in its native tongue to output Hello World. The results were not too good, one of the fastest got just over 120 req/sec, the slowest was 8 req/sec. This is a dramatic difference and of course highlights his argument for performance. Where did Drupal score? Right above 50 req/sec. So not the greatest, but he did make the point that Drupal is not really a framework in the traditional sense. It is a web content management system that can be quickly extended.</p>
<p>So, are there any frameworks that don&#8217;t suck? Rasmus did mention that he liked <a href="http://codeigniter.com/">CodeIgniter</a> because it is faster, lighter and the least like a framework.</p>
<p><strong>How to make PHP fast</strong></p>
<p>&quot;Well, you can&#8217;t&quot; was his quick answer. PHP is simply not fast enough to scale to Yahoo levels. PHP was never meant for those sorts of tasks. &quot;Any script based language is simply not fast enough&quot;. To get the speed that is necessary for truly massive web systems you have to use compiled C++ extensions to get true, scaleable architecture. That is what Yahoo does and so do many other PHP heavyweights.</p>
<p><strong>RDF, Semantic Web and the Monkey</strong></p>
<p>RDF in Drupal. Rasmus made a special point of highlighting the importance of embedding structured    metadata into the page. RDFa allows you to embed data into your web pages and also lets you create custom vocabularies, or even better, reuse existing vocabularies. Why would you want to do this? Searchmonkey will go out and index this content and open up a rich search API to allow you to do intelligent queries. Well beyond what is possible with traditional search. </p>
<p>Along with rich search you also get enhanced search results. I have blogged about this previously so take a <a href="http://www.sitepoint.com/blogs/2008/03/16/why-rdfa-is-the-only-web-scaleable-metadata-format-for-next-generation-search-engines/">look</a>. It is really cool stuff and I will be discussing it in much more detail over the course of the conference.</p>
<p><strong>Pitching the Semantic Web</strong></p>
<p>What if all Drupal sites had embedded RDFa tags? Well, for one, Yahoo would be very happy. It would play directly into the strengths of Yahoo&#8217;s new Semantic Web strategy. They are trying to do interesting things with semantic data but of course they need data &#8212; the classic chicken and egg thing.</p>
<p>Rasmus mentioned that Yahoo&#8217;s semantic data store can scale to the size of the web so the invitation is open. </p>
<p><strong>The future of Drupal</strong></p>
<p>This is where my focus at Drupalcon is, driving the adoption of semantic technologies within Drupal &#8212; I feel that the momentum here will make that a reality. There is a lot of interest, a Semantic Web BoF session was stacked with people with some cool ideas&#8230;</p>
<p>More to come.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script><br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=bd69f41062fdfd5362bf5c5295add7ef" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=bd69f41062fdfd5362bf5c5295add7ef" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/08/29/rasmus-lerdorf-php-frameworks-think-again/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Mangling XML as Text with PHP DOM</title>
			<link>http://www.pheedo.com/click.phdo?i=ef04dcb7d2896c483a85e565bbdb7d5a</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/07/24/mangling-xml-as-text-with-php-dom/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/07/24/mangling-xml-as-text-with-php-dom/#comments</comments>
			<pubDate>Thu, 24 Jul 2008 06:46:09 +0000</pubDate>
			<dc:creator>brothercake</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2703</guid>
			<description><![CDATA[
Recently I had to do some mass-conversion of HTML files to DITA XML &#8212; material I&#8217;d written for the upcoming JavaScript Ultimate Reference (the third, and arguably most complicated, part of the SitePoint Reference).


But a problem I came across several times was the sheer complexity of recursive element conversion &#8212; &#60;code&#62; becomes &#60;jsvalue&#62; (or one [...]<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=ef04dcb7d2896c483a85e565bbdb7d5a" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=ef04dcb7d2896c483a85e565bbdb7d5a" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p>
Recently I had to do some mass-conversion of <abbr title="HyperText Markup Language">HTML</abbr> files to <a href="http://dita.xml.org/">DITA XML</a> &#8212; material I&#8217;d written for the upcoming JavaScript Ultimate Reference (the third, and arguably most complicated, part of the <a href="http://reference.sitepoint.com/">SitePoint Reference</a>).
</p>
<p>
But a problem I came across several times was the sheer complexity of recursive element conversion &#8212; <code>&lt;code&gt;</code> becomes <code>&lt;jsvalue&gt;</code> (or one of a dozen similar elements), <code>&lt;a&gt;</code> becomes <code>&lt;xref&gt;</code> &#8230; and that&#8217;s all simple enough; but each of these elements might contain the other, or further child elements like <code>&lt;em&gt;</code>, and as we walk through the <abbr title="Document Object Model">DOM</abbr> so the incidence of potential recursion increases, until it gets to the point where my brain explodes.
</p>
<p>
There&#8217;s a limit to how much recursion I can get my head around &#8212; or rather &#8212; a limit to how much I&#8217;m <em>prepared</em> to get my head around before I just go <q>the heck with this, why can&#8217;t I mangle it as text with regular expressions!?</q>
</p>
<p>
Unfortunately there doesn&#8217;t seem to be a way with <abbr title="HyperText Pre-Processor">PHP</abbr> <abbr title="Document Object Model">DOM</abbr> to get the text equivalent of any arbitrary node, but we can do that at the <code>Document</code> or <code>DocumentFragment</code> level; so with a little toying-around I came up with a way to leverage that capability and make it work at the <code>Node</code> level.
</p>
<p>So for example, let&#8217;s begin with this <abbr title="eXtensible Markup Language">XML</abbr>:</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;root id="introduction"&gt;
	&lt;div class="section"&gt;
		The fundamental data type is &lt;code&gt;Node&lt;/code&gt;
	&lt;/div&gt;
&lt;/root&gt;</code></pre>
<p>We have a reference to its <abbr title="Document Object Model">DOM</abbr> saved to a <abbr title="HyperText Pre-Processor">PHP</abbr> variable called <code>$xmldom</code>. And we want to parse it so that the <code>&lt;code&gt;</code> element becomes a <code>&lt;jstype&gt;</code>, and the <code>&lt;div class="section"&gt;</code> becomes simply <code>&lt;section&gt;</code>, all without affecting the rest of the document.</p>
<p>Here&#8217;s the complete code to do it, which I&#8217;ll then talk through stage by stage:</p>
<pre><code>$node = $xmldom-&gt;documentElement-&gt;firstChild;

$doc = new DOMDocument();
$doc-&gt;loadXML('&lt;xmltext/&gt;');
$node = $doc-&gt;importNode($node, true);
$doc-&gt;documentElement-&gt;appendChild($node);
$xmltext = ereg_replace('^.*&lt;xmltext&gt;(.*)&lt;\/xmltext&gt;.*$', '\\1', $doc-&gt;saveXML());

$xmltext = ereg_replace('&lt;([\/]?)code&gt;', '&lt;\\1jstype&gt;', $xmltext);
$xmltext = ereg_replace('&lt;([\/]?)div[^&gt;]*&gt;', '&lt;\\1section&gt;', $xmltext);

$node = $xmldom-&gt;createDocumentFragment();
$node-&gt;appendXML($xmltext);

$xmldom-&gt;documentElement-&gt;replaceChild($node, $xmldom-&gt;documentElement-&gt;firstChild);</code></pre>
<p>
In the first step we get a reference to the element we want to work with, and save it to <code>$node</code>.
</p>
<div id="adz" class="vertical"></div><p>
In the second step we create a new document, and use <code>loadXML()</code> to create a placeholder root node (the <a href="http://au.php.net/manual/en/domdocument.loadxml.php"><code>loadXML</code>  method</a> converts text input to <abbr title="eXtensible Markup Language">XML</abbr>, and is one of the cornerstones of our process). Next we import the original node into that document, then use <code>saveXML()</code> to convert the whole document to text (the <a href="http://au.php.net/manual/en/domdocument.savexml.php"><code>saveXML</code> method</a> converts an XML document to text, and is as critical as <code>loadXML()</code> for what we&#8217;re doing here). The text output is parsed using <a href="http://au.php.net/manual/en/function.ereg-replace.php"><code>ereg_replace</code></a> to remove the outer contents of the document (its prolog and root node) so that we&#8217;re left with a text equivalent of the original input node.
</p>
<p>
In the third step we do whatever text-based mangling we need; in this case it&#8217;s simple element name conversions, but it could be anything.
</p>
<p>
In the fourth step we want to convert our parsed text back into <abbr title="eXtensible Markup Language">XML</abbr>, and we do this by creating a document fragment, then using <code>appendXML()</code> to load the text and have it converted to <abbr title="eXtensible Markup Language">XML</abbr> (the <a href="http://au.php.net/manual/en/domdocumentfragment.appendxml.php"><code>appendXML</code> method</a> does the same thing as <code>loadXML()</code>, but it doesn&#8217;t require an entire document to be created).
</p>
<p>
Finally, in the fifth step we merge the processed <abbr title="eXtensible Markup Language">XML</abbr> back into our original document. The document fragment has the original document as its owner, so we can simply use the <a href="http://au.php.net/manual/en/domnode.replacechild.php"><code>replaceChild</code></a> method to replace the original node and its children with the processed version. (Whenever a document fragment is added to a document, only its children are actually added, the document fragment itself is discarded; <code>DocumentFragment</code> is a virtual construct and never actually appears in a document.)
</p>
<p>
Both the first and the final step are arbitrary &#8212; we could work with an entire document, or just a single node, and edit our referencing and merging statements accordingly. Or we could build a method from the inner steps, which accepts <code>$node</code> as an argument (and maybe an array of replacement expressions), and returns the processed node at the end:
</p>
<pre><code>function mangleXML($node)
{
	...
	
	return $node;
}</code></pre>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script><br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=ef04dcb7d2896c483a85e565bbdb7d5a" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=ef04dcb7d2896c483a85e565bbdb7d5a" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/07/24/mangling-xml-as-text-with-php-dom/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Keeping Current With PHP</title>
			<link>http://www.pheedo.com/click.phdo?i=bdb2ba25ef4890adc5ad6c928a5855e2</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/07/16/keeping-current-with-php/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/07/16/keeping-current-with-php/#comments</comments>
			<pubDate>Tue, 15 Jul 2008 23:09:08 +0000</pubDate>
			<dc:creator>Troels Knak-Nielsen</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2653</guid>
			<description><![CDATA[Just a quick hint to people with an interest in the development of PHP, but no time for following php-internals. Since March, there has been a wiki at wiki.php.net. The most interesting section is probably wiki.php.net/rfc, which - as the name implies - contains RFC&#8217;s for improvements of the language. I&#8217;ve rambled on about closures [...]<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=bdb2ba25ef4890adc5ad6c928a5855e2" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=bdb2ba25ef4890adc5ad6c928a5855e2" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p>Just a quick hint to people with an interest in the development of PHP, but no time for following <a href="http://news.php.net/php.internals">php-internals</a>. Since March, there has been a wiki at wiki.php.net. The most interesting section is probably <a href="http://wiki.php.net/rfc">wiki.php.net/rfc</a>, which - as the name implies - contains <a href="http://en.wikipedia.org/wiki/Request_for_Comments" title="Request for Comments">RFC</a>&#8217;s for improvements of the language. <a href="http://www.sitepoint.com/blogs/2007/12/23/lexical-scope-to-appear-in-php/">I&#8217;ve rambled on about closures and lambdas</a> before, but as you can see, there is now an accepted <a href="http://wiki.php.net/rfc#accepted">patch</a>. Whether it&#8217;ll make it into 5.3 is unlikely at this point, but it looks like it&#8217;ll at least be coming with 5.4 and/or 6.0.</p>
<p>While we&#8217;re at it, <a href="http://devzone.zend.com/member/83-steph-fox-staff">Steph Fox</a> have dutifully been writing up <a href="http://devzone.zend.com/tag/Weekly_Summaries">summaries of php-internals discussions</a> on a weekly basis since the beginning of time. If you just want to get the headlines, it&#8217;s an informative read.</p>
<p>Have a nice summer.</p>
<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=bdb2ba25ef4890adc5ad6c928a5855e2" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=bdb2ba25ef4890adc5ad6c928a5855e2" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/07/16/keeping-current-with-php/feed/</wfw:commentRss>
		</item>
		<item>
			<title>Last we checked, PHP IS a framework.</title>
			<link>http://www.pheedo.com/click.phdo?i=173e105a2fad6c2e33827b99d107dcc6</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/06/08/last-we-checked-php-is-a-framework/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/06/08/last-we-checked-php-is-a-framework/#comments</comments>
			<pubDate>Sun, 08 Jun 2008 04:18:58 +0000</pubDate>
			<dc:creator>Akash Mehta</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2539</guid>
			<description><![CDATA[When it comes to web programming languages, PHP probably holds the record for copping criticism from the community at large. Comparisons with alternatives such as Ruby on Rails and Python/Django are common; defenders of PHP are quick to criticise the comparison of a language and a framework. But at the end of the day, developers [...]<br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=173e105a2fad6c2e33827b99d107dcc6" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=173e105a2fad6c2e33827b99d107dcc6" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.sitepoint.com/blogs/wp-content/uploads/2008/06/phpframework1.jpeg" alt="" width="130" height="70" class="imgright" />When it comes to web programming languages, PHP probably holds the record for copping criticism from the community at large. Comparisons with alternatives such as Ruby on Rails and Python/Django are common; defenders of PHP are quick to criticise the comparison of a language and a framework. But at the end of the day, developers work with Ruby on Rails, and with Python/Django, and with PHP. Just PHP. For most of the PHP applications out there, the language is just perfect, because PHP, to an extent, <em>is</em> the framework.</p>
<p>PHP is designed for the web. You could plug vanilla Ruby or Python into a web server and get up and running pretty quickly. But, at least at a basic level, you&#8217;d want a framework to deal with common issues of web development. In PHP, you just get started. PHP and Apache work out request data, output handling and more, right out of the box. (<a href="http://www.sitepoint.com/blogs/2008/01/13/what-php-deployment-gets-right-ian-bicking-nails-it-at-last/">PHP also masters deployment.</a>) David Heinemeier Hanson, the creator of the Ruby on Rails framework, <a href="http://www.loudthinking.com/posts/23-the-immediacy-of-php">calls this the immediacy of PHP</a>.</p>
<p>Now, consider the &#8220;average&#8221; PHP frameworks. They help you handle request data, manage your output, control app flow - essentially, extending PHP&#8217;s inbuilt functionality. They are, therefore, PHP frameworks on the PHP framework. PHP provides a vast array (pardon the pun) of functionality out of the box. But when you want to do things your way, it gets out of the way, and this is really important when building anything beyond a simple database frontend.</p>
<p>How many PHP applications in wide distribution are built on a third-party framework? MediaWiki? No framework here. Wordpress? Not here either. Drupal? You get the idea. Each of these applications have their own framework, inasfar that the developers built a structure for their code that suited what they were trying to create. These three, and the countless others, clearly did something right - MediaWiki even powers <a href="http://en.wikipedia.org/">one of the world&#8217;s top 10 websites</a>. And when building these &#8220;frameworks&#8221;, PHP helped them along the way.</p>
<div id="adz" class="vertical"></div><p>Sure, Cake, Symfony, CI - they all help you build PHP applications. But unlike a Ruby framework or a Python framework, coding is perfectly tolerable without them. Of course, most developers tend to create their own framework as they go along - I call this PHP&#8217;s <em>DIY framework</em> mentality, where you build the last level in your stack, and by extension you know exactly what&#8217;s going on under the hood.</p>
<p>This comes back to the oft-cited &#8220;best tool for the job&#8221; argument - but by being a &#8220;half framework&#8221; of sorts, PHP simply helps you within a web context. I&#8217;m sure Rails is great for countless applications; Ruby syntax helps a little too. But beyond the basics, the language becomes increasingly irrelevant, and a framework will force you to build your app according to design decisions made by the original developers. On the other hand, PHP allows you to quickly put together your application the way you want, helping you with the web-based aspect, and <a href="http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html">without having to break the language/framework to achieve your goals</a>. Essentially, <em>PHP is the web layer without the framework baggage.</em></p>
<p>Twitter <a href="http://www.sitepoint.com/blogs/2008/06/06/did-rails-sink-twitter/">recently had some downtime that could be attributed to its use of Ruby on Rails</a>. Now, there&#8217;s nothing wrong with Ruby, or Rails. But Twitter is a messaging system, RoR is an application framework. Could Rails be worked around to suit Twitter? Maybe. Could Twitter have avoided these problems if they&#8217;d used PHP? Probably. Twitter&#8217;s developers have noted they weren&#8217;t quite expecting the site to be so succesful. If they had built it in PHP, they would probably have encountered other (similar) problems earlier on, rewritten the entire app while it was still feasible, and built a powerful system that could scale just fine (likely with the messaging platform in C). Using PHP could have helped, not as a language with syntax and libraries as such, but as a web development platform that gives developers the freedom to architect their systems as they want. (<a href="http://www.facebook.com/notes.php?id=9445547199">They could also have tried Erlang</a>.)</p>
<p>So the next time you&#8217;re on the lookout for a PHP framework to build your killer app on, consider using the best framework of them all: PHP. It will give you the freedom to achieve what you want, how you want, with results. A quick hack? Check the manual, it could be a one-liner. A massive distributed messaging platform? Full steam ahead, build it your way. For everything in between, there&#8217;s a multitude of options, but if you have the time, PHP is all the framework you need.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script><br style="clear: both;"/>
<img alt="" style="border: 0; height:1px; width:1px;" border="0" src="http://www.pheedo.com/img.phdo?i=173e105a2fad6c2e33827b99d107dcc6" height="1" width="1"/>
<img src="http://www.pheedo.com/feeds/tracker.php?i=173e105a2fad6c2e33827b99d107dcc6" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/06/08/last-we-checked-php-is-a-framework/feed/</wfw:commentRss>
		</item>
		<item>
			<title>PHPBench.com: Live PHP benchmarks, demystifying &#8220;best practices&#8221;</title>
			<link>http://www.pheedo.com/click.phdo?i=a06ea5a1e71de340a404c4494d15a4e2</link>
			<pheedo:origLink>http://www.sitepoint.com/blogs/2008/06/02/phpbench-live-php-benchmarks-best-practices/</pheedo:origLink>
			<comments>http://www.sitepoint.com/blogs/2008/06/02/phpbench-live-php-benchmarks-best-practices/#comments</comments>
			<pubDate>Mon, 02 Jun 2008 11:49:39 +0000</pubDate>
			<dc:creator>Akash Mehta</dc:creator>
			<category><![CDATA[PHP]]></category>
			<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=2522</guid>
			<description><![CDATA[As a new contributor to the SitePoint blogs, I&#8217;ll be covering PHP web development, JavaScript and general web tech.
When it comes to optimizing PHP for performance, there&#8217;s no end of resources available, and no end of conflicting opinions either. Everyone seems to have their own approach to writing &#8220;fast&#8221; PHP code; using single quotes, avoiding [...]<br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=a06ea5a1e71de340a404c4494d15a4e2"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=a06ea5a1e71de340a404c4494d15a4e2"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=a06ea5a1e71de340a404c4494d15a4e2" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></description>
			<content:encoded><![CDATA[<p><em>As a new contributor to the SitePoint blogs, I&#8217;ll be covering PHP web development, JavaScript and general web tech.</em></p>
<p>When it comes to optimizing PHP for performance, there&#8217;s <a href="http://reinholdweber.com/?p=3">no</a> <a href="http://phplens.com/lens/php-book/optimizing-debugging-php.php">end</a> <a href="http://www.moskalyuk.com/blog/php-optimization-tips/1272">of</a> <a href="http://www.performancewiki.com/faster-php-code.html">resources</a> <a href="http://www.joomlaperformance.com/articles/performance/52_php_programming_tips_43_14.html">available</a>, and no end of conflicting opinions either. Everyone seems to have their own approach to writing &#8220;fast&#8221; PHP code; using single quotes, avoiding require_once() and using isset() before is_array() are some of the most common. But with reliable benchmarks thin on the ground, how do we know if any of these techniques - often touted as &#8220;performance best practices&#8221; - actually deliver benefits? Chris Vincent&#8217;s new PHP benchmark suite at <a href="http://www.phpbench.com/">PHPBench.com</a> aims to &#8220;set the record straight&#8221; on PHP performance techniques, with a simple, comprehensive view of how various approaches actually stack up.<br />
<span id="more-2522"></span><br />
The benchmark suite covers all the usual bases, taking a simple task &#8212; like iterating over an array &#8212; and speed testing almost every possible way to achieve it. Most importantly, however, Chris takes raw numbers out of the spotlight and instead focuses on how the options compare with each other. Each test takes the fastest technique as the base value for execution time; all the other options are measured as percentages in relation to this. For example, <code>foreach($aHash as $val)</code> has script execution time of 558% compared to <code>while(list($key) = each($aHash)) $tmp[] = $aHash[$key]</code> with 100%.</p>
<p>The test scores are also generated live; refreshing the page will produce a slightly different set of results. Chris uses the header of the relatively uncomplicated results page to recommend refreshing a few times, just to ensure consistency and to avoid a one-off impact on any particular test. Personally, I&#8217;d have preferred the tests be carried out in a controlled environment and regenerated every time a new test is added; anomalies don&#8217;t help anyone and live benchmarking offers little real benefit besides operational simplicity. The code for each test is supplied for transparency.</p>
<p>His current set of tests are very comprehensive; no less than 13 tests compared the performance of various <code>echo</code> and <code>print</code> calls, with enough variety to check for any usage scenario. He&#8217;s also accepting suggestions for new tests. Most importantly, however, many of his tests help identify the value of best practices. For example, PHP is often criticised for the vague results of <code>==</code> comparisons; the control structures tests show us that not only is <code>===</code> safer, it also takes about 2/3 as long to execute.</p>
<p>While most of the tests show trivial performance differences, there are some interesting results. For example, iterating over an array and modifying each element is 100 times as fast using <code>while(list($key) = each($aHash))</code> than a simple <code>foreach ($aHash as $key=&gt;$val)</code>, while <code>array_keys()</code> is about 20 times slower than <code>while(list($key,$val) = each($aHash));</code>.</p>
<div id="adz" class="vertical"></div><p>The next step, of course, would be to download the test suite to your local machine or server and run the tests yourself, to see how the factors of your production environment affect the results; Chris aims to make this possible in the near future. Many of the techniques listed are clearly going to be either memory-efficient or CPU cycle efficient, and the limits of your infrastructure will determine which way you want to go before scaling out. Nevertheless, managing bottlenecks in your code can really help you get the most out of your servers &#8212; after all, if you can achieve something 100 times as fast, why not? &#8212; and PHPBench.com could become the definitive reference on PHP performance.</p>
<p><strong>Update:</strong> Many commenters have noted issues with the usefulness and reliability of the tests. It&#8217;s important to consider Chris&#8217; intentions while creating the site, as he&#8217;s <a href="http://www.sitepoint.com/blogs/2008/06/02/phpbench-live-php-benchmarks-best-practices/#comment-738130">described in the comments</a>. With all the &#8220;use this syntax because it&#8217;s slightly faster&#8221; posts, PHPBench.com was built to see if there is any real material benefit to using a particular syntax; most of the tests show that there clearly isn&#8217;t. I&#8217;ve done a few tests of my own and seen similar results, but if something looks amiss, feel free to point it out to Chris. The site is not trying to identify immaterial performance benefits from e.g. single quotes vs. double quotes. Moving further, PHP Bench could be used to measure algorithm performance and other more intensive procedures; for now, the basic syntax tests simply reflect the potential of the system. Hopefully this clears things up.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script><br style="clear: both;"/>
<a href="http://www.pheedo.com/click.phdo?s=a06ea5a1e71de340a404c4494d15a4e2"><img alt="" style="border: 0;" border="0" src="http://www.pheedo.com/img.phdo?s=a06ea5a1e71de340a404c4494d15a4e2"/></a>
<img src="http://www.pheedo.com/feeds/tracker.php?i=a06ea5a1e71de340a404c4494d15a4e2" style="display: none;" border="0" height="1" width="1" alt=""/>
]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2008/06/02/phpbench-live-php-benchmarks-best-practices/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
<!-- Dynamic Page Served (once) in 0.608 seconds -->
<!-- Cached page served by WP-Cache -->