<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Pablo Viquez Blog</title>
	
	<link>http://www.pabloviquez.com</link>
	<description>Mi vida y cosas relacionadas</description>
	<lastBuildDate>Thu, 06 Dec 2012 00:35:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PabloViquezBlog" /><feedburner:info uri="pabloviquezblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/PabloViquezBlog" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FPabloViquezBlog" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>PHP Step by Step Debugging with JMeter, XDebug &amp; Eclipse PDT</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/q6xyvwRRxzM/</link>
		<comments>http://www.pabloviquez.com/2012/12/php-step-by-step-debugging-with-jmeter-xdebug-eclipse-pdt/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 00:21:59 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=364</guid>
		<description><![CDATA[In a previous post I wrote about doing step by step debugging using Zend Debugger and Zend Studio making the calls from JMeter, however not everyone has Zend Server or Zend Studio installed, and since XDebug is an awesome project I though that will be awesome to do the same using XDebug. Basic Intro To [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/">previous post</a> I wrote about doing step by step debugging using Zend Debugger and Zend Studio making the calls from JMeter, however not everyone has Zend Server or Zend Studio installed, and since XDebug is an awesome project I though that will be awesome to do the same using XDebug.</p>
<h3>Basic Intro</h3>
<p>To start, lets define the tools we will required</p>
<p>For this tutorial, you required the following awesome projects:</p>
<ul>
<li>Apache Webserver with the XDebug module installed
<ul>
<li>XDebug is a PHP extension which provides debugging and profiling capabilities. It uses the DBGp debugging protocol.</li>
<li><a href="http://xdebug.org/" target="_blank">http://xdebug.org</a></li>
</ul>
</li>
<li>Eclipse with PHP Development Tools
<ul>
<li>The Eclipse PHP Development Tools project (PDT) is a PHP Integrated Development Environment (IDE). PDT provides all the core capabilities needed in a PHP IDE. Powerful IDE with all the PHP required tools installed. I normally use the All-In-One package, which is the one I used for doing this tutorial</li>
<li><a href="http://www.eclipse.org/pdt/downloads/" target="_blank">http://www.eclipse.org/pdt/downloads/</a></li>
<li><a href="http://www.zend.com/en/community/pdt/downloads" target="_blank">All-In-One download</a></li>
</ul>
</li>
<li>Apache JMeter
<ul>
<li>JMeter is a desktop application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions.</li>
<li><a href="http://jmeter.apache.org/" target="_blank">JMeter Project</a></li>
</ul>
</li>
</ul>
<h2>Issue</h2>
<p>As <a href="http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/">explained previously</a>, using the browser for API debugging can be pretty hard or nearly impossible unless you build some sort of UI, which normally I do not have time to do, so JMeter is perfect for the job!
</p>
<p>Now, the hard part is to be able to do real debugging using JMeter, which means hook JMeter to start the debugging session and catch the XDebug call with Eclipse, which sounds quite hard but on the contrary, it&#8217;s very simple.<br />
<h2>Apache Configuration</h2>
<p>XDebug requires some small configurations in the <em>php.ini</em> file in order to work, lets look at them:</p>
<p>Open the <strong><em>php.ini</em></strong> file add the following configurations <u>(if you don&#8217;t have it already)</u></p>
<pre>
[XDebug]

; Load the XDebug module
zend_extension="{FULL_PATH_FOR_XDEBUG_EXTENSION}/xdebug.so"

; This switch controls whether Xdebug should try to contact a debug client, defaults to 0
; http://xdebug.org/docs/all_settings#remote_enable
xdebug.remote_enable=1


; Selects the host where the debug client is running, you can either use a host name or an
; IP address
; http://xdebug.org/docs/all_settings#remote_host
xdebug.remote_host=127.0.0.1


; If enabled, the xdebug.remote_host setting is ignored and Xdebug will try to connect
; to the client that made the HTTP request. It checks the $_SERVER['REMOTE_ADDR']
; variable to find out which IP address to use. Please note that there is no filter
; available, and anybody who can connect to the webserver will then be able to start a
; debugging session, even if their address does not match
; xdebug.remote_host.
; http://xdebug.org/docs/all_settings#remote_connect_back
; xdebug.remote_connect_back=1

; The port to which Xdebug tries to connect on the remote host. Port 9000 is the
; default for both the client and the bundled debugclient.
; http://xdebug.org/docs/all_settings#remote_port
; xdebug.remote_port=9000


; Can be: php3, gdb or dbgp. The DBGp protocol is more widely supported by clients.
; Default value: dbgp
; http://xdebug.org/docs/all_settings#remote_handler
xdebug.remote_handler=dbgp


; If set to a value, it is used as filename to a file to which all remote debugger
; communications are logged. 
; http://xdebug.org/docs/all_settings#remote_log
xdebug.remote_log="/tmp/xdebug/xdebug.log"


; Controls which IDE Key Xdebug should pass on to the DBGp debugger handler.
; http://xdebug.org/docs/all_settings#idekey
xdebug.idekey=ECLIPSE_DBGP

</pre>
<h3>Remote Debugging Gotchas</h3>
<ol>
<li>XDebug <strong>requires</strong> a local copy of the source code, if you are doing remote debugging, you need to have the project configured locally</li>
<li>You can follow the same steps and do remote debugging, as long as you have the code locally. You don&#8217;t require a working instance running, just the code.</li>
<li><strong>Important:</strong> For remote debugging make sure your local port 9000 is open and can receive connections from the remote host.</li>
</ol>
<h2>Eclipse PDT Setup</h2>
<p>In Eclipse, we need to create a new project, in my case I&#8217;ll use the same Apache instance and domain as the one <a href="http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/">used here</a></p>
<h3>1. Create the project</h3>
<p>Right click in the PHP Explorer area and select <strong>New</strong> &gt; <strong>PHP Project</strong></p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/1_jmeter.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/1_jmeter.png" alt="" title="Create the Eclipse project" class="aligncenter size-full wp-image-374" /></a></p>
<p>&nbsp;</p>
<p>In my case, the project source files were already created, so I selected Created project at existing location</p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/2_project_settings.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/2_project_settings.png" alt="Eclipse Project Settings" title="Eclipse Project Settings" class="size-full wp-image-366" /></a></p>
<p>&nbsp;</p>
<h3>2. Set XDebug as your debugger</h3>
<p>Now we need to tell the project to use XDebug. To do this, right click the project name and select <strong>Properties</strong></p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_setttings1.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_setttings1.png" alt="Project Settings" title="Project Settings" class="size-full wp-image-375" /></a></p>
<p>&nbsp;</p>
<p>In the properties window, select the <strong>PHP Debug</strong> option and select as the PHP Debugger <strong>XDebug</strong>. Once you do that, click <strong>Configure&#8230;</strong></p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings1.png" target="_blank"><img style="width:100%;" src="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings1.png" alt="PHP Project Debug " title="PHP Project Debug " class="size-full wp-image-367" /></a></p>
<p>&nbsp;</p>
<p>Select XDebug and click <strong>Configure</strong></p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings2.png" target="_blank"><img style="width:100%;" src="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings2.png" alt="PHP Project Debug" title="PHP Project Debug" class="size-full wp-image-367" /></a></p>
<p>&nbsp;</p>
<p>Now select <strong>any</strong> for the Accept remote session (JIT) option.</p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings3.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/3_project_xdebug_settings3.png" alt="XDebug Settings" title="XDebug Settings" class="size-full wp-image-369" /></a></p>
<p>&nbsp;</p>
<p>With the previous steps, you should be set and ready for serious debugging!. <strong>NOTE:</strong> I had to restart Eclipse for it to work, I guess because of the port binding but this is just a guess. So after doing these steps it does not work, just restart Eclipse.</p>
<h2>JMeter Plan</h2>
<p>I will be using the exact same plan as my <a href="http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/">previous post</a> with the small difference of the <strong>Cookie Manager</strong>. So I won&#8217;t be covering the JMeter setup, just the <strong>Cookie Manager</strong> part.</p>
<h3>Download the JMeter plan</h3>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/JMeterXdebug.zip">Click here to download the JMeter plan (JMeterXdebug.zip)</a></p>
<p>XDebug is much more simple than Zend Debugger, it just require one cookie called <strong>XDEBUG_SESSION</strong> as follow:</p>
<table cellspacing="1" cellpadding="1" border="1" width="100%">
<tr>
<th>Cookie name</th>
<th>Cookie value</th>
<th>Domain</th>
<th>Path</th>
</tr>
<tr>
<td>XDEBUG_SESSION</td>
<td>ECLIPSE_DBGP</td>
<td><em>Host name</em> In our case, the host is a global JMeter variable, so I&#8217;ll be using <strong>${HOST}</strong></td>
<td>/</td>
</tr>
</table>
<p>&nbsp;</p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/4_jmeter_cookie_manager.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/4_jmeter_cookie_manager.png" alt="JMeter Cookie Manager" title="JMeter Cookie Manager" style="width:100%;"  class="size-full wp-image-370" /></a></p>
<h2>Execute the JMeter plan</h2>
<p>Now let&#8217;s test the plan, on the top menu select <strong>Run &gt; Start</strong></p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/5_jmeter_exec.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/5_jmeter_exec.png" alt="Execute the JMeter Plan" title="Execute the JMeter Plan" class="size-full wp-image-371" /></a></p>
<p>&nbsp;</p>
<p>Now Eclipse should start and ask you to switch to the debug perspective, if you click yes, this is the Eclipse view you will have</p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/6_eclipse_debug1.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/6_eclipse_debug1.png" alt="Eclipse Debugging" title="Eclipse Debugging" style="width:100%;" class="size-full wp-image-376" /></a></p>
<p>Now Eclipse should start and ask you to switch to the debug perspective, if you click yes, this is the Eclipse view you will have</p>
<p>Note that the parameters sent to the request are available in the Variables view</p>
<p><a href="http://www.pabloviquez.com/wp-content/uploads/2012/12/6_eclipse_debug2.png" target="_blank"><img src="http://www.pabloviquez.com/wp-content/uploads/2012/12/6_eclipse_debug2.png" alt="Eclipse Debugging" title="Eclipse Debugging" style="width:100%;" class="size-full wp-image-376" /></a></p>
<h2>You&#8217;re done!</h2>
<p>Congrats you now have a JMeter plan that triggers an XDebug debugging session!</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/q6xyvwRRxzM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2012/12/php-step-by-step-debugging-with-jmeter-xdebug-eclipse-pdt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2012/12/php-step-by-step-debugging-with-jmeter-xdebug-eclipse-pdt/</feedburner:origLink></item>
		<item>
		<title>PHP debugging with JMeter and Zend Debugger</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/QetgvsbQpOw/</link>
		<comments>http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/#comments</comments>
		<pubDate>Fri, 19 Oct 2012 05:49:30 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[debug]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend server]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=327</guid>
		<description><![CDATA[For those who don&#8217;t know what JMeter is, you&#8217;re missing A LOT! in short, JMeter is a desktop application designed to load test functional behavior and measure performance. (http://jmeter.apache.org/) If you&#8217;re working on an API or consuming content from any HTTP service you could easily create a JMeter plan in order to test it. Problem [...]]]></description>
			<content:encoded><![CDATA[<p>For those who don&#8217;t know what JMeter is, <b>you&#8217;re missing A LOT!</b> in short, JMeter is a desktop application designed to load test functional behavior and measure performance. (<a href="http://jmeter.apache.org/" target="_blank">http://jmeter.apache.org/</a>)</p>
<p>If you&#8217;re working on an API or consuming content from any HTTP service you could easily create a JMeter plan in order to test it.</p>
<h2>Problem</h2>
<p>Now, I think JMeter is awesome, no doubt about it, however what if I want to test something while developing a new API Endpoint? well I used to be accustom to the nasty <i>var_dump(); exit;</i> combination or if the API was already completed I used to do <i>error_log()</i> everywhere and figure out the results.</p>
<p>Now, I&#8217;ve been using Zend Studio for quite a while and installed Zend Server on my local machine to test and develop and I love the easy integration that Zend Server has with Zend Studio for debugging and I though to myself, why not just change the client that triggers the debugging console so instead of the browser use JMeter, at the end both uses HTTP so it should work, well guess what, IT DOES, and It&#8217;s awesome. No more print_r, error_log, var_dump in the API, lets do the Step by Step debugging with JMeter!</p>
<h2>Solution</h2>
<p>If you can do it using a browser you can do it using JMeter. So lets start.</p>
<p><strong>Note:</strong> Even though I&#8217;m writting about Zend Debugger and Zend Studio, I would like to point out that the same can be acomplished using XDebug (I&#8217;ll write later on about it). If you don&#8217;t like Zend Server/Zend Studio, don&#8217;t worry, XDebug is an awesome project, it&#8217;s open, free and there are plugins for the most popular browsers and IDEs, <strong>100% recommended!</strong></p>
<h3>Download the JMeter Plan</h3>
<p>JMeter Plan: <a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/JMeterZend.jmx_.zip">JMeterZend.jmx</a></p>
<h3>1. Create a new project in Zend Studio.</h3>
<p>I created a new virtual host on my machine just for the sake of the example. In my case I&#8217;ll use <b>fakesite.pabloviquez.com</b>.</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter1.png" target="_blank"><img style="width:100%;" class="aligncenter size-full wp-image-333" title="Zend Studio Project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter1.png" alt="Zend Studio Project Setup" width="675" height="534" /></a>
</p>
<p>&nbsp;</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter2.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="Zend Studio Project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter2.png" alt="Zend Studio Project Setup" width="675" height="534" /></a></p>
<p>Once that was completed, I added a new page (index.php) with some simple code for the sake of the example.</p>
<p><b>index.php</b></p>
<pre class="brush: php">
&lt;?php
/**
 * This site is a fake site, however I want to make request to
 * it and do step by step debugging with JMeter and
 * Zend Debugger
 *
 * @see http://www.pabloviquez.com
 * @author Pablo Viquez &lt;pviquez@pabloviquez.com&gt;
 */
$startVariable = 1;
$anotherVariable = &#039;x&#039;;

for ($i = 0; $i &lt;= 10; $i++) {
    echo &quot;For loop, i: {$i}\n&lt;br /&gt;\n&quot;;
}
</pre>
<h3>2. Configure Zend Studio</h3>
<p>Open Zend Studio preferences, and open the Installed Debuggers section: PHP &gt; Debug &gt; Installed Debuggers, now write the port used for the Zend Debugger somewhere, we&#8217;re going to need it later on.</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter6.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="Zend Studio installed debuggers" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter6.png" alt="Zend Studio installed debuggers" /><br />
</a></p>
<h3>3. Create a new JMeter Plan</h3>
<p>Open JMeter and create a new plan, should look like this:</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter4.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter4.png" alt="JMeter project" /><br />
</a></p>
<p>Now lets add the following sections using the same structure:</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_13.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_13.png" alt="JMeter project" /><br />
</a></p>
<ul>
<li>Thread Group
<ul>
<li>HTTP Request</li>
<li>HTTP Cookie Manager</li>
</ul>
<li>User Defined Variables</li>
<li>View Results Tree</li>
</li>
</ul>
<h3>4. Configure JMeter</h3>
<p>Now, lets add the required configurations to JMeter in order to make a simple GET request to the index.php page we created in the step 1.</p>
<h3>4.1 User Defined Variables</h3>
<p>Create a new variable with the name <b>HOST</b>, the value must be the host name you&#8217;re going to use <b>without</b> the protocol.</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter8.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter8.png" alt="JMeter project" /><br />
</a></p>
<h3>4.2 HTTP Request</h3>
<p>Click on the HTTP Request, and put the HOST variable we created in the previous step inside the Server Name or IP field.</p>
<p>For the sake of testing, add a parameter in the &#8220;Send Parameters With the Request:&#8221; section. Add whatever you want, this is because I want to be able to see them in the debugger later on.</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_7.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_7.png" alt="JMeter project" /><br />
</a></p>
<h3>4.3 HTTP Cookie Manager</h3>
<p>This is where the magic happens! Zend Debugger requires a set of cookies in the request in order to launch the debugger. Basically, PHP reads these cookies and the Zend Debugger module recognize them, if they are good, the debugger makes a broadcast to the debug port configured launching the debugging session.</p>
<p>The set of key/values are:</p>
<table width="100%" cellspacing="1" cellpadding="1" border="1">
<tbody>
<tr>
<td style="text-align: center;"><strong>Parameter<br />
            </strong></td>
<td style="text-align: center;"><strong>Method<br />
            </strong></td>
<td style="text-align: center;"><strong>Description</strong></td>
</tr>
<tr>
<td>start_debug</td>
<td>GET/COOKIE</td>
<td>Starts the debug session.<br />
            Set to zero to deactivate the debugger.</td>
</tr>
<tr>
<td>debug_host</td>
<td>GET/COOKIE</td>
<td>The client IP to which debugging results will be returned.<br />
            This host should be allowed via php.ini setting <em>zend_debugger.allow_hosts</em>. The default is localhost.</td>
</tr>
<tr>
<td>debug_port</td>
<td>GET/COOKIE</td>
<td>The port to which the debugger will connect. This should match the 			port number configured in Zend Studio (<strong>Window 			| Preferences, PHP | Debug | Installed Debuggers</strong>).</td>
</tr>
<tr>
<td>send_sess_end</td>
<td>GET/COOKIE</td>
<td>Enables 			data to be sent at the end of a profiling session.</td>
</tr>
<tr>
<td>debug_stop</td>
<td>GET/COOKIE</td>
<td>If 			set, the debugger will pause at the first line of PHP code.</td>
</tr>
<tr>
<td>original_url</td>
<td>GET/COOKIE</td>
<td>The 			URL from which the debugging process will start. This is an 			important parameter, since Path Mapping resolution is based on it.</td>
</tr>
<tr>
<td>use_ssl</td>
<td>GET/COOKIE</td>
<td>If 			set, the communication with the client is encrypted using SSL.</td>
</tr>
<tr>
<td>start_profile</td>
<td>GET/COOKIE</td>
<td>Starts 			a profiling session. 			This 			cannot be used simultaneously with a  <em>start_debug</em> request.  			 			The 			<em>send_sess_end</em> flag must be enabled for profiling results to be 			returned.</td>
</tr>
<tr>
<td>debug_start_session</td>
<td>GET/COOKIE</td>
<td>Enables 			debug session capabilities according to the parameter set in 			<em>debug_cont_session</em>.</td>
</tr>
<tr>
<td>debug_start_url</td>
<td>GET</td>
<td>If 			the <em>debug_start_session</em> parameter is set, browsing to the URL 			specified here will activate a debug session. Until this URL is 			reached, the debugger is not triggered even though a debug session 			is still active. After the URL is reached, the session will 			continue according to the settings specified for the 			<em>debug_cont_session</em> parameter.</td>
</tr>
<tr>
<td>debug_cont_session</td>
<td>GET</td>
<td>If 			set to 0, a debug session will be launched once when 			<em>debug_start_url</em> is reached.<br />
            If 			set to 1, the debugging session will be launched once when the 			next link in the <em>debug_start_url</em> is clicked, a form is posted, or 			an AJAX request is executed.<br />
            If 			set to 2, a debug session is started whenever the URL set in 			<em>debug_start_url</em> is browsed to.</td>
</tr>
<tr>
<td>no_remote</td>
<td>GET/COOKIE</td>
<td>If 			set to 1, the file content will only be taken from files located 			on the server.</td>
</tr>
<tr>
<td>use_remote</td>
<td>GET/COOKIE</td>
<td>If set to 1, file content will be taken from the project in Zend Studio.</td>
</tr>
<tr>
<td>debug_file_bp</td>
<td>GET/COOKIE</td>
<td>Sets 			a breakpoint in the specified file.</td>
</tr>
<tr>
<td>debug_line_bp</td>
<td>GET/COOKIE</td>
<td>Sets 			a breakpoint in the specified line in the file configured in 			<em>debug_file_bp</em>.</td>
</tr>
<tr>
<td>_bm</td>
<td>GET/COOKIE</td>
<td>Sets 			a bitmask with the configured options.</td>
</tr>
<tr>
<td>debug_jit</td>
<td>COOKIE</td>
<td>Debugger 			will delete cookie values after the debug session ends.</td>
</tr>
<tr>
<td>debug_fastfile</td>
<td>GET/COOKIE</td>
<td>Speeds 			up file exchange. Supported in Zend Studio since version 6.1.0</td>
</tr>
<tr>
<td>debug_coverage</td>
<td>GET/COOKIE</td>
<td>Enables 			code coverage when profiling.</td>
</tr>
<tr>
<td>debug_session_id</td>
<td>GET/COOKIE</td>
<td>Debug session ID. Zend Studio since version 6.0.0 can work with several simultaneous debug sessions. This parameter allows to specify which debug session to attach to.</td>
</tr>
</tbody>
</table>
<p><span style="font-size:8px">(Values taken from: <a href="http://kb.zend.com/index.php?View=entry&#038;EntryID=434" target="_blank">http://kb.zend.com/index.php?View=entry&#038;EntryID=434</a>)</span></p>
<p>Using those values, now add them to the HTTP Cookie manager:</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter9.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter9.png" alt="JMeter project" /><br />
</a></p>
<h3>5. Run the test plan!</h3>
<p>Click Run &gt; Run</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_10.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_10.png" alt="JMeter project" /><br />
</a></p>
<p>The IDE should start! with the step by step debugging</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_11.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_11.png" alt="JMeter project" /><br />
</a></p>
<p>Once completed you can check the results like you normally will do.</p>
<p style="text-align: center;border:solid 1px #333;">
<a href="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_12.png" target="_blank"><br />
<img style="width:100%;" class="aligncenter size-full wp-image-333" title="JMeter project" src="http://www.pabloviquez.com/wp-content/uploads/2012/10/jmeter_12.png" alt="JMeter project" /><br />
</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/QetgvsbQpOw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2012/10/php-debugging-with-jmeter-and-zend-debugger/</feedburner:origLink></item>
		<item>
		<title>MySQL Profiling and Zend Framework</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/EWk9WF6ztiU/</link>
		<comments>http://www.pabloviquez.com/2010/08/mysql-profiling-and-zend-framework/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 01:48:46 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[debug]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=300</guid>
		<description><![CDATA[You can do profiling on PHP using XDebug or Zend Debugger ad both works beautifully, however what about MySQL? Can you do something similar? The response is yes you can. Now the best part is that you can take advantage of the tools MySQL give you, if you want to take the profiler to a [...]]]></description>
			<content:encoded><![CDATA[<p>You can do profiling on PHP using XDebug or Zend Debugger ad both works beautifully, however what about MySQL? Can you do something similar?</p>
<p>The response is <b>yes you can</b>. Now the best part is that you can take advantage of the tools MySQL give you, if you want to take the profiler to a new level.</p>
<h2>ZF built-in profiler.</h2>
<p>If you just care about the time that takes a certain query to execute and retrieve the data on your PHP application, then this might be the best choice for you.</p>
<p>Zend Framework provides a built in profiler for MySQL that keep tracks of the time that took a query to execute on your page and as a plus you can get the results displayed using Firebug (see: <a href="http://www.pabloviquez.com/2009/11/zend_log-firebug-and-zend_application-another-how-to/" target="_self">how to enable Firebug on ZF</a>), the setup is quite simple and does not require rocket science to get it up and running.</p>
<p>To enable the MySQL profiling built in on ZF + FirePHP just modified the config file (assuming you’re using a ZF with Zend_Application):</p>
<p><b>config.ini</b>
<pre class="brush: php">
database.params.profiler.enabled = true
database.params.profiler.class = Zend_Db_Profiler_Firebug
</pre>
<p>That’s it! easy enough huh?</p>
<p><strong>ZF built-in profiler preview</strong></p>
<p style="text-align: center;border:solid 1px #333;"><img class="aligncenter size-full wp-image-307" title="Zend_Db_Profiler_Firebug" src="http://www.pabloviquez.com/wp-content/uploads/2010/08/Zend_Db_Profiler_Firebug.png" alt="This is how it should look" width="597" height="233" /></p>
<h2>MySQL Profiler Advanced</h2>
<p>If you care about deep performance and want to see &#8220;real&#8221; MySQL profiling, which tells you what did MySQL engine actually did, and the time it took to performed each particular step, then this is your best choice.</p>
<p>You can enable profiling on MySQL itself, which you can later query and see what did the database actually did in order to get your data.</p>
<p>Applying the same plugin architecture, you need to write a new plugin and register it. In this case I’ll assume the following directory structure:</p>
<pre>
lib/
   MyApp/
      Controller/
         Plugin/
            MySQLProfiling.php
   zend/
    *
</pre>
<p>The MySQLProfiling.php will contain the necessary code to communicate with the MySQL DB server and get the data I want:</p>
<p><strong>MySQLProfiling.php</strong></p>
<pre class="brush: php">
&lt;?php
/**
 * MySQL Profiling plugin
 *
 * Enables the profiling feature on MySQL server, queries it and
 * retrieves the nescesary data for each individual query.
 *
 * @category MyApp
 * @package MyApp_Controller
 * @subpackage MyApp_Controller_Plugin
 * @author Pablo Viquez &lt;pviquez@pabloviquez.com&gt;
 */
class MyApp_Controller_Plugin_MySQLProfiling
    extends Zend_Controller_Plugin_Abstract
{
    /**
     * Constant to use to diferentiate the queries that dont require
     * profiling
     *
     * @var string
     */
    const DONT_PROFILE = &#039;/*DN_PROFILE*/ &#039;;

    /**
     * Predispatch loop.
     *
     * Is called before an action is dispatched by the dispatcher. This
     * callback allows for proxy or filter behavior. By altering the
     * request and resetting its dispatched flag (via
     * Zend_Controller_Request_Abstract::setDispatched(false)), the
     * current action may be skipped and/or replaced.
     *
     * @return null
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // Init the profiler
        $db = GET_DB_CONNECTION_INSTANCE
        $db-&gt;query(self::DONT_PROFILE . &#039;set profiling=1&#039;);
        $db-&gt;query(self::DONT_PROFILE . &#039;set profiling_history_size=100&#039;);
    }

    /**
     * Postdispatch Loop.
     *
     * Is called after an action is dispatched by the dispatcher. This
     * callback allows for proxy or filter behavior.
     */
    public function postDispatch(
        Zend_Controller_Request_Abstract $request)
    {
        $columns =
            array(
                &#039;Query ID&#039;,
                &#039;Duration&#039;,
                &#039;Executed Query&#039;);

        $profiles =
            $this-&gt;_constructFirePhp(
                $columns,
                &#039;MySQL Profiling - Profiles&#039;);

        $columns =
            array(
                &#039;Query ID&#039;,
                &#039;SEQ&#039;,
                &#039;State&#039;,
                &#039;numb ops&#039;,
                &#039;Total duration&#039;,
                &#039;Avg duration&#039;,
                &#039;Total CPU&#039;,
                &#039;Avg CPU&#039;,
                &#039;Avg CPU Sys&#039;,
                &#039;Block Ops In&#039;,
                &#039;Block Ops Out&#039;);

        // Do the MySQL profiling
        $queryIds = $this-&gt;_setProfiles($profiles);

        // Get the profiling for each individual query
        foreach ($queryIds as $id) {
            $queriesProfile =
                $this-&gt;_constructFirePhp(
                    $columns,
                    &quot;MySQL Profiling - Query ID: {$id}&quot;);
            $this-&gt;_getProfileForQueryId($queriesProfile, $id);
        }
    }

    /**
     * Retrieves the query profile for each indidividual query
     *
     * @param Zend_Wildfire_Plugin_FirePhp_TableMessage $profiles
     * @param int $queryId
     * @return void
     */
    private function _getProfileForQueryId(
        Zend_Wildfire_Plugin_FirePhp_TableMessage $profiles,
        $queryId)
    {
        if (!ctype_digit((string)$queryId)) {
            return;
        }

        $query = self::DONT_PROFILE .
            &quot;SELECT {$queryId},
                    MIN(seq),
                    state,
                    COUNT(*),
                    ROUND(SUM(duration),5),
                    ROUND(AVG(duration),5),
                    ROUND(SUM(cpu_user),5),
                    ROUND(AVG(cpu_user),5),
                    ROUND(AVG(cpu_system),5) ,
                    ROUND(AVG(block_ops_in),5),
                    ROUND(AVG(block_ops_out),5)
               FROM information_schema.profiling
              WHERE query_id = {$queryId}
           GROUP BY state
           ORDER BY seq&quot;;

        $db = GET_DB_CONNECTION_INSTANCE
        $sth = $db-&gt;query($query);
        $rows = $sth-&gt;fetchAll();

        foreach($rows as $row) {
            $values = array_values($row);
            $profiles-&gt;addRow($values);
        }
    }

    /**
     * Constructs and send the profiles table.
     *
     * @param Zend_Wildfire_Plugin_FirePhp_TableMessage $profiles
     * @return array Retrieves an array with the queries profiles
     */
    private function _setProfiles(
        Zend_Wildfire_Plugin_FirePhp_TableMessage $profiles)
    {
        // Get the profiles
        $db = GET_DB_CONNECTION_INSTANCE
        $sth = $db-&gt;query(self::DONT_PROFILE . &#039;show profiles&#039;);
        $rows = $sth-&gt;fetchAll();

        $queryIds = array();
        foreach($rows as $row) {
            // Profile only queries marked as profile
            if (!(strpos($row[&#039;Query&#039;], self::DONT_PROFILE) === false)) {
                continue;
            }

            $queryIds[] = $row[&#039;Query_ID&#039;];
            $values = array_values($row);
            $profiles-&gt;addRow($values);
        }

        return $queryIds;
    }

    /**
     * Constructs the FirePHP messages.
     *
     * @param array $profiles
     * @param string $label
     * @return Zend_Wildfire_Plugin_FirePhp_TableMessage
     */
    private function _constructFirePhp(
        array $columns,
        $label,
        $setBuffer = true)
    {
        $msg = new Zend_Wildfire_Plugin_FirePhp_TableMessage($label);

        // If a message is buffered it can be updated for the duration
        // of the request and is only flushed at the end of the request.
        $msg-&gt;setBuffered($setBuffer);
        $msg-&gt;setHeader($columns);

        // Destroy the message to prevent delivery
        $msg-&gt;setOption(&#039;includeLineNumbers&#039;, false);
        Zend_Wildfire_Plugin_FirePhp::getInstance()-&gt;send($msg);
        return $msg;
    }
}

</pre>
<p>Now, you need to modify 3 lines of code, in the same file “MySQLProfiling.php” look in the lines 38, 122 and 142.</p>
<pre class="brush: php">
$db = GET_DB_CONNECTION_INSTANCE
</pre>
<p>Modify those lines and instead of &#8220;GET_DB_CONNECTION_INSTANCE&#8221; replace it with a call to your DB handler that you created with &#8220;Zend_Db::factory&#8221;.</p>
<p>Once that’s done, you can enable the plugin by either registering it on your bootstrap, or enabling it on your config file:</p>
<p><strong>config.ini</strong></p>
<pre class="brush: php">
resources.frontController.plugins.MySQLProfiling = MyApp_Controller_Plugin_MySQLProfiling
</pre>
<p>Done! you should have your MySQL profiler running!</p>
<p><strong>MySQL profiling plugin preview</strong></p>
<p style="text-align: center;border:solid 1px #333;">
<img class="aligncenter size-full wp-image-306" title="MyApp_Controller_Plugin_MySQLProfiling" src="http://www.pabloviquez.com/wp-content/uploads/2010/08/MyApp_Controller_Plugin_MySQLProfiling.png" alt="" width="992" height="614" /></p>
<h2>Keep in mind…</h2>
<p>Always keep in mind…</p>
<ul>
<li>DB profile tools SHOULD BE USE on development environments only.</li>
<li>The plugin is set to profile 100 queries (line 40), <u>I HOPE</u> your page contains much less than 100 queries, however be aware that for every query performed on your page, the plugin will generate one table with all the data plus the profiles table.</li>
</ul>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/EWk9WF6ztiU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2010/08/mysql-profiling-and-zend-framework/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2010/08/mysql-profiling-and-zend-framework/</feedburner:origLink></item>
		<item>
		<title>Zend Framework Documentation</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/7EW6GAbzXPI/</link>
		<comments>http://www.pabloviquez.com/2010/03/zend-framework-documentation/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 08:09:46 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[chm]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=272</guid>
		<description><![CDATA[I&#8217;ve been wanting to do this for quite some time now, so here it&#8217;s. Go to the downloads As you might now, you can view and download the Zend Framework reference manual from the Zend Framework site and download it from the download section, however what I wanted was the Windows compiled version of it [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been wanting to do this for quite some time now, so here it&#8217;s. <a href="#zf_chm_download">Go to the downloads</a></p>
<p>As you might now, you can view and download the Zend Framework reference manual from the Zend Framework site and download it from the download section, however what I wanted was the Windows compiled version of it (CHM file). In order to get this version you need to compile the documentation, after running into some small issues, I manage to do it, and to save you some work here it&#8217;s <img src='http://www.pabloviquez.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>By the way, the problem I had was parsing one XML file. Zend Framework issue tracker reports that the <a href="http://zendframework.com/issues/browse/ZF-9290">issue was fixed</a> but the SVN tag have the error, anyway if you try to create the documentation from the SVN repository for the version 1.10.2, you will encounter some parsing errors, in order to fix those, you can do this:</p>
<p><strong>Line 161</strong><br />
From:
<pre class="brush: xml">
&lt;title type=&quot;html&quot;&gt;&lt;![CDATA[All Your Base Are Belong To Us]]&gt;&lt;/title&gt;
</pre>
<p>To:
<pre class="brush: xml">
&lt;title type=&quot;html&quot;&gt;&lt;![CDATA[All Your Base Are Belong To Us]]&amp;gt;&lt;/title&gt;
</pre>
<p><strong>Line 163</strong><br />
From:
<pre class="brush: xml">
&lt;![CDATA[Exposing the difficultly of porting games to English.]]&gt;
</pre>
<p>To:
<pre class="brush: xml">
&lt;![CDATA[Exposing the difficultly of porting games to English.]]&amp;gt;
</pre>
<p><strong>Line 177</strong><br />
From:
<pre class="brush: xml">
The example is long enough as is ;;).]]&gt;
</pre>
<p>To:
<pre class="brush: xml">
The example is long enough as is ;;).]]&amp;gt;
</pre>
<p><strong>IMPORTANT</strong>, since you escaped the XML file, you also need to revert it in the generated HTML file.</p>
<p>Anyway, if you want you can just download both files here: <a href="http://www.pabloviquez.com/wp-content/uploads/2010/03/zend.feed_.writer.zip">Zend_Feed_Writer.xml and zend.feed.writer.html</a></p>
<p><a name="zf_chm_download"></a></p>
<h2>Zend Framework Documentation &#8211; CHM Format</h2>
<p>I compile the CHM format for English and Spanish, the spanish version is incomplete so you might find some parts in english.</p>
<p><center></p>
<table width="70%" align="center">
<tr>
<th bgcolor="#405A69" scope="col">
<div align="center"><font color="#FFFFFF">English</font></div>
</th>
<th bgcolor="#405A69" scope="col">
<div align="center"><font color="#FFFFFF">Español</font></div>
</th>
</tr>
<tr>
<td>
<div align="center"><a href="http://www.pabloviquez.com/wp-content/uploads/2010/03/Zend_Framework_en.zip"><font color="#0000CC"><u>Zend_Framework_en.chm</u></font></a></div>
</td>
<td>
<div align="center"><a href="http://www.pabloviquez.com/wp-content/uploads/2010/03/Zend_Framework_es.zip"><font color="#0000CC"><u>Zend_Framework_es.chm</u></font></a></div>
</td>
</tr>
</table>
<p></center></p>
<h3>Información para el archivo en español</h3>
<p>La documentación en español está incompleta y debido a esto, se econtrará muchas secciones de la guía en inglés.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/7EW6GAbzXPI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2010/03/zend-framework-documentation/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2010/03/zend-framework-documentation/</feedburner:origLink></item>
		<item>
		<title>Zend_Log, FirePHP and Zend_Application. How to</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/8bep8JF8gj8/</link>
		<comments>http://www.pabloviquez.com/2009/11/zend_log-firebug-and-zend_application-another-how-to/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 22:23:36 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[debug]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firephp]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=243</guid>
		<description><![CDATA[I wanted to enable logging of exceptions to my PHP log file and also display them using FireBug. On a standard setup of Zend Framework, the Zend error handler plugin (Zend_Controller_Plugin_ErrorHandler) enable by default and it was designed for: Errors due to missing controllers or actions Errors occurring within action controllers I wanted to keep [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to enable logging of exceptions to my PHP log file and also display them using FireBug.</p>
<p>On a standard setup of Zend Framework, the Zend error handler plugin (Zend_Controller_Plugin_ErrorHandler) enable by default and it was designed for:</p>
<ul>
<li>Errors due to missing controllers or actions</li>
<li>Errors occurring within action controllers</li>
</ul>
<p>I wanted to keep using the error handler plugin and didn&#8217;t want to log the exceptions by using: <em>Zend_Controller_Front::throwExceptions()</em> or <em>Zend_Controller_Response_Abstract::renderExceptions()</em> or any other way since eventually might get complicated, besides, I think that the error handler plugin works fine and if it gets updated in the future, I won&#8217;t have to do a major refactor.</p>
<p>So this is how  I did it:</p>
<h2>Create the Zend Log Object</h2>
<p>Using Zend_Application can be very helpful here, because you can init the logger and automatically store the object in the registry, making available to the controllers later on.</p>
<p>Summary, if you want an object created on the boostrap class, to be available on the controllers later, you need to return it from the init method, in this case, we&#8217;re initializing the Zend_Log, so we need to return the object.</p>
<pre class="brush: php">
&lt;?php
class App_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    /**
     * Initializes the logging on the application
     * 
     * We&#039;re using 2 ways for logging exceptions:
     * 1. PHP Error log file.
     * 2. Firebug for Development environments only.
     *
     * @return Zend_Log
     */
    protected function _initLogger()
    {
        // Create the Zend_Log object
        $logger = new Zend_Log();

        // Create the resource for the error log file
        // if you dont want to use the error suppressor &quot;@&quot;
        // you can always use: is_writable
        // http://php.net/manual/function.is-writable.php
        $stream = @fopen(ini_get(&#039;error_log&#039;), &#039;a&#039;);
        if ($stream) {
            $stdWritter = new Zend_Log_Writer_Stream($stream);
            $stdWritter-&gt;addFilter(Zend_Log::DEBUG);
            $stdWritter-&gt;addFilter(Zend_Log::INFO);
            $logger-&gt;addWriter($stdWritter);
        }

        // Create the Firebug writter - Development only
        if ($this-&gt;_application-&gt;getEnvironment() != &#039;production&#039;) {
            // Init firebug logging
            $fbWriter = new Zend_Log_Writer_Firebug();
            $logger-&gt;addWriter($fbWriter);
        }

        return $logger;
    }
</pre>
<p>I have now the log object but I&#8217;m not logging anything yet, so I need to implement the logging part.</p>
<h2>Log the Exception</h2>
<p>For this part, I thought in 2 ways to do it:</p>
<ol>
<li>Extend the error handler plugin and log errors there.</li>
<li>Log the errors on the error controller.</li>
</ol>
<p>I choose the second one for several reasons:</p>
<ol>
<li>Easier.</li>
<li>If the error handler changes somehow, you dont have to change your code.</li>
<li>Extending the error plugin, might lead to repeated code and eventually deprecated code.</li>
</ol>
<p>By default, Zend_Controller_Plugin_ErrorHandler will forward to ErrorController::errorAction() in the default module.</p>
<p>Now in order to retrieve a resource created in the bootstrap we need to access the bootstrap registered in the front controller, and from there we can get our logger:</p>
<pre class="brush: php">
// The method _initLogger on the class App_Bootstrap
// returns a Zend_Log object that is available
// on the Zend_Registry. To retrieve it we need to request the
// bootstrap from the Front controller and then get the logger.
$boot = $this-&gt;getInvokeArg(&#039;bootstrap&#039;);
if ($boot-&gt;hasResource(&#039;logger&#039;)) {
    $log_object = $boot-&gt;getResource(&#039;logger&#039;);
}
</pre>
<p>So using the <a href="http://framework.zend.com/manual/en/zend.controller.plugins.html#zend.controller.plugins.standard.errorhandler.fourohfour" target="_blank">Zend Framework default error controller</a> (the one provided on the reference), with the logging will be something like this:</p>
<pre class="brush: php">
class ErrorController extends Zend_Controller_Action
{
    /**
     * Error action. This method is called by
     * Zend_Controller_Plugin_ErrorHandler
     *
     * @see Zend_Controller_Plugin_ErrorHandler
     * @return void
     */
    public function errorAction()
    {
        $errors = $this-&gt;_getParam(&#039;error_handler&#039;);

        // Log the Error.
        $boot = $this-&gt;getInvokeArg(&#039;bootstrap&#039;);
        if ($boot-&gt;hasResource(&#039;logger&#039;)) {
            $boot-&gt;getResource(&#039;logger&#039;)-&gt;err($errors-&gt;exception);
        }

        // Default error handling...
        switch ($errors-&gt;type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // 404 error -- controller or action not found
                $this-&gt;getResponse()-&gt;setHttpResponseCode(404);
                $this-&gt;view-&gt;message = &#039;Page not found&#039;;
                break;
            default:
                // application error
                $this-&gt;getResponse()-&gt;setHttpResponseCode(500);
                $this-&gt;view-&gt;message = &#039;Application error&#039;;
                break;
        }

        $this-&gt;view-&gt;exception = $errors-&gt;exception;
        $this-&gt;view-&gt;request   = $errors-&gt;request;
    }
}
</pre>
<h2>Result</h2>
<p>The final result looks like this:</p>
<h3>Firefox with Firebug enabled:</h3>
<p><img class="size-full wp-image-245" title="Firebug Screenshot" src="http://www.pabloviquez.com/wp-content/uploads/2009/11/firebug.gif" alt="Firefox Screenshot with Firebug enabled" width="851" height="511" /></p>
<h3>PHP error log file:</h3>
<pre class="brush: shell">
[pviquez /usr/home/pviquez]$ cat php_error.log
2009-11-25T15:23:19-06:00 ERR (3): exception &#039;Zend_Exception&#039; with message &#039;The logging is working!&#039; in /usr/home/pviquez/app/deploy/application/modules/admin/controllers/IndexController.php:33
Stack trace:
#0 /usr/home/pviquez/app/deploy/library/Zend/Controller/Action.php(513): Admin_IndexController-&gt;indexAction()
#1 /usr/home/pviquez/app/deploy/library/Zend/Controller/Dispatcher/Standard.php(289): Zend_Controller_Action-&gt;dispatch(&#039;indexAction&#039;)
#2 /usr/home/pviquez/app/deploy/library/Zend/Controller/Front.php(946): Zend_Controller_Dispatcher_Standard-&gt;dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#3 /usr/home/pviquez/app/deploy/library/Zend/Application/Bootstrap/Bootstrap.php(77): Zend_Controller_Front-&gt;dispatch()
#4 /usr/home/pviquez/app/deploy/library/Zend/Application.php(346): Zend_Application_Bootstrap_Bootstrap-&gt;run()
#5 /usr/home/pviquez/app/deploy/public/index.php(23): Zend_Application-&gt;run()
#6 {main}
</pre>
<h2>References</h2>
<ul>
<li>Install Firebug on Firefox <a href="https://addons.mozilla.org/firefox/addon/1843">Firebug Add-on</a></li>
<li>Error Handler Plugin: <a href="http://framework.zend.com/manual/en/zend.controller.plugins.html#zend.controller.plugins.standard.errorhandler">http://framework.zend.com/manual/en/zend.controller.plugins.html#zend.controller.plugins.standard.errorhandler</a></li>
<li>MVC Exceptions: <a href="http://framework.zend.com/manual/en/zend.controller.exceptions.html">http://framework.zend.com/manual/en/zend.controller.exceptions.html</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/8bep8JF8gj8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/11/zend_log-firebug-and-zend_application-another-how-to/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/11/zend_log-firebug-and-zend_application-another-how-to/</feedburner:origLink></item>
		<item>
		<title>Export Excel Spreadsheets using Zend Framework</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/eykAumd-Ldg/</link>
		<comments>http://www.pabloviquez.com/2009/08/export-excel-spreadsheets-using-zend-framework/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 20:04:11 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Excel Spreadsheets]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=224</guid>
		<description><![CDATA[Last week, I had to allow the user to export a given report into an MS Excel file format. The application uses Zend Framework 1.9.1 and so far ZF does not support for &#8220;Office&#8221; formats, so after searching for a nice implementation, I found a PEAR module called Spreadsheet Excel Writter, which looked pretty good, [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, I had to allow the user to export a given report into an MS Excel file format.</p>
<p>The application uses <a href="http://www.zendframework.com/" target="_blank">Zend Framework 1.9.1</a> and so far ZF does not support for &#8220;Office&#8221; formats, so after searching for a nice implementation, I found a PEAR module called <a href="http://pear.php.net/package/Spreadsheet_Excel_Writer/" target="_blank">Spreadsheet Excel Writter</a>, which looked pretty good, it had very good documentation and the code was clean and well structured so I wanted to give it a shot.</p>
<h2>1. PEAR Setup</h2>
<p>I used the web interface for the PEAR setup which worked pretty good! (Not covering PEAR installation here). </p>
<p>If you want more info on how to install PEAR, go here: http://pear.php.net/manual/en/installation.getting.php and for the web setup: http://pear.php.net/go-pear</p>
<p><b>ONCE INSTALLED, REMEMBER TO ADD THE PEAR PATH TO YOUR INCLUDE PATH</b></p>
<h2>2. Following the MVC pattern.</h2>
<div class="wp-caption alignright" style="width: 331px"><img title="Model View Controller" src="http://www.pabloviquez.com/images/ModelViewControllerDiagram.png" alt="Model View Controller" width="321" height="151" /><p class="wp-caption-text">Model View Controller Diagram</p></div>
<p>I love the architecture following <a href="http://framework.zend.com/docs/quickstart" target="_blank">MVC (Model View Controller)</a> and if I follow the MVC pattern, excel file will go as VIEW, this because the data is being presented  an excel file.</p>
<p>Also, the controller does not care which format does the info gets display, the controller should care about manipulating modules, getting the data, controlling the flow of the application not about the presentation layer.</p>
<h3>So what did I do?</h3>
<p>Zend Framework offers a nice feature called <a href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch" target="_blank">&#8220;Context Switch&#8221;</a>. This is an <a href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html" target="_blank">action helper</a> that detects requested output and calls the specific view for the required format.</p>
<p>In my case, I wanted to enable this feature to the user controller, which had 3 actions:</p>
<ul>
<li>user/index</li>
<li>user/new</li>
<li>user/report</li>
</ul>
<p>Now, I wanted to give the option to export the data as excel only for the &#8220;report&#8221; action, so I did this on the controller init method:</p>
<pre class="brush: php">
class UserController extends Zend_Controller_Action
{
    /**
     * Initializes the controller
     *
     * @return void
     */
    public function init()
    {
        // Optional added for consistency
        parent::init();

        // Excel format context
        $excelConfig =
            array(
                &#039;excel&#039; =&gt; array(
                    &#039;suffix&#039;  =&gt; &#039;excel&#039;,
                    &#039;headers&#039; =&gt; array(
                        &#039;Content-type&#039; =&gt; &#039;application/vnd.ms-excel&#039;)),
            );

        // Init the Context Switch Action helper
        $contextSwitch = $this-&gt;_helper-&gt;contextSwitch();

        // Add the new context
        $contextSwitch-&gt;setContexts($excelConfig)

        // Set the new context to the reports action
        $contextSwitch-&gt;addActionContext(&#039;report&#039;, &#039;excel&#039;)

        // Initializes the action helper
        $contextSwitch-&gt;initContext();
    }

    public function indexAction() { /* ... */ }
    public function newAction() { /* ... */ }
    public function reportAction() { /* ... */ }
}

</pre>
<p>What this code does is that it tells the controller to search on the parameters (GET/POST) for token &#8220;format&#8221; and the value &#8220;excel&#8221;. In other words, If the report action get requested like this:</p>
<p>/user/report?format=excel or /user/report/format/excel instead of loading the view: report.phtml will load the view report.excel.phtml and here is where the magic happens!</p>
<p>In the setup of the Context Switch, the &#8220;suffix&#8221; is what will be appended to the view file.</p>
<p>The report action, just gets the report and sets a variable on the view so it&#8217;s accesible as follow:</p>
<pre class="brush: php">
class UserController extends Zend_Controller_Action
{
    public function init() { /* ... */ }
    public function indexAction() { /* ... */ }
    public function newAction() { /* ... */ }

    /**
     * Report action
     *
     * @return void
     */
    public function reportAction()
    {
        // Proof of concept
        // Lets say that the result have the following structure
        // 
        // array(
        //     [USER ID] =&gt; array(
        //                      &#039;name&#039;  =&gt; &#039;Pablo Víquez&#039;,
        //                      &#039;email&#039; =&gt; &#039;email@domain.com&#039;,
        //                  ),
        //     [USER_ID] =&gt; array(...),
        //     ...
        // )
        $this-&gt;view-&gt;users = User_Model_Name::getReport();
    }
}
</pre>
<h3>Now the view&#8230;</h3>
<p>I need to have 2 files for this action:</p>
<ul>
<li>report.phtml &#8211; Output will be regular HTML</li>
<li>report.excel.phtml &#8211; Output will be an MS Excel spreadsheet</li>
</ul>
<h3>report.phtml</h3>
<p>This is the HTML format.</p>
<pre class="brush: html">
&lt;h1&gt;Users report&lt;/h1&gt;

&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;User Id&lt;/th&gt;
            &lt;th&gt;Name&lt;/th&gt;
            &lt;th&gt;Email&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
&lt;!--
    Variable set on the controller, if there&#039;s no data to display
    the count will be 0.
--&gt;
&lt;?php if(count($this-&gt;users) &gt; 0) : ?&gt;
&lt;?php foreach ($this-&gt;users as $userId =&gt; $user) : ?&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;?php echo $userId; ?&gt;&lt;/td&gt;
        &lt;td&gt;&lt;?php echo $user[&#039;name&#039;]; ?&gt;&lt;/td&gt;
        &lt;td&gt;&lt;?php echo $user[&#039;email&#039;]; ?&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;?php endforeach; ?&gt;
&lt;?php endif; ?&gt;
&lt;/table&gt;

</pre>
<h3>report.excel.phtml</h3>
<pre class="brush: php">

// Change error reporting for compatibility
// Spreadsheet Excel Writter was built using PHP4,
// so there&#039;s a lot of DEPRECATED notices
error_reporting(E_ERROR | E_WARNING | E_PARSE);


/**
 * PEAR package
 *
 * @link http://pear.php.net/package/Spreadsheet_Excel_Writer
 * @see PEAR/Spreadsheet/Excel/Writer.php
 */
require_once &#039;Spreadsheet/Excel/Writer.php&#039;;


// Lets define some custom colors codes
define(&#039;CUSTOM_DARK_BLUE&#039;, 20);
define(&#039;CUSTOM_BLUE&#039;, 21);
define(&#039;CUSTOM_LIGHT_BLUE&#039;, 22);
define(&#039;CUSTOM_YELLOW&#039;, 23);
define(&#039;CUSTOM_GREEN&#039;, 24);


// First, we create a Workbook
$workbook = new Spreadsheet_Excel_Writer();


// Add one sheet, called: Users Report
$worksheet = &amp;$workbook-&gt;addWorksheet(&#039;Users Report&#039;);


// Create the custom colors on our new workbook
// This function takes 4 params:
//    - Code index [1 to 64]
//    - RGB colors (0-255)
$workbook-&gt;setCustomColor(CUSTOM_DARK_BLUE, 31, 73, 125);
$workbook-&gt;setCustomColor(CUSTOM_BLUE, 0, 112, 192);
$workbook-&gt;setCustomColor(CUSTOM_LIGHT_BLUE, 184, 204, 228);
$workbook-&gt;setCustomColor(CUSTOM_YELLOW, 255, 192, 0);
$workbook-&gt;setCustomColor(CUSTOM_GREEN, 0, 176, 80);


// Lets hide gridlines
$worksheet-&gt;hideScreenGridlines();


// Lets create some custom styles
$formatHeader = &amp;$workbook-&gt;addFormat();
$formatHeader =
    &amp;$workbook-&gt;addFormat(
        array(&#039;Size&#039;    =&gt; 16,
              &#039;VAlign&#039;  =&gt; &#039;vcenter&#039;,
              &#039;HAlign&#039;  =&gt; &#039;center&#039;,
              &#039;Bold&#039;    =&gt; 1,
              &#039;Color&#039;   =&gt; &#039;white&#039;,
              &#039;FgColor&#039; =&gt; CUSTOM_DARK_BLUE));


$formatReportHeader =
    &amp;$workbook-&gt;addFormat(
        array(&#039;Size&#039;     =&gt; 9,
              &#039;VAlign&#039;   =&gt; &#039;bottom&#039;,
              &#039;HAlign&#039;   =&gt; &#039;center&#039;,
              &#039;Bold&#039;     =&gt; 1,
              &#039;FgColor&#039;  =&gt; CUSTOM_LIGHT_BLUE,
              &#039;TextWrap&#039; =&gt; true));

$formatData =
    &amp;$workbook-&gt;addFormat(
        array(
            &#039;Size&#039;   =&gt; 8,
            &#039;HAlign&#039; =&gt; &#039;center&#039;,
            &#039;VAlign&#039; =&gt; &#039;vcenter&#039;));

/**
 * First, format the worksheet, adding the headers
 * and row/columns custom sizes
 */

// Create a nice header with a dark blue background
// The function setRow takes 3 parameters:
//    - row index
//    - row height
//    - Format to apply to row [Optional]
$worksheet-&gt;setRow(0, 11, $formatHeader);
$worksheet-&gt;setRow(1, 46, $formatHeader);
$worksheet-&gt;setRow(2, 11, $formatHeader);


// Set the size of the columns
// The function setColumn takes 5 params:
//     - First column
//     - Last column
//     - Column Width
//     - Format [Optional, default = 0]
//     - Hidden [Optional, default = 0]
$worksheet-&gt;setColumn(0, 0, 7); // User Id, shrink it to 7
$worksheet-&gt;setColumn(1, 1, 12); // Name, set the width to 12
$worksheet-&gt;setColumn(1, 1, 15); // Email, set the width to 15


/**
 * 
 * Once we have the format ready, add the text to the spreadsheet
 * 
 */
// Write a text header
$worksheet-&gt;write(1, 1, &#039;Users report&#039;, $formatHeader);


// Create the header for the data starting @ row 4
$indexCol = 0;
$indexRow = 4;
$worksheet-&gt;write($indexRow, $indexCol++, &#039;User Id&#039;, $formatReportHeader);
$worksheet-&gt;write($indexRow, $indexCol++, &#039;Name&#039;, $formatReportHeader);
$worksheet-&gt;write($indexRow, $indexCol++, &#039;Email&#039;, $formatReportHeader);


$indexRow++;   // Advance to the next row
$indexCol = 0; // Start @ column 0

// Print the report data
if(count($this-&gt;users) == 0) {
    // No data
    $worksheet-&gt;write(
        $indexRow,
        $indexCol, 
        &#039;No data to display&#039;,
        $formatData);

} else {
    // Write the data
    foreach ($this-&gt;users as $userId =&gt; $user) {
        $worksheet-&gt;writeNumber(
            $indexRow,
            $indexCol++,
            $userId,
            $formatData);

        $worksheet-&gt;write(
            $indexRow, 
            $indexCol++, 
            $user[&#039;name&#039;], 
            $formatData);

        $worksheet-&gt;write(
            $indexRow, 
            $indexCol++, 
            $user[&#039;email&#039;], 
            $formatData);

        // Advance to the next row
        $indexRow++;
    }
}


/**
 *
 * Response with the excel file
 *
 */

// Sends HTTP headers for the Excel file.
$workbook-&gt;send(&#039;report.xls&#039;);

// Calls finalization methods.
// This method should always be the last one to be called on every workbook
$workbook-&gt;close();
</pre>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/eykAumd-Ldg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/08/export-excel-spreadsheets-using-zend-framework/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/08/export-excel-spreadsheets-using-zend-framework/</feedburner:origLink></item>
		<item>
		<title>Proxima reunión</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/qnOtYIsjvRs/</link>
		<comments>http://www.pabloviquez.com/2009/08/proxima-reunin/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 22:54:44 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[costa rica php]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[costa rica]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/2009/08/proxima-reunin/</guid>
		<description><![CDATA[Ya se anunció la próxima reunión del grupo de PHP. (Ver anuncio) Esta es la información del evento: Donde: Auditorio Universidad Latina de Costa Rica Cuando: Martes 11 de Agosto, 7:00pm El tema de Unit Testing e Integración Continua la verdad está muy bueno, recomendado.]]></description>
			<content:encoded><![CDATA[<p>Ya se anunció la próxima reunión del grupo de PHP. (<a title="Comunidad PHP" href="http://www.costaricaphp.org/archives/68" target="_blank">Ver anuncio</a>)</p>
<p>Esta es la información del evento:</p>
<p><strong>Donde: </strong>Auditorio Universidad Latina de Costa Rica</p>
<p><strong>Cuando:</strong> Martes 11 de Agosto, 7:00pm</p>
<p><img title="reunion_2009-08-11" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="397" alt="reunion_2009-08-11" src="http://www.pabloviquez.com/wp-content/uploads/2009/08/reunion_20090811.gif" width="576" border="0" /></p>
<p>El tema de Unit Testing e Integración Continua la verdad está muy bueno, recomendado.</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/qnOtYIsjvRs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/08/proxima-reunin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/08/proxima-reunin/</feedburner:origLink></item>
		<item>
		<title>How to use json_encode with ISO-8859-1 data – Part2</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/62XC2kUGkUE/</link>
		<comments>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%e2%80%93-part2/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 18:04:22 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[iso 8859-1]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[utf-8]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[json_encode]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=200</guid>
		<description><![CDATA[To continue with the previous post. Problem: Function json_encode does not support ISO-8859-1 encoded data. One solution that I did, in order to preserve the character set was to encode the data before using the json_encode function to use just A-Z, a-z and 0-9 characters, instead of sending text with accents or symbols. One encoding [...]]]></description>
			<content:encoded><![CDATA[<p>To continue with <a title="JSON, ISO 8859-1 and UTF-8 – Part1" href="http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-part1/">the previous post</a>.</p>
<p><strong>Problem:</strong> Function json_encode does not support ISO-8859-1 encoded data.</p>
<p>One solution that I did, in order to preserve the character set was to encode the<br />
data before using the json_encode function to use just A-Z, a-z and 0-9 characters,<br />
instead of sending text with accents or symbols.</p>
<p>One encoding that fits perfectly in this schema, is Base64 Content-Transfer-Encoding. (see base 64 explanation below)</p>
<p>This leads me to the solution: Encode the ISO-8859-1 using base64 and decoded in the client using JavaScript.</p>
<p>Now, this lead me to another issue, what&#8217;s the algorithim to implement the base64_decode function in JavaScript?</p>
<p>Luckly enough, I was looking at the site: http://phpjs.org/ which ported most of the PHP functions to JavaScript and problem solved!</p>
<p><a href="http://www.pabloviquez.com/demo_files/Encoding-JSON.zip">Download the demo files here</a></p>
<h2>Solution</h2>
<p>So my solution will look like this (using the demo files from my previous post):</p>
<p><b>prueba_ansi.php</b></p>
<pre class="brush: php">
&lt;?php
$id =
    base64_encode(
        utf8_encode(&#039;iso-8859-1&#039;));
$name =
    base64_encode(
        utf8_encode(&#039;Pablo Víquez - This is an ISO-8859-1 encoded text&#039;));
$notes =
    base64_encode(
        utf8_encode(&#039;Test with JSON encoding. á é í ó ú, ñ, Ñ.&#039;));

$customer =
    array(
        &#039;id&#039;    =&gt; $id,
        &#039;name&#039;  =&gt; $name,
        &#039;notes&#039; =&gt; $notes
);

echo json_encode($customer);
</pre>
<p>As you can see, I used 2 functions to encode the data: base64_encode and utf8_encode.</p>
<p>I used these 2, mostly because the JavaScript implementation of base64_decode asumes<br />
that the data is UTF-8 encoded, by doing </i>base64_encode(utf8_encode(&#8216;iso-8859-1&#8242;))</i><br />
I&#8217;m acctually first encoding the data to be UTF-8 first and then encoding it using Base64.</p>
<p><b>base64_encode</b><br />
Encodes data with MIME base64, and has the following description:</p>
<pre class="brush: php">string base64_encode ( string $data )</pre>
<p><b>utf8_encode</b><br />
Encodes an ISO-8859-1 string to UTF-8, and has the following description:</p>
<pre class="brush: php">string utf8_encode  ( string $data  )</pre>
<h2>Client Side</h2>
<p>I used JQuery to retrieve the JSON data, and the phpjs.org implementation for the<br />
base64_decode and utf8_decode functions.</p>
<p><b>index.html</b></p>
<pre class="brush: html">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;title&gt;JSON Consumer&lt;/title&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function(){
    $(&quot;#query_data_iso&quot;).click(
        function(){
            getIsoData();
        }
    );

    $(&quot;#query_data_utf8&quot;).click(
        function(){
            getUtfData();
        }
    );
});

function getUtfData() {
    $.ajax({
        type:       &quot;GET&quot;,
        dataType:   &quot;json&quot;,
        url:        &quot;prueba_utf8.php&quot;,
        success:    function(response){
            $(&quot;#customer_data_id&quot;).html(response.id);
            $(&quot;#customer_data_name&quot;).html(response.name);
            $(&quot;#customer_data_notes&quot;).html(response.notes);
        },
    });
}

/**
 * Gets a JSON response from the server.
 * Expectes a base64 encoded response with: id, name and notes all base64 encoded.
 */
function getIsoData() {
    $.ajax({
        type:       &quot;GET&quot;,
        dataType:   &quot;json&quot;,
        url:        &quot;prueba_ansi.php&quot;,
        success:    function(response){
            $(&quot;#customer_data_id&quot;).html(base64_decode(response.id));
            $(&quot;#customer_data_name&quot;).html(base64_decode(response.name));
            $(&quot;#customer_data_notes&quot;).html(base64_decode(response.notes));
        },
    });
}

/**
 * Decodes string using MIME base64 algorithm
 * @see http://phpjs.org/functions/base64_decode
 */
function base64_decode( data ) {
    var b64 = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=&quot;;
    var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, dec = &quot;&quot;, tmp_arr = [];

    if (!data) {
        return data;
    }

    data += &#039;&#039;;

    do {  // unpack four hexets into three octets using index points in b64
        h1 = b64.indexOf(data.charAt(i++));
        h2 = b64.indexOf(data.charAt(i++));
        h3 = b64.indexOf(data.charAt(i++));
        h4 = b64.indexOf(data.charAt(i++));

        bits = h1&lt;&lt;18 | h2&lt;&lt;12 | h3&lt;&lt;6 | h4;

        o1 = bits&gt;&gt;16 &amp; 0xff;
        o2 = bits&gt;&gt;8 &amp; 0xff;
        o3 = bits &amp; 0xff;

        if (h3 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1);
        } else if (h4 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1, o2);
        } else {
            tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
        }
    } while (i &lt; data.length);

    dec = tmp_arr.join(&#039;&#039;);
    dec = this.utf8_decode(dec);
    return dec;
}

/**
 * Converts a UTF-8 encoded string to ISO-8859-1
 * @see http://phpjs.org/functions/utf8_decode
 */
function utf8_decode ( str_data ) {
    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;

    str_data += &#039;&#039;;

    while ( i &lt; str_data.length ) {
        c1 = str_data.charCodeAt(i);
        if (c1 &lt; 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if ((c1 &gt; 191) &amp;&amp; (c1 &lt; 224)) {
            c2 = str_data.charCodeAt(i+1);
            tmp_arr[ac++] = String.fromCharCode(((c1 &amp; 31) &lt;&lt; 6) | (c2 &amp; 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i+1);
            c3 = str_data.charCodeAt(i+2);
            tmp_arr[ac++] = String.fromCharCode(((c1 &amp; 15) &lt;&lt; 12) | ((c2 &amp; 63) &lt;&lt; 6) | (c3 &amp; 63));
            i += 3;
        }
    }

    return tmp_arr.join(&#039;&#039;);
}
&lt;/script&gt;

&lt;/head&gt;

&lt;body&gt;
    &lt;h1&gt;ISO 8859-1, JSON consumer&lt;/h1&gt;

    &lt;p&gt;
        &lt;a href=&quot;#&quot; id=&quot;query_data_iso&quot;&gt;Query for ISO-8859-1 data&lt;/a&gt; |
        &lt;a href=&quot;#&quot; id=&quot;query_data_utf8&quot;&gt;Query for UTF-8&lt;/a&gt;
    &lt;/p&gt;
    &lt;table border=&quot;1&quot;&gt;
        &lt;tr&gt;
            &lt;td&gt;Id&lt;/td&gt;
            &lt;td&gt;Name&lt;/td&gt;
            &lt;td&gt;Notes&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;div id=&quot;customer_data_id&quot;&gt;&lt;/div&gt;&lt;/td&gt;
            &lt;td&gt;&lt;div id=&quot;customer_data_name&quot;&gt;&lt;/div&gt;&lt;/td&gt;
            &lt;td&gt;&lt;div id=&quot;customer_data_notes&quot;&gt;&lt;/div&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>Downsize</h2>
<p>The downsize to this solution will be the size of the encoded transfer, this because Base64-encoded data takes about 33% more space than the original data.</p>
<h2>References</h2>
<h3>Base64 Content-Transfer-Encoding</h3>
<p>http://tools.ietf.org/html/rfc2045</p>
<p>Normally, many media types which could be usefully transported via email are<br />
represented, in their &#8220;natural&#8221; format, as 8bit character or binary data.<br />
Such data cannot be transmitted over some transfer protocols.</p>
<p>For example, email. The SMTP (simple mail transfer protocol) restricts mail<br />
messages to 7bit US-ASCII data with lines no longer than 1000 characters<br />
including any trailing CRLF line separator.</p>
<h3>PHP JS</h3>
<ul>
<li><b>base64_decode</b> &#8211; http://phpjs.org/functions/base64_decode</li>
<li><b>utf8_decode</b> &#8211; http://phpjs.org/functions/utf8_decode</li>
</ul>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/62XC2kUGkUE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%e2%80%93-part2/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%e2%80%93-part2/</feedburner:origLink></item>
		<item>
		<title>How to use json_encode with ISO-8859-1 data – Part1</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/qBHhe2qKfpE/</link>
		<comments>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-part1/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 19:51:34 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[debug]]></category>
		<category><![CDATA[iso 8859-1]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[utf-8]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[json_encode]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=190</guid>
		<description><![CDATA[Download the demo files While I was looking at some AJAX calls, I started to have a problem, for some reason, when I tried to query a JSON service I did using JQuery, the result was null for some fields. Going a little deeper, I notice that the records from the DB were OK, and [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Demo Files" href="http://www.pabloviquez.com/demo_files/Encoding-JSON.zip">Download the demo files</a></p>
<p>While I was looking at some AJAX calls, I started to have a problem, for some reason, when I tried to query a JSON service I did using JQuery, the result was null for some fields.</p>
<p>Going a little deeper, I notice that the records from the DB were OK, and the JavaScript was OK to, so what was the problem? <strong>The JSON Encode!</strong></p>
<p>So take for instance this code:</p>
<pre class="brush: php">
$customer =
    array(
        &#039;id&#039;    =&gt; 1,
        &#039;name&#039;  =&gt; &#039;Pablo Víquez&#039;,
        &#039;notes&#039; =&gt; &#039;Pruebas de encoding con JSON. á é í ó ú, ñ, Ñ&#039;
);

echo json_encode();
</pre>
<p>If I save it as a ISO-8859-1, the result is the following:</p>
<pre class="brush: php">
{&quot;id&quot;:1,&quot;name&quot;:null,&quot;notes&quot;:null}
</pre>
<p>Now, using the same code, but saving the PHP file as UTF-8 I got this result:</p>
<pre class="brush: php">
{&quot;id&quot;:1,&quot;name&quot;:&quot;Pablo V\u00edquez&quot;,&quot;notes&quot;:&quot;Pruebas de encoding con JSON. \u00e1 \u00e9 \u00ed \u00f3 \u00fa, \u00f1, \u00d1&quot;}
</pre>
<p>The problem that I had was that the site was built using ISO 8859-1 not UTF-8, and changing it to UTF-8 is not an option, andn the AJAX call must return a JSON response.</p>
<h3>json_encode documentation</h3>
<p>string json_encode ( mixed $value  [, int $options= 0  ] )</p>
<ul>
<li>$value: The value being encoded. Can be any type except a resource.<br />
<span style="text-decoration: underline;"><strong>This function only works with UTF-8 encoded data.</strong></span></li>
<li>$options (PHP 5.3 ONLY): Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_FORCE_OBJECT. Defaults to 0.</li>
</ul>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/qBHhe2qKfpE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-part1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-part1/</feedburner:origLink></item>
		<item>
		<title>PHP 5.3 with improved Type Hinting and type casting</title>
		<link>http://feedproxy.google.com/~r/PabloViquezBlog/~3/qeNrZFecqLI/</link>
		<comments>http://www.pabloviquez.com/2009/07/php-5-3-with-improved-type-hinting-and-type-casting/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 15:58:46 +0000</pubDate>
		<dc:creator>Pablo Viquez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[php 5.3]]></category>
		<category><![CDATA[type hinting]]></category>

		<guid isPermaLink="false">http://www.pabloviquez.com/?p=176</guid>
		<description><![CDATA[From Illia Alshanetsky blog post: There has been a lot of comments both on this blog and the internals list. There seems to be a fairly large group of core developers who like the idea as well as surpassingly large support base on the user level too (wow, didn&#8217;t think that this many people want [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Ilia Alshanetsky Blog" href="http://ilia.ws/archives/206-Type-hinting-rehashed-now-with-type-casting-support.html" target="_blank">From Illia Alshanetsky blog post:</a></p>
<blockquote><p>There has been a lot of comments both on this blog and the internals list. There seems to be a fairly large group of core developers who like the idea as well as surpassingly large support base on the user level too (wow, didn&#8217;t think that this many people want type hinting). Unfortunately, there have also been, as is typically on the internals list a few people complaining for the sake of complaining. Their arguments have ranged from type hinting is against PHP&#8217;s loosely typed nature and people will mis-use it and make PHP into something that it is not, to I don&#8217;t need or will use it, so no one should get it.</p>
<p>…Here is the quick changelog.</p>
<ol>
<li>Added support for &#8220;object&#8221; type hint</li>
<li>Modified the patch not to break binary compatibility so you can now use patched PHP without having to re-compile your extensions or having issues with binary ones.</li>
<li>Added full reflection support, which I appropriated from Felipe&#8217;s earlier work on type hinting</li>
<li>Added support for type casting, where by you can do things like this function a((int)$foo), which will force PHP to cast the value of $foo to an integer</li>
<li>Added tests, which again I partially appropriated from Felipe&#8217;s earlier work.</li>
</ol>
</blockquote>
<p>The types that could be used (according to the proposed patch) are:</p>
<table border="0">
<tr>
<td align="center"><b>Boolean</b></td>
<td align="center"><b>String</b></td>
<td align="center"><b>Integers</b></td>
<td align="center"><b>Floats</b></td>
<td align="center"><b>Others</b></td>
</tr>
<tr>
<td valign="top">
<ul>
<li>bool</li>
<li>boolean</li>
</ul>
</td>
<td valign="top">
<ul>
<li>string</li>
<li>binary</li>
<li>unicode</li>
</ul>
</td>
<td valign="top">
<ul>
<li>int</li>
<li>integer</li>
<li>long</li>
</ul>
</td>
<td valign="top">
<ul>
<li>real</li>
<li>double</li>
<li>float</li>
</ul>
</td>
<td valign="top">
<ul>
<li>resource</li>
<li>numeric</li>
<li>scalar</li>
<li>object</li>
</ul>
</td>
</tr>
</table>
<p>So, how do that will look like? Here some examples of how this will look like:</p>
<h2>Type Casting on function definition:</h2>
<pre class="brush: php">
function printMe((int) $value) {
    var_dump($value);
}

// Output:
// int(50)
printMe(50);

// Output:
// int(123)
printMe(&#039;123&#039;);

// Output:
// int(0)
printMe(&#039;Testing&#039;);

// Output:
// int(0)
printMe(null);
</pre>
<h3>Or using String as type casting</h3>
<pre class="brush: php">
function printMeAgain((string) $value) {
    var_dump($value);
}

// Output:
// string(2) &quot;50&quot;
printMeAgain(50);

// Output:
// string(3) &quot;123&quot;
printMeAgain(&#039;123&#039;);

// Output:
// string(7) &quot;Testing&quot;
printMeAgain(&#039;Testing&#039;);

// Output:
// string(0) &quot;&quot;
printMeAgain(null);

</pre>
<h2>Type Hinting</h2>
<pre class="brush: php">
function test_int(int $a = 1) {
    var_dump($a);
}

// Output:
// int(1)
test_int();

// Output:
// int(123)
test_int(123);

// Output:
// Catchable fatal error: Argument 2 passed to test_int()
// must be of the type integer, string given
test_int(&quot;123&quot;);
</pre>
<h3>With doubles:</h3>
<pre class="brush: php">
function test_double(real $a) {
    var_dump($a);
}

// Output:
// float(1)
test_double(1);

// Output:
// float(1.123)
test_double(1.123);

// Output:
// Catchable fatal error: Argument 1 passed to
// test_double() must be of the type double,
// string given.
test_double(&quot;123&quot;);
</pre>
<h3>With Strings:</h3>
<pre class="brush: php">
function test_string(string $a) {
    var_dump($a);
}

// Output:
// string(10) &quot;Hola Mundo&quot;
test_double(&quot;Hola Mundo&quot;);

// Output:
// Catchable fatal error: Argument 1 passed to
// test_string() must be of the type string,
// int given
test_double(123);


// Output:
// Catchable fatal error: Argument 1 passed to
// test_string() must be of the type string,
// null given
test_str(null);
</pre>
<img src="http://feeds.feedburner.com/~r/PabloViquezBlog/~4/qeNrZFecqLI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pabloviquez.com/2009/07/php-5-3-with-improved-type-hinting-and-type-casting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.pabloviquez.com/2009/07/php-5-3-with-improved-type-hinting-and-type-casting/</feedburner:origLink></item>
	</channel>
</rss>
