<?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>CodeDread Blog &#187; PHP</title>
	<atom:link href="http://www.codedread.com/blog/archives/category/technology/software/web/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codedread.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 02 Jan 2012 15:30:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Microblogging Floo-Flah</title>
		<link>http://www.codedread.com/blog/archives/2008/07/10/microblogging-floo-flah/</link>
		<comments>http://www.codedread.com/blog/archives/2008/07/10/microblogging-floo-flah/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 07:55:24 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[identi.ca]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[ping.fm]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.codedread.com/archives/2008/07/10/microblogging-floo-flah/</guid>
		<description><![CDATA[Despite my best intentions and my inner voice crying out &#8220;microblogging is stupid!&#8221;, I&#8217;ve been slowly sucked into it. It started innocently enough with the Facebook status. Then I joined the party over at Twitter just to see what all the hubbub was about. When I learned about identi.ca, I decided to check that out [...]]]></description>
			<content:encoded><![CDATA[<p><object type="image/svg+xml" width="100" height="100" align="right" hspace="10" data="http://codedread.com/clipart/social.svgz"><span/></object>Despite my best intentions and my inner voice crying out &#8220;microblogging is stupid!&#8221;, I&#8217;ve been slowly sucked into it.  It started innocently enough with the <a href="http://www.facebook.com/">Facebook</a> status.  Then I joined the party over at <a href="http://www.twitter.com/">Twitter</a> just to see what all the hubbub was about.  When I learned about <a href="http://www.identi.ca/">identi.ca</a>, I decided to check that out a couple days ago (more and more people are joining there now).</p>
<p>The problem, of course, is that not everyone is on the same social network.  And you might not want to be on any of the social networks that I&#8217;m on.  Or you might not trust any of those companies.  Enter <a href="http://ping.fm/">ping.fm</a>.  <span id="more-474"></span></p>
<p>ping.fm serves as a central point for me to <span title="i.e. cross-post">blast out</span> my navel-gazing, mind-numbingly boring status updates to a variety of services (all of the ones mentioned above and more like Plurk, MySpace, Pownce, LinkedIn, Tumblr).  This means when I make a status update at ping.fm, it gets fanned out to all the sites I&#8217;ve ping-enabled (of course I have to give them credentials for each site).</p>
<p>All of this is great but not totally innovative, it&#8217;s just another layer of madness above the existing, silo&#8217;ed madness.  And it doesn&#8217;t solve the fragmented two-way conversation problem (replies on Twitter stay on Twitter, etc).  But what caught my eye this evening was the ability to fan my ping.fm updates to <a href="http://ping.fm/custom/help/">custom URLs</a>.  This means I can set up a PHP page on my own website and ping.fm will send the status updates to that page also.  This opens up some interesting possibilities.</p>
<p><object type="image/svg+xml" width="100" height="100" align="right" hspace="10" data="http://codedread.com/clipart/feed.svgz"><span/></object>So I did just that.  I now have a <a href="http://www.codedread.com/μ" title="Jeff Schiller's MicroBlog Feed">microblog/status feed</a> on this site if anyone cares when I brushed my teeth or if I&#8217;m late for a train.  Be the first to know!</p>
<p>How it works:  I use ping.fm to post my status and it is fanned out automatically to Facebook, LinkedIn, Twitter, identi.ca and codedread&#8217;s custom PHP.  That PHP takes the status and adds it to a static Atom file on my site.</p>
<p>So now that I&#8217;ve got a microblog feed that&#8217;s disentangled from any one particular social network, I&#8217;ll probably add some code to my site to display the latest status from my microblog feed somewhere.</p>
<p>Oh and if you don&#8217;t like the funky character in the URL then you can also use <a href="http://www.codedread.com/microblog/">this one</a>.  They both point to the same location.</p>
<p>One request to ping.fm:  Please support OpenID!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2008/07/10/microblogging-floo-flah/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Whole PHP5 Migration Thing</title>
		<link>http://www.codedread.com/blog/archives/2008/01/16/the-whole-php5-migration-thing/</link>
		<comments>http://www.codedread.com/blog/archives/2008/01/16/the-whole-php5-migration-thing/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 19:38:41 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.codedread.com/archives/2008/01/16/the-whole-php5-migration-thing/</guid>
		<description><![CDATA[I recently made the switch from PHP4 to PHP5. Let me know if you see any breakages. Lots of hoopla about PHP4 being EOL&#8216;d in 2007, effectively forcing everyone (including hosts) to upgrade to PHP5. Matt from WordPress disses the heavy-handed move to PHP5. I personally like PHP5 better than PHP4, though my site was [...]]]></description>
			<content:encoded><![CDATA[<p><object type="image/svg+xml" width="100" height="100" align="right" hspace="10" data="http://codedread.com/clipart/php.svgz"><span/></object>I recently made the switch from PHP4 to PHP5.  Let me know if you see any breakages.  Lots of hoopla about PHP4 being <span class="definition" title="End Of Life">EOL</span>&#8216;d in 2007, effectively forcing everyone (including hosts) to upgrade to PHP5.  <span id="more-419"></span></p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
<p><a href="http://photomatt.net/2007/07/13/on-php/">Matt</a> from WordPress disses the heavy-handed move to PHP5.  I personally like PHP5 better than PHP4, though my site was using PHP4 for everything.  I notice Matt says &#8220;there isn’t a released PHP app today that isn’t PHP 5-compatible&#8221;.  But I don&#8217;t think this can be true, unless he means PHP apps that matter to him.  They point to <a href="http://www.php.net/manual/en/migration5.incompatible.php">this page</a> which describes the differences between PHP 4 and 5, but I think something huge is missing from this page: DOM manipulation.  There is a potentially big change to web apps out there that use DOM XML.</p>
<p>The only thing I had to do when migrating was to change my <a href="http://us.php.net/manual/en/ref.domxml.php">DOM XML</a> function calls to use <a href="http://us.php.net/manual/en/ref.dom.php">DOM</a>.</p>
<ul>
<li>DOM XML will &#8220;never be released with PHP 5&#8243;.</li>
<li>DOM is a PHP5-only feature.</li>
</ul>
<p>These changes affect every line of code that used a DOM XML function, but the changes are pretty trivial, especially if you already know the DOM.  XSLT handling is also not backward/forward compatible, from what I understand.</p>
<p>But why does that PHP page neglect to mention this?  This was pointed out in 2004 by Justin Gehring, but the page fails to have been updated as an official notice.  <a href="http://alexandre.alapetite.net/cv/alexandre-alapetite.en.html">Alexandre Alapetite</a> has provided a <a href="http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/">module</a> that, I think, eases this transition (Disclaimer:  I have not used this module because I rewrote my PHP for PHP5).</p>
<p>In all likelihood, I am missing something obvious here &#8211; so please chime in and put me on the clue-train.  Do people typically not manipulate the DOM in PHP?</p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2008/01/16/the-whole-php5-migration-thing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Make SVG From PHP</title>
		<link>http://www.codedread.com/blog/archives/2006/01/28/make-svg-from-php/</link>
		<comments>http://www.codedread.com/blog/archives/2006/01/28/make-svg-from-php/#comments</comments>
		<pubDate>Sun, 29 Jan 2006 05:07:09 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.codedread.com/?p=218</guid>
		<description><![CDATA[I&#8217;ve been writing a bit of PHP, SVG and JavaScript. Creating nested XML nodes with a procedural language can be a pain, PHP is no exception here. I wrote a quick PHP function to help with my SVG node creation. It&#8217;s nothing fancy, I just thought I&#8217;d save somebody the time of writing it themselves: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been writing a bit of PHP, SVG and JavaScript.  Creating nested XML nodes with a procedural language can be a pain, PHP is no exception here.  I wrote a quick PHP function to help with my SVG node creation.  <span id="more-218"></span></p>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
<p>It&#8217;s nothing fancy, I just thought I&#8217;d save somebody the time of writing it themselves:</p>
<div class="code">
function make($domxml, $element, $attrs = null, $children = null) {<br />
&#160;&#160;$node = $domxml->create_element_ns(&#8220;http://www.w3.org/2000/svg&#8221;, $element, &#8220;svg&#8221;);<br />
&#160;&#160;if($attrs != null) {<br />
&#160;&#160;&#160;&#160;foreach($attrs as $key => $value) {<br />
&#160;&#160;&#160;&#160;&#160;&#160;$node->set_attribute($key, $value);<br />
&#160;&#160;&#160;&#160;}<br />
&#160;&#160;}<br />
&#160;&#160;if($children != null) {<br />
&#160;&#160;&#160;&#160;foreach($children as $child) { $node->append_child($child); }<br />
&#160;&#160;}<br />
&#160;&#160;return $node;<br />
}
</div>
<p>Simple usage to create a <em>&#60;g></em> element and append it to the <em>&#60;svg></em> element $svgnode.  ($doc in this context is the DOM XML object i.e. the &#8220;document&#8221; in JavaScript):</p>
<div class="code">
$svgnode->append_child(make($doc, &#8220;g&#8221;));
</div>
<p>To set several attributes, you send an array of attribute name/value pairs to the function:</p>
<div class="code">
$svgnode->append_child(make($doc, &#8220;circle&#8221;, array(&#8220;cx&#8221; => 35.5, &#8220;cy&#8221; => -12.5, &#8220;fill&#8221; => &#8220;blue&#8221;)));
</div>
<p>To append children to the node you&#8217;re creating, fill an array with the nodes:</p>
<div class="code">
$svgnode->append_child( make($doc, &#8220;linearGradient&#8221;,<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;array(&#8220;x1&#8243; => 0.0, &#8220;y1&#8243; => 0.0, &#8220;x2&#8243; => 1.0, &#8220;y2&#8243; => 1.0),<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;array(make($out, &#8220;stop&#8221;, array(&#8220;offset&#8221; => 0.0, &#8220;stop-color&#8221; => &#8220;#ffffff&#8221;)),<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;make($out, &#8220;stop&#8221;, array(&#8220;offset&#8221; => 1.0, &#8220;stop-color&#8221; => &#8220;#cccccc&#8221;)))));
</div>
<p>You can use this technique to create a tree of nodes to an arbitrary depth, though the biggest pain with using this technique is getting the correct number of right parentheses, make sure you have a good editor to match them up.</p>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2006/01/28/make-svg-from-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Inlaying SVG with HTML</title>
		<link>http://www.codedread.com/blog/archives/2006/01/13/inlaying-svg-with-html/</link>
		<comments>http://www.codedread.com/blog/archives/2006/01/13/inlaying-svg-with-html/#comments</comments>
		<pubDate>Sat, 14 Jan 2006 04:02:30 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.codedread.com/?p=206</guid>
		<description><![CDATA[After Rob called my code ugly, I decided to update my technique for embedding SVG into HTML and it finally crystallized into a nice solution for me. I hesitate to say &#8220;embedding&#8221; because that might imply that I condone the &#60;embed&#62; tag, when in fact I only use it at gunpoint. Rob came up with [...]]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://rr.latenightpc.com/wp/archives/2006/01/13/embedding-svg-in-wordpress-posts/">Rob called my code ugly</a>, I decided to update my technique for embedding SVG into HTML and it finally crystallized into a nice solution for me.  I hesitate to say &#8220;embedding&#8221; because that might imply that I condone the <em>&#60;embed&#62;</em> tag, when in fact I only use it at gunpoint.  <a href="http://rr.latenightpc.com/wp/">Rob</a> came up with a suitable term for including SVG in a HTML document:  inlaying (as opposed to inlining).  <span id="more-206"></span></p>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
<p>At first glance, this seems like such a simple thing.  Most people out there think it&#8217;s as simple as using the &#60;object&#62; tag, and let me be clear:  ideally it should be.  However, in my experience the Adobe SVG Viewer (especially version 3.0) tends to have a problem including SVG documents in an <em>&#60;object&#62;</em> tag and prefers to non-standard <em>&#60;embed&#62;</em> tag,  Of course, other browsers (Firefox and Opera) have various problems with <em>&#60;embed&#62;</em>.  Typical web developer frustration.</p>
<p>I found it interesting to see how my practices had changed on this matter in seven or so months:</p>
<ul>
<li>My first approach, like <a href="http://labs.silverorange.com/archives/2006/january/howtoinclude">this guy</a>, was to simply use <em>&#60;object&#62;</em> tags because I didn&#8217;t know at that time that ASV only worked perfectly with <em>&#60;embed&#62;</em> tags.</li>
<li>Upon learning this, <a href="http://blog.codedread.com/archives/2005/06/21/detecting-svg-viewer-capabilities/">I wrote some JavaScript</a> that would scan the page and transform any <em>object</em> tags referencing SVG content into <em>embed</em> tags if ASV is detected as installed.  This has the benefit of keeping the web page author out of the sticky mess (except for including the JavaScript in the document&#8217;s onload event handler) but it resulted in reduced page loading time.  Furthermore, I later discovered that ASV acted funny with this sometimes (i.e. it wasn&#8217;t a perfect solution).  Another problem is that the <em>embed</em> tag does not provide any mechanism to provide fallback content.  This means that if a user hadn&#8217;t downloaded ASV, their page would be broken.</li>
<li>In the fall of last year, I learned about IE&#8217;s &#8220;<a href="http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp">conditional comments</a>&#8221; from <a href="http://oskamp.dyndns.org/SiemensClock/SVG/SiemensClock.xhtml">Stefan Oskamp</a> who devised a technique of including an SVG image in a HTML document so that I could drop the JavaScript mentioned above.  I published that technique <a href="http://blog.codedread.com/archives/2005/12/01/guide-to-deploying-svg-with-html/" title="Guide to Deploying SVG with HTML">here</a>.  Using conditional comments, I can supply an <em>embed</em> to IE and an <em>object</em> with fallback content to all other browsers.  It has the benefit of providing a static document (i.e. no scripting involved that changed the document at load time) but it has the disadvantages of 1) lengthier HTML code and 2) <em>embed</em> still doesn&#8217;t provide a mechanism for fallback content</li>
<li>At the end of last month, I finally put most of the pieces together and used some JavaScript with the above solution to provide fallback content dynamically.  Unfortunately this lengthens the code considerably and the author has to write the fallback content in THREE different places.  It also requires scripting be enabled to see the SVG in IE (though I consider this to be acceptable).</li>
</ul>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
<p>So now we arrive at yesterday where I realized the obvious:  Since my sites are PHP-based, I will simply provide a PHP function that constructs all the HTML+JS code for me.  If Adobe releases a viewer that handles <em>object</em> properly, I can update my PHP function to simply spit out an <em>object</em> and forget about <em>embed</em> forever.</p>
<p><a href="http://www.codedread.com/lib/svginlay.inc" title="PHP Library to Inlay SVG">Click here to view the PHP source</a></p>
<p>To use this PHP library, you include the file once at the top of the web page like so:</p>
<div class="code">&#60;?php include &#8220;svginlay.inc&#8221;; ?&#62;</div>
<p>Then to &#8220;inlay&#8221; an SVG document into your HTML you use this PHP fragment:</p>
<div class="code">&#60;?php inlaySVG(&#8216;some_id&#8217;, &#8216;myfile.svg&#8217;, 500, 375, &#8216;&#60;p&#62;Click &#60;a href=&#8221;http://www.adobe.com/svg/main.html&#8221;&#62;here&#60;/a&#62; to download the Adobe SVG Viewer&#60;/p&#62;&#8217;); ?&#62;</div>
<p>This will inlay <em>myfile.svg</em> into your HTML page via an object/embed frame (depending on the viewer&#8217;s browser) with id=&#8217;some_id&#8217; and dimensions 500&#215;375.  If the viewer&#8217;s browser does not support SVG, fallback content is provided in the form of a link to download the SVG Viewer.</p>
<p>One caveat is that the fallback string must be properly formatted PHP string.  This means that if you start the string with single quotes in PHP, then you should use double-quotes within the fallback string to represent quotation marks.  In other words, the string has to be valid PHP and the string contents have to be valid HTML.</p>
<p>The HTML code that this PHP function call produces is:</p>
<div class="code">
&#160;&#160;&#60;!&#8211;[if IE]><br />
&#160;&#160;&#160;&#160;&#60;script type=&#8217;text/javascript&#8217;><br />
&#160;&#160;&#160;&#160;try{<br />
&#160;&#160;&#160;&#160;&#160;&#160;new ActiveXObject(&#8216;Adobe.SVGCtl&#8217;);<br />
&#160;&#160;&#160;&#160;&#160;&#160;document.write(&#8216;&#60;embed id=&#8221;some_id&#8221; width=&#8221;500&#8243; height=&#8221;375&#8243; src=&#8221;myfile.svg&#8221; class=&#8221;svgex&#8221;/>&#8217;);<br />
&#160;&#160;&#160;&#160;} catch(e) {<br />
&#160;&#160;&#160;&#160;&#160;&#160;document.write(&#8216;&#60;p&#62;Click &#60;a href=&#8217;http://www.adobe.com/svg/main.html&#8217;&#62;here&#60;/a&#62; to download the Adobe SVG Viewer&#60;/p&#62;&#8217;);<br />
&#160;&#160;&#160;&#160;}<br />
&#160;&#160;&#160;&#160;&#60;/script><br />
&#160;&#160;&#160;&#160;&#60;noscript><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#60;p&#62;Click &#60;a href=&#8217;http://www.adobe.com/svg/main.html&#8217;&#62;here&#60;/a&#62; to download the Adobe SVG Viewer&#60;/p&#62;<br />
&#160;&#160;&#160;&#160;&#60;/noscript><br />
&#160;&#160;&#60;![endif]&#8211;><br />
&#160;&#160;&#60;![if !IE]><br />
&#160;&#160;&#160;&#160;&#60;object id=&#8221;some_id&#8221; type=&#8221;image/svg+xml&#8221; data=&#8221;myfile.svg&#8221; width=&#8221;500&#8243; height=&#8221;375&#8243;><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#60;p&#62;Click &#60;a href=&#8217;http://www.adobe.com/svg/main.html&#8217;&#62;here&#60;/a&#62; to download the Adobe SVG Viewer&#60;/p&#62;<br />
&#160;&#160;&#160;&#160;&#60;/object><br />
&#160;&#160;&#60;![endif]>
</div>
<p>You can see the reason why the PHP file is a good idea.  The above is a pretty hefty stretch of code to simply include an SVG document with fallback content.  The PHP file keeps your code much cleaner and you can centrally maintain the inlaying functionality.</p>
<p>Now if you don&#8217;t have PHP you can still use this technique, it just requires you to manually enter all that code yourself on your HTML pages whenever you want to inlay some SVG.</p>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2006/01/13/inlaying-svg-with-html/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Pretty Web Statistics in SVG</title>
		<link>http://www.codedread.com/blog/archives/2006/01/12/pretty-web-statistics-in-svg/</link>
		<comments>http://www.codedread.com/blog/archives/2006/01/12/pretty-web-statistics-in-svg/#comments</comments>
		<pubDate>Thu, 12 Jan 2006 17:05:57 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.codedread.com/?p=205</guid>
		<description><![CDATA[I posted a week ago about how there are some blogs/sites out there that roll their own web statistics and display them SVG. After reading this challenge on the weekend, I decided to work on my own, roughly mimicking these designs. Now while the results aren&#8217;t as pretty as the static rasters, I did provide [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://blog.codedread.com/archives/2006/01/05/web-stats-a-la-svg/">posted a week ago</a> about how there are some blogs/sites out there that roll their own web statistics and display them <span class="definition" title="Scalable Vector Graphics">SVG</span>.  After reading <a href="http://ecmanaut.blogspot.com/2006/01/prediction-about-svg-canvas.html">this challenge</a> on the weekend, I decided to work on my own, roughly mimicking <a href="http://www.rad-e8.com/log/archives/2005/09/12/02.50/">these designs</a>.  <span id="more-205"></span></p>
<p>Now while the results aren&#8217;t as pretty as <a href="http://www.rad-e8.com/log/i/0912diag_ua.jpg">the static rasters</a>, I did provide some minimal interactivity/dynamism that folks like <a href="http://weblog.infoworld.com/udell/2005/12/20.html#a1357" title="Jon Udell's Blog at InfoWorld">Jon Udell</a> might appreciate.</p>
<div style="border-style:solid; border-color: black; border-width: 1px; float:right; margin:10px;">
<a href="http://www.codedread.com/displayWebStats.php" title="Web Statistics in SVG"><br />
<img width="300" src="http://www.codedread.com/images/webstats.png" alt="Raster image of my SVG web statistics"/><br />
</a>
</div>
<p>Without further ado, my live web statistics SVG image is located <strong><a href="http://www.codedread.com/displayWebStats.php">HERE</a></strong>.  It is constructed using a variety of techniques:</p>
<ul>
<li>Include a small <a href="http://www.php.net/">PHP</a> file to record each document request on my site and blog.  Each result is written into a <span class="definition" title="eXtensible Markup Language">XML</span> file.</li>
<li>I have another server-side PHP script to crunch each day&#8217;s worth of hits into summarized daily statistics XML file.</li>
<li>I have yet another server-side PHP script that reads in all daily statistics XML files and crunches them into the SVG you see.</li>
<li>The interactivity is provided via SVG and JavaScript.  Basically mouse and keyboard listener events handle moving the &#8220;day cursor&#8221; around the time-based graph to affect the pie chart</li>
</ul>
<p>Go ahead and play with it.  It seems to work for me in <a href="http://www.mozilla.com/firefox/">Firefox 1.5</a> and Internet Explorer with <a href="http://www.adobe.com/svg/main.html">Adobe SVG Viewer</a>.  It also displays in <a href="http://www.opera.com/">Opera</a> 9 <span class="definition" title="Technical Preview">TP</span>1 but the dynamic/interactivity part does not work in that browser (hoping to see it fixed in the next TP).  Can someone with a nightly build of Safari tell me whether anything shows up?</p>
<p>As with JavaScript, creating SVG using PHP&#8217;s XMLDOM library is tedious at best.  If I knew XSLT I would have given that a shot, but I don&#8217;t (yet) &#8211; so I didn&#8217;t.</p>
<p>Nonetheless, I&#8217;m quite happy with the result because now that it&#8217;s written it requires very little manual action on my part to keep it up-to-date.  I could hook up calls to my server-side generation scripts to a cron-job if I had a server-machine under my control (mine currently has a fried motherboard), but I actually prefer to ensure that the XML is being properly generated, so for now I&#8217;ll just invoke the server-side crunching scripts every few days to keep the SVG fresh.</p>
<p><a href="http://www.codedread.com/displayWebStats.php" title="Pretty Web Statistics in SVG">Click here to see my SVG web statistics in a full page</a>.</p>
<p>NOTE:  One challenge was to properly embed the SVG image into this blog entry with fallback content.  For IE+ASV, I can serve an <em>&#60;embed&#62;</em> tag via a <em>&#60;script&#62;</em> with the fallback being written by a <em>&#60;noscript&#62;</em>.  For all other browsers, I can serve an <em>&#60;object&#62;</em> tag to Firefox and Opera the way it should be.  However, it seems that WordPress mangles things to a degree such that it will not load inside WordPress. I eventually gave up on this, though I have successfully used this technique in my own HTML pages.</p>
<p><script language="JavaScript" src="http://www.codedread.com/yahooads.js"></script><br />
<script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2006/01/12/pretty-web-statistics-in-svg/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Deploying For The Live Web</title>
		<link>http://www.codedread.com/blog/archives/2005/05/24/deploying-for-the-live-web/</link>
		<comments>http://www.codedread.com/blog/archives/2005/05/24/deploying-for-the-live-web/#comments</comments>
		<pubDate>Wed, 25 May 2005 04:18:42 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">/?p=96</guid>
		<description><![CDATA[I&#8217;ve been pecking a way at this online chat program that I started as an excuse to learn some JavaScript and enhance my PHP skills (as well as get around a certain corporate firewall). It&#8217;s coming along nicely. Tonight I added a RSS feed for it so that users can monitor the most recent conversation [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been pecking a way at this online chat program that I started as an excuse to learn some JavaScript and enhance my PHP skills (as well as get around a certain corporate firewall).  It&#8217;s coming along nicely.  Tonight I added a RSS feed for it so that users can monitor the most recent conversation without having to be constantly logged in.  I&#8217;ve been trying to figure out a good way to manage the deployment of the web application. <span id="more-96"></span></p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
<p>My design philosophy in the last year or two has switched from &#8220;Big, Massive Projects That I Can Never Finish Given My Diminishing Spare Time&#8221; to &#8220;Small, Constantly Evolving But Always Fully Functional Projects&#8221;.  The paradigm shift was a result of simply not having enough time, energy, and enthusiasm to commit to a large project and constantly feeling the pain of never finishing what I started.  Now, I can play with a project, add a few new features to it and put it away for some time.  At all stages of &#8220;release&#8221;, the project is fully functional, yet I&#8217;ve always got a laundry list of future features which I&#8217;ll eventually get to.  So far, it&#8217;s led to a couple interesting little applications, the most complete of which is the afore-mentioned instant messaging web application.</p>
<p>Anyway, the Instant Messenger was unique in my experience so far because there were multiple users who, at any point and time, may be using the latest version of the application.</p>
<p>Deploying the new version into the same directory was not a good idea because the instant messaging application relied on asynchronous JavaScript calls to fetch conversation data that was uniquely identified.  In short, adding in new features had the potential to break existing sessions.</p>
<p>Thus, I ended up developing and testing the newer version in a private web directory, then broadcasting to all participants:  &#8220;Ok, I&#8217;m going to deploy the next version of the chat program so everybody log out for a couple minutes&#8221;.  I&#8217;d then scurry around in my website file manager, setting up some config files, rename some directories and then log back in and wait for the other participants to rejoin.</p>
<p>Not the best deployment plan, I know.</p>
<p>Tonight I struck on an easier way for me to deploy the application without having to force people to log off.</p>
<p>First, I set up the directory structure like this:</p>
<p>/chat/<br />
/chat/1.0/<br />
/chat/1.1/<br />
/chat/1.2/<br />
/chat/WIP/</p>
<p>All versions of the chat program code are located in subdirectories inside /chat/.  The most recent &#8220;live&#8221; version in this example is located at /chat/1.2/.  The 1.2 directory houses all the PHP, JavaScript, user information, conversation and state information for that version of the application.  For instance, /chat/1.2 might contain:</p>
<p>/chat/1.2/index.php<br />
/chat/1.2/some_scripts.js<br />
/chat/1.2/serverside_stuff.php<br />
/chat/1.2/rss.php<br />
/chat/1.2/users.passwd<br />
/chat/1.2/chat0000.xml<br />
/chat/1.2/chat0001.xml<br />
&#8230;</p>
<p>Similarly, the /chat/WIP/ folder is my &#8220;Work In Progress&#8221; folder that allows me to experiment freely without upsetting anyone.</p>
<p>Now it&#8217;s kind of a hassle to ask people to browse to http://www.mydomain.com/chat/1.2/index.php and then when I update to 1.3, tell them they have to update their bookmarks accordingly to http://www.mydomain.com/chat/1.3/.  Such a scheme would hardly be &#8220;user friendly&#8221; and it wouldn&#8217;t scale properly to an application with a large user base.  Same goes for the RSS link (http://www.mydomain.com/chat/1.2/rss.php).</p>
<p>So what I did was a simple PHP trick.  I created the following files</p>
<p>/chat/<br />
<b>/chat/deploy.php<br />
/chat/index.php<br />
/chat/rss.php</b><br />
/chat/1.0/<br />
/chat/1.1/<br />
/chat/1.2/<br />
/chat/WIP/</p>
<p>The content of these files are as follows:</p>
<p>/chat/deploy.php:</p>
<div style="background: #eee; border-style: solid; border-width: 1px; width: 700px;">
<pre>&#60;?php
    $DEPLOY_MYCHAT_CUR_VER = "1.2";
?&#62;
</pre>
</div>
<p>/chat/index.php:</p>
<div style="background: #eee; border-style: solid; border-width: 1px; width: 700px;">
<pre>
&#60;?php
    include 'deploy.php';
    $urlstr = "http://www.mydomain.com/chat/" . $DEPLOY_MYCHAT_CUR_VER . "/index.php";
?&#62;
&#60;html&#62;&#60;head&#62;
    &#60;meta HTTP-EQUIV="Refresh" content="0; URL=&#60;?php echo $urlstr; ?&#62;" &#62;
&#60;/head&#62;&#60;body/&#62;&#60;/html&#62;
</pre>
</div>
<p>/chat/rss.php:</p>
<div style="background: #eee; border-style: solid; border-width: 1px; width: 700px;">
<pre>
&#60;?php
    include 'deployment.php';
    $filestr = "./" . $DEPLOY_MYCHAT_CUR_VER . "rss.php";
    include $filestr;
?&#62;
</pre>
</div>
<p>Now what&#8217;s the benefit of this?  Well, if a user browses to http://www.mydomain.com/chat/ they will end up at http://www.mydomain.com/chat/1.2/index.php.  i.e. the most recently released version of the application and all their doings-and-goings-on will be isolated to the /chat/1.2/ folder.</p>
<p>Meanwhile, I finally finished up feature XYZ in the WIP and want to deploy the new version.  What do I do?</p>
<p>I create a /chat/1.3/ folder and copy the contents of the WIP into it.  Then I modify /chat/deploy.php such that $DEPLOY_MYCHAT_CUR_VER equals &#8220;1.3&#8243;.</p>
<p>Now anyone currently logged into the chat program can safely stay on 1.2 for as long as they want.  However, the moment they log out, when they try to log back in, they will automatically end up at http://www.mydomain.com/chat/1.3/.  What I like about this is: 1) there is no requirement for any user currently using the application to log out; they are safe in their &#8220;1.2&#8243; buckets and 2) there is no requirement for me to rename existing folders, mess with configuration files, etc.  Deployment is a simple two-step process.</p>
<p>To end this entry, I&#8217;ll discuss a third thing I like about this technique.  I could centralize the data (i.e. the conversations, the user information such as passwords) into the /chat/ directory and allow any version to access this common data.  This means that someone using version 1.2 would be able to chat with someone using version 1.3.  As long as the backing data store is in a format that easily downgrades for older versions (i.e. XML elements/attributes or database tables/fields that would simply be ignored by older &#8220;less-smart&#8221; versions).  Of course doing so might require some type of synchronization across deployment versions and may end up causing me another deployment nightmare all over again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2005/05/24/deploying-for-the-live-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Gotcha</title>
		<link>http://www.codedread.com/blog/archives/2005/04/23/php-gotcha/</link>
		<comments>http://www.codedread.com/blog/archives/2005/04/23/php-gotcha/#comments</comments>
		<pubDate>Sat, 23 Apr 2005 19:21:05 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">/?p=86</guid>
		<description><![CDATA[After I wrote this entry, I knew I had forgotten one &#8220;gotcha&#8221; from my little Remote Scripting experience. I remembered it today. It involves PHP and the annoying aspect of having to declare within a function when you want to use a global variable: $gSomeVariable = 5; function somefunc() { &#160;&#160;&#160;printf(&#8220;%d&#8221;, gSomeVariable); } The above [...]]]></description>
			<content:encoded><![CDATA[<p>After I wrote <a href="http://blog.codedread.com/archives/2005/04/21/ajax-gotchas/">this entry</a>, I knew I had forgotten one &#8220;gotcha&#8221; from my little Remote Scripting experience.  I remembered it today.  It involves PHP and the annoying aspect of having to declare within a function when you want to use a global variable:</p>
<div class="code">
$gSomeVariable = 5;<br />
function somefunc() {<br />
&#160;&#160;&#160;printf(&#8220;%d&#8221;, gSomeVariable);<br />
}
</div>
<p>The above will not produce &#8220;5&#8243;.  Without explicitly telling PHP that gSomeVariable is a global variable, it will assume it is a local variable and currently undefined.</p>
<p>Do you know how many time this has tripped me up?  The correct PHP code is:</p>
<div class="code">
$gSomeVariable = 5;<br />
function somefunc() {<br />
<strong>&#160;&#160;&#160;global $gSomeVariable;</strong><br />
&#160;&#160;&#160;printf(&#8220;%d&#8221;, gSomeVariable);<br />
}
</div>
<p>For all the times I made this mistake:   AAAAAARRRRRGGGGHHHH!!!!!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2005/04/23/php-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax Gotchas</title>
		<link>http://www.codedread.com/blog/archives/2005/04/21/ajax-gotchas/</link>
		<comments>http://www.codedread.com/blog/archives/2005/04/21/ajax-gotchas/#comments</comments>
		<pubDate>Thu, 21 Apr 2005 20:18:43 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">/?p=80</guid>
		<description><![CDATA[This is just a quick entry for me to jot down some caveats that I encountered while making a simple instant messaging application for the browser using Asynchronous JavaScript, XML and PHP. Properly Set the Content Type of the Returned Document I stumbled around for a bit and couldn&#8217;t figure out why the XML document [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a quick entry for me to jot down some caveats that I encountered while making a simple instant messaging application for the browser using Asynchronous JavaScript, XML and PHP.  <span id="more-80"></span></p>
<h2>Properly Set the Content Type of the Returned Document</h2>
<p>I stumbled around for a bit and couldn&#8217;t figure out why the XML document returned by the PHP server script wasn&#8217;t being parsed into walkable DOM objects at the client side by my JavaScript.  Finally it dawned on me that the client must receive the XML content type in the header.  I used the following PHP code (before any output):</p>
<div class="code">
header(&#8220;Content-type: text/xml&#8221;);
</div>
<p>And suddenly everything started parsing from the client side!
</p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
<h2>Preventing Browser Caching of the URL</h2>
<p>When I finally got an XML document returned, I noticed that Internet Explorer would not retrieve a newer document from a subsequent request (though somehow Firefox was able to get a new XML document).  Once I determined that different browsers were experiencing different results, I had an inkling that it was a caching problem on the client-side.  When doing periodic &#8220;get&#8221; via the XMLHttpRequest document, apparently Internet Explorer was checking its cache and noticing that the same URL had been fetched previously and just using that stale document.  IE had no way of knowing that the retrieved document could by dynamic content that might vary over time.</p>
<p>The way around this is to modify the URL slightly so that IE believes it is a new document.  I did this using the following JavaScript code:</p>
<div class="code">
var urlstr = &#8220;myserver.php?<strong>RANDOM=&#8221; + (Math.random() * Date.parse(new Date()))</strong> + rest of url&#8230;<br />
var req = new XMLHttpRequest(); // use ActiveXObject(&#8220;Microsoft.XMLHTTP&#8221;) if IE<br />
req.open(&#8220;GET&#8221;, urlstr, true);
</div>
<p>This inserts an (unused) URL variable into the string and fools the browser into thinking it is a new document (which, in fact, it is!).  I have no idea if this should be considered a bug from the IE side or the FF side&#8230;
</p>
<h2>PHP File Locking</h2>
<p>Since my little application uses the server&#8217;s filesystem for its backend storage (and not a database) and transactions can occur in parallel and asynchronously, I took some care to make sure I locked the server-side files before accessing them.  I used PHP&#8217;s &#8220;flock&#8221; function:</p>
<div class="code">
$f = @fopen($filename, &#8216;w&#8217;);<br />
<strong>while( !flock($f, LOCK_EX) ) {<br />
&#160;&#160;usleep(50000);<br />
}</strong><br />
$xmlstr = formatIntoXml(&#8230;);<br />
fwrite($f, $xmlstr);<br />
fwrite($f, &#8220;rn&#8221;);<br />
<strong>flock($f, LOCK_UN);</strong><br />
fclose($f);
</div>
<p>Though I never experienced any odd conflict scenarios even before I implemented file locking (due to the relatively low network traffic that my app experiences), I&#8217;m convinced that this is a necessity for any real application (and a very persuasive argument to using a database as the backend storage mechanism).</p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2005/04/21/ajax-gotchas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passing Text Between Web Components</title>
		<link>http://www.codedread.com/blog/archives/2005/04/19/passing-text-between-web-components/</link>
		<comments>http://www.codedread.com/blog/archives/2005/04/19/passing-text-between-web-components/#comments</comments>
		<pubDate>Tue, 19 Apr 2005 13:37:38 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">/?p=83</guid>
		<description><![CDATA[In designing a little on-line chat program accessible through a web browser, I came across what was one of the most frustrating problems in my software development career. Here&#8217;s what I wanted to do: 1) User types in some text on a form and submits the form 2) JavaScript mangles the text so that it [...]]]></description>
			<content:encoded><![CDATA[<p>In designing a little on-line chat program accessible through a web browser, I came across what was one of the most frustrating problems in my software development career.  <span id="more-83"></span></p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
<p>Here&#8217;s what I wanted to do:</p>
<p>1) User types in some text on a form and submits the form<br />
2) JavaScript mangles the text so that it is not easily readable and sends the disguised text to a server-side script<br />
3) Server-side script writes any text received to the end of a &#8220;conversation&#8221; file as XML<br />
4) Server-side script mangles the XML document and sends back to all attached clients<br />
5) Client receives the mangled text, un-mangles and generates an XML document, extracts the text, and displays on the screen</p>
<p>The overall process is pretty simple and is represented by the following diagram:</p>
<p><img src="http://www.codedread.com/images/chat_flow.jpg" alt="flow of text throughout the chat application"></img></p>
<p>The frustrating part came when I started encountering the quirks of the various languages/syntaxes that I was using coupled with the requirement to be able to pass <em>any</em> text to the server.  Things got confusing fast, and as they always say, the devil is in the details.</p>
<h2>Sending Text from JavaScript to PHP</h2>
<p>The transition from user text to mangled text is a simple function (written in both JavaScript and PHP) that takes an input string of N characters and returns an output string of N characters.  The function works transitively (such that mangled text becomes un-mangled and vice versa) for convenience.  This is the really simple part of the process:</p>
<div class="code">
var outStr = mangle(&#8220;Our sample text&#8221;);<br />
// outStr is now &#8220;ubW(&#038;2v A;(z;+z&#8221;
</div>
<p>However, it is when we want to actually send this output string as a URL argument to a server-side PHP script that we encounter our first problem.  For example:</p>
<div class="code">http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=&#8230;.</div>
<p>Just as with text entered from the form, the mangled string could contain <em>any</em> printable ASCII character.  But the ampersand character (&#8220;&#38;&#8221;) is used to delimit URL variables in PHP and valid URLs cannot have spaces (&#8221; &#8220;) in them.  There are other characters that have special meaning in URLs as well.  Thus, if we tried to put our outStr into the URL it would become:</p>
<div class="code">http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=ubW(&#038;2v A;(z;+z</div>
<p>The portion after the space (i.e. &#8220;<span style="color: blue">A;(z;+z</span>&#8220;) is removed from the URL.  Also, the $TEXT variable from the PHP side would contain only &#8220;<span style="color: blue">ubW(</span>&#8221; and the remaining string is interpreted as another PHP variable called &#8220;<span style="color: blue">2v</span>&#8220;.</p>
<p>What we want is for the PHP script to see one variable called $TEXT with the complete mangled string.  Thus, it is important that we escape the mangled string such that spaces become &#8220;%20&#8243;, ampersands become &#8220;%26&#8243;, &#8220;=&#8221; become &#8220;%3D&#8221;, and other characters like &#8220;%&#8221; become &#8220;%25&#8243;.  i.e. any character that might be interpreted in a special way inside a URL  Thankfully we can just use the JavaScript escape() function for this.  Handy-dandy:</p>
<div class="code">
var outStr = mangle(&#8220;Our sample text&#8221;);<br />
// outStr is now &#8220;ubW(&#038;2v A;(z;+z&#8221;<br />
outStr = escape(outStr);<br />
// outStr is now &#8220;ubW(%26v%20A;(z;+z&#8221;<br />
var urlStr = &#8220;http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=&#8221; + escape(outStr);<br />
// urlStr is now http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=ubW(%26v%20A;(z;+z&#8221;
</div>
<p>Now we can send this string to the PHP script, right?  Almost, but not quite!  It seems that the &#8220;+&#8221; character in a URL is automatically translated into a space by PHP.  Thus, if we really want to send the + character in our URL we&#8217;ll also need to escape it as &#8220;%2B&#8221; (and only AFTER we escape the rest of our string, otherwise its &#8220;%2B&#8221; would become &#8220;%252B&#8221;!!):</p>
<div class="code">
var outStr = mangle(&#8220;Our sample text&#8221;);<br />
// outStr is now &#8220;ubW(&#038;2v A;(z;+z&#8221;<br />
outStr = escape(outStr);<br />
// outStr is now &#8220;ubW(%26v%20A;(z;+z&#8221;<br />
<strong>outStr = outStr.replace(/(+)/g, &#8220;%2B&#8221;);</strong><br />
// outStr is now &#8220;ubW(%26v%20A;(z;%2Bz&#8221;<br />
var urlStr = &#8220;http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=&#8221; + escape(outStr);<br />
// urlStr is now http://www.mydomain.com/chat.php?USER=Jeff&#038;TEXT=ubW(%26v%20A;(z;%2Bz&#8221;
</div>
<p>Is the string safe for PHP now?  Yes, it would seem so.</p>
<p>[NOTE:  When discussing this topic with <a href="http://rr.latenightpc.com/wp/">a friend</a> he told me about the encodeURIComponent() function.  However, I had already gone through the above learning experience and I also noted that encodeURIComponent() is not supported in MacIE or Safari...poor Mac users.]</p>
<p>The nice part is that once passed to PHP, the PHP interpreter automatically un-escapes any %xx characters such they magically return to their equivalent single-character representations again.</p>
<p>But!  Apart from unescaping the %xx characters, PHP can also do some mangling of its own.  This depends on whether or not the &#8220;magic quotes&#8221; feature is enabled or not.  If it is, then PHP automatically adds backslashes to specific characters (single-quote and double-quotes) presupposing that you&#8217;re going to try and shove the text into a database.  This is NOT what we want, as extra characters changes the content that was originally typed when you un-mangle things.  i.e. we&#8217;ll have extra characters in our returned string.  You can avoid this on the PHP side by either configuring PHP to not use magic quotes (via php cfg files or .htaccess) or use some simple PHP code:</p>
<div class="code">
if(get_magic_quotes_gpc()) {<br />
&#160;&#160;$thechatmsg = stripslashes($TEXT);<br />
}</div>
<p>Now $TEXT should contain &#8220;ubW(&#038;2v A;(z;+z&#8221; again.  We&#8217;re finally back to our mangled version of the text from the JavaScript.</p>
<p>However, the fun doesn&#8217;t stop there.  In fact, we&#8217;ve only made it from (1) to (2) in our diagram.</p>
<h2>Creating XML in PHP</h2>
<p>Now we need to un-mangle the text and shove it into an XML document:</p>
<div class="code">
if(get_magic_quotes_gpc()) {<br />
&#160;&#160;$thechatmsg = stripslashes($TEXT);<br />
}<br />
<strong>$thechatmsg = mangle($thechatmsg);</strong>
</div>
<p>There, now we have un-mangled text, but before we can blindly shove it into a XML document, we have to make sure that the original text typed by the user doesn&#8217;t violate the allowed characters of an XML document (namely &#60; and &#62; characters).  As you may know, XML documents rely heavily on markup tags and thus, characters such as &#60; and &#62; are verbotten within the XML document contents itself.  Since the receiving clients expect a valid XML document we have to take care that any of the data we&#8217;re shoving into the XML document does not invalidate the syntax required.  PHP provides a simple function for this called htmlspecialchars():</p>
<div class="code">
if(get_magic_quotes_gpc()) {<br />
&#160;&#160;$thechatmsg = stripslashes($TEXT);<br />
}<br />
$thechatmsg = mangle($thechatmsg);<br />
<strong>$thechatmsg = htmlspecialchars($thechatmsg, ENT_QUOTES);</strong>
</div>
<p>We are finally ready to format $thechatmsg into a XML document and write to a file:</p>
<div class="code">
if(get_magic_quotes_gpc()) {<br />
&#160;&#160;$thechatmsg = stripslashes($TEXT);<br />
}<br />
$thechatmsg = mangle($thechatmsg);<br />
$thechatmsg = htmlspecialchars($thechatmsg, ENT_QUOTES);<br />
<strong>$xmlStr = sprintf(&#8220;&#60;chat xml:space=&#8221;preserve&#8221;&#62;&#60;msg id=&#8221;%d&#8221;&#62;&#60;user&#62;%s&#60;/user&#62;&#60;text&#62;%s&#60;/text&#62;&#60;/msg&#62;&#60;/chat&#62;&#8221;, $n, $USER, $thechatmsg);<br />
fwrite($f, $xmlStr);<br />
</strong>
</div>
<p>We use xml:space=&#8221;preserve&#8221; to indicate that whitespace within the XML document should be preserved.</p>
<p>Now we&#8217;ve made it safely from (2) to (3).  We&#8217;ve sent the mangled text across the network to a PHP script and the PHP script has un-mangled it, written it into an XML document to the filesystem.  Next, we have to send all new messages back to the JavaScript call in the form of an XML document (as a response to a XMLHttpRequest).</p>
<h2>Sending Text from PHP to JavaScript</h2>
<p>This is actually pretty straightforward PHP code:</p>
<div class="code">
$xmldoc = &#8220;&#8221;;<br />
while(!feof($f)) {<br />
&#160;&#160;$line = trim(fgets($f));<br />
&#160;&#160;if(strlen($line) > 0) {<br />
&#160;&#160;&#160;&#160;$xmldoc .= $line;<br />
&#160;&#160;}<br />
} // while (loop<br />
// now mangle the entire XML document<br />
$xmldoc = mangle($xmldoc);<br />
printf(&#8220;%sn&#8221;, $xmldoc);
</div>
<p>Now we&#8217;ve made it from (3) to (4).  The only thing left for the client to do is to un-mangle it, reformat it into an XML document, walk the document nodes and extract the information.</p>
<h2>Creating an XML Document From Text in JavaScript</h2>
<p>Since browsers have different means of doing this, I decided to use <a href="http://sarissa.sourceforge.net/doc/">Sarissa</a> which abstracts these differences and lets me just deal with the XML document itself.</p>
<p>The mangled text comes back as the responseText field of the XMLHttpRequest object (not as valid XML).  I take this string, un-mangle it, and create an XML document out of it:</p>
<div class="code">
var xmlString = mangle(req.responseText);<br />
var oDomDoc = Sarissa.getDomDocument();<br />
oDomDoc.loadXML(xmlString);<br />
//get the root node<br />
var xmldoc = oDomDoc.documentElement;
</div>
<p>The one caveat I had is that regular HTML does not (by default) preserve whitespace.  To get around this, I used the CSS rule &#8220;white-space: pre&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2005/04/19/passing-text-between-web-components/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax &#8211; The Power Of Clean?</title>
		<link>http://www.codedread.com/blog/archives/2005/04/11/ajax-the-power-of-clean/</link>
		<comments>http://www.codedread.com/blog/archives/2005/04/11/ajax-the-power-of-clean/#comments</comments>
		<pubDate>Tue, 12 Apr 2005 04:49:56 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">/?p=79</guid>
		<description><![CDATA[I&#8217;ve been working on learning JavaScript over the last month or so and I&#8217;ve come to a point where I&#8217;ve started to delve into the hot topic of &#8220;Asynchronous JavaScript, DHTML and Server-side Programming&#8221;, or as some pundits have termed it &#8220;Ajax&#8221;. The &#8216;x&#8217; is supposed to stand for XML since one of the primary [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on learning JavaScript over the last month or so and I&#8217;ve come to a point where I&#8217;ve started to delve into the hot topic of &#8220;Asynchronous JavaScript, <abbr title="Declarative HyperText Markup Language">DHTML</abbr> and Server-side Programming&#8221;, or as <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php">some pundits</a> have termed it &#8220;Ajax&#8221;.  The &#8216;x&#8217; is supposed to stand for XML since one of the primary enablers for this technology is the JavaScript object <a href="http://jpspan.sourceforge.net/wiki/doku.php?id=javascript:xmlhttprequest:snippets:callback">XMLHttpRequest</a> (though you can use it to return any type of text).<span id="more-79"></span></p>
<div class="ads"><object type="text/html" width="468" height="60" data="http://www.codedread.com/gads.php"></object></div>
<p>Overall, there are two main (and obvious!) problems with programming for the web that I&#8217;ve experienced so far:</p>
<ol>
<li>
<h2>Lack of Cohesion</h2>
<p>I&#8217;m coming from an environment where all I do is program in C++.  To do anything non-trivial for the web requires a solid understanding of at least 5 different technologies:  <a href="http://www.w3.org/TR/xhtml11/">(X)HTML</a>, <a href="http://www.w3.org/TR/CSS21/">CSS</a>, <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">JavaScript</a>, <a href="http://www.php.net/">PHP</a> and the <a href="http://www.w3.org/DOM/DOMTR#dom1">DOM</a> (I separate this from knowing the core JavaScript language).  If you want to use a database, you&#8217;ll also need to know some SQL and how to interface PHP (or ASP or whatever) to the database.  If you want to have some interactive graphics/animations, you&#8217;ll likely need to know Flash or <a href="http://www.w3.org/TR/SVG11/index.html">SVG</a>.  Now we&#8217;re up to seven different technologies.</p>
<p>Learning all these new languages is great, at first.  You can plop those babies onto your resume and sit back and watch the job offers roll in.  However, actually working on a web application can either be tackled in two ways:  1) design up all your interfaces between the various technologies beforehand and then tackle each side in turn (do all your PHP, then work on the client-side bindings, then work on the presentation code, etc) or 2) start to cobble together pieces of things as you work in the hopes of getting something you can watch evolve into your final app. </p>
<p>I&#8217;ve got (maybe) an hour or two to spend each day on something like this.  Which way do you think I work?</p>
<p>Of course, the problem with working on everything at once is that it is really disorienting to switch gears.  I think I&#8217;m getting better at the switch between PHP and JavaScript but it still leaves me a little breathless when I do.</p>
<p>The other problem is that it takes a ridiculous amount of time to do everything you want to do because of the steep learning curves.  Being a man with other priorities (aka &#8220;my family&#8221;) means that the amount of time I can spend learning anything has been drastically reduced since my single days (not that I&#8217;d ever trade my life for that).  Expecting to learn seven new technologies and come up with something &#8220;killer&#8221; is highly unrealistic (and, well, just plain sad, really).  The best I should be hoping for is to focus hard on a one or two areas and partner with others to cover everything.  Alternatively, I can continue creeping along the seven paths and deal with the whole thing as a hobby to fill the time.</p>
<p>Along with the &#8220;developing-everything-at-once&#8221; syndrome, there&#8217;s also the matter of debugging/testing your app.  Basically to test an end-to-end application requires a web server running PHP and potentially a database (<a href="http://www.mysql.com/">MySQL</a>) set up and configured on any machine you want to test it on.  The other option is to constantly FTP your server-side files to your &#8220;live&#8221; web server into a sandbox location (which is what I do, since I tend to work on the same things from different machines throughout the day).</p>
<li>
<h2>Lack of Standards Compliance</h2>
<p>The server-side, I can deal with, and I can deal with it pretty well.  The environment is fixed and even though I&#8217;m not fully in control of it, once I get things straight I really don&#8217;t need to worry too much about it.</p>
<p>The problem comes with all the different browsers (user agents) out there that might chance upon my application / website.  Each browser is made by a different set of developers, each interprets standards a certain way, each has various levels of standards compliance, each has its own sets of bugs and each has special (aka &#8220;non-standards compliant&#8221;) features they have chosen to implement.  Getting even a few browser configurations right when programming up the client-side has proven to be quite a learning curve for me (considering I&#8217;m also learning JavaScript and the DOM).  At this point, I&#8217;m targetting very modern browsers: <a href="http://www.microsoft.com/windows/ie/default.mspx">IE 6.0</a> and <a href="http://www.mozilla.org/products/firefox/">FF 1.0</a>.  I may venture into <a href="http://www.apple.com/macosx/features/safari/">Safari</a>, <a href="http://www.opera.com/">Opera</a>, and <a href="http://www.netscape.com">Netscape</a> at some later stage long after things are stable and well-tested but I don&#8217;t think I&#8217;ll ever try to be compliant with older browsers (Netscape 6-, IE 5-, etc).</p>
</li>
</li>
</ol>
<p>Now the problems I&#8217;ve listed above may be very obvious to a web developer, but what amazes me is that <em> everyone is ok with them</em>.  Web developers seem to thrive in this environment where they have 8 different (and very sharp!) knives instead of one big bazooka.   I can&#8217;t say I can see a solution either:  8 knives it is&#8230;they all do different tasks (and they do them pretty good).</p>
<p>I&#8217;d like to make at least one suggestion:  Someone come up with PHP for the web browser, will you?  By this, I mean being able to write a client-side script in PHP in a web page that can access the DOM.  At least if we have this then we can use one scripting language on both ends:  server-side we have the core PHP and the massive PHP libraries invoked by the server and client-side we have the core PHP language and the DOM invoked by the browser.  At least then I don&#8217;t need to remember whether my variables need dollar signs in front of them or to be declared with &#8220;var&#8221;&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codedread.com/blog/archives/2005/04/11/ajax-the-power-of-clean/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

