<?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>Thibauld &#187; technical</title>
	<atom:link href="http://thibauld.com/category/technical/feed/" rel="self" type="application/rss+xml" />
	<link>http://thibauld.com</link>
	<description>- Imagination and Execution -</description>
	<lastBuildDate>Sat, 02 Oct 2010 01:14:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Get a command prompt with administrator privileges from explorer</title>
		<link>http://thibauld.com/2010/10/get-a-command-prompt-with-administrator-privileges-from-explorer/</link>
		<comments>http://thibauld.com/2010/10/get-a-command-prompt-with-administrator-privileges-from-explorer/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 01:14:33 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[administrator]]></category>
		<category><![CDATA[command prompt]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=305</guid>
		<description><![CDATA[While I was looking to install Dig on my Windows 7 machine. I stumbled on a dead simple but very useful piece of code that I thought I would share with you. It just allows you to open a command prompt as an administrator on any folder by doing a right mouse click on this [...]]]></description>
			<content:encoded><![CDATA[<p>While I was looking to <a href="http://members.shaw.ca/nicholas.fong/dig/" target="_blank">install Dig on my Windows 7 machine</a>. I stumbled on a dead simple but very useful piece of code that I thought I would share with you. It just allows you to open a command prompt as an administrator on any folder by doing a right mouse click on this folder.</p>
<ol>
<li>Download <a target="_blank" href="http://members.shaw.ca/nicholas.fong/dig/CmdHereAsAdmin.inf">CmdHereAsAdmin.inf</a></li>
<li>Right click on the file and choose "Install"</li>
<li>You're all set!</li>
</ol>
<p> You can now right click on any folder an launch an CMD prompt with administrator privileges directly from the explorer. Quick &#038; easy!</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2010/10/get-a-command-prompt-with-administrator-privileges-from-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>postgresql, date input format and black magic</title>
		<link>http://thibauld.com/2010/09/postgresql-date-input-format-and-black-magic/</link>
		<comments>http://thibauld.com/2010/09/postgresql-date-input-format-and-black-magic/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 22:00:55 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[bug]]></category>
		<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=298</guid>
		<description><![CDATA[I hate when I have the impression that black magic took the control of my PC. If you're a developer, you know it happens sometimes... when something is obviously wrong but you just can't figure out *what* is wrong. Hopefully, we work in IT, a field where we can reasonably assume that *everything* happens for [...]]]></description>
			<content:encoded><![CDATA[<p>I hate when I have the impression that black magic took the control of my PC. If you're a developer, you know it happens sometimes... when something is obviously wrong but you just can't figure out *what* is wrong. Hopefully, we work in IT, a field where we can reasonably assume that *everything* happens for a reason. So after digging a while, you eventually end up finding where the issue comes from.</p>
<p>It happened this week while trying to figure out why Postgresql had a different behavior on apparently completely similar platforms. I'm born April 1st, let's say I want to save my birthday in a table, I'd go with the following SQL statement :<br />
<code>INSERT INTO birthdays (date) VALUES ('01-04-1981');</code></p>
<p>As I'm french, each time I deal with dates, I tend to verify that they were understood correctly. Indeed, the above date format was french ('dd-mm-YYYY') but postgresql could have interpreted as a US date format ('mm-dd-YYY'). So let's check with the following statement:<br />
<code>SELECT date_part('month',date) FROM  birthdays;</code></p>
<p>Here comes the problem. On 2 different machines with (apparently) the same setup, this statement would return 2 different results. One would return '04' (correct) and the other one would return '01' (wrong).</p>
<p>I took me a while to find out that postgresql had <a href="http://www.postgresql.org/docs/8.2/static/runtime-config-client.html#GUC-DATESTYLE">datestyle</a> option (in postgresql.conf) which defines the rule to interpret ambiguous date input values. </p>
<p>So if datestyle is set to 'iso, dmy', it means dates will be interpreted as 'date-month-year' and if it is set to 'iso-mdy', dates will be interpreted as 'month-date-year'. It is that simple... once you found it <img src='http://thibauld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2010/09/postgresql-date-input-format-and-black-magic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to validate email addresses in PHP</title>
		<link>http://thibauld.com/2010/08/how-to-validate-email-addresses-in-php/</link>
		<comments>http://thibauld.com/2010/08/how-to-validate-email-addresses-in-php/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 22:25:18 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=293</guid>
		<description><![CDATA[I guess that every PHP developer out there already had to cope with email validation in PHP. I personally used to think it was not completely straight forward. 
Indeed, when you google the subject you quickly find this article with a completely misguiding title: "Validate an Email Address with PHP, the Right Way". Do not [...]]]></description>
			<content:encoded><![CDATA[<p>I guess that every PHP developer out there already had to cope with email validation in PHP. I personally used to think it was not completely straight forward. </p>
<p>Indeed, when you google the subject you quickly find <a href="http://www.linuxjournal.com/article/9585">this article</a> with a completely misguiding title: "Validate an Email Address with PHP, the Right Way". Do not use the regexp proposed in this article outdated article. Not only because <a href="http://www.php.net/manual/en/function.ereg.php">ereg()</a> has been deprecated and replaced by <a href="http://www.php.net/manual/en/function.preg-match.php">preg_match()</a> in latest PHP version (5.3 actually), but also because there is much simpler since PHP 5.2. </p>
<p>Check this out:<br />
<code><br />
function is_email_valid($email) {<br />
    return filter_var($email,FILTER_VALIDATE_EMAIL)!==false;<br />
}<br />
</code><br />
Now, that's straight forward, isn't it? Here's <a href="http://fr.php.net/filter_var">filter_var() documentation</a> if you want to find out more.</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2010/08/how-to-validate-email-addresses-in-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to exclude multiple directories while creating an archive with tar</title>
		<link>http://thibauld.com/2010/02/how-to-exclude-multiple-directories-while-creating-an-archive-with-tar/</link>
		<comments>http://thibauld.com/2010/02/how-to-exclude-multiple-directories-while-creating-an-archive-with-tar/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 14:49:55 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[archive]]></category>
		<category><![CDATA[exclude]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=285</guid>
		<description><![CDATA[A very quick post again as I've just spent way too much time to find out how to use the --exclude option of tar. All I wanted is tar to omit a few subdirectories while creating an archive of a directory. I was surprised to see how much tar is picky about his --exclude option: [...]]]></description>
			<content:encoded><![CDATA[<p>A very quick post again as I've just spent way too much time to find out how to use the <code>--exclude</code> option of <em>tar</em>. All I wanted is <em>tar</em> to omit a few subdirectories while creating an archive of a directory. I was surprised to see how much <em>tar</em> is picky about his <code>--exclude</code> option: if you don't use the exact syntax, it won't work and, unfortunately, the exact syntax is not so easy to figure out from the man page.</p>
<p>So here is the exact syntax you should use if you want to exclude multiples directories with tar:</p>
<p><code>tar cvfz myproject.tgz --exclude='path/dir_to_exclude1' --exclude='path/dir_to_exclude2' myproject</code></p>
<p>Hope it will save you some time!</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2010/02/how-to-exclude-multiple-directories-while-creating-an-archive-with-tar/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Configuring iptables to allow internet surfing while blocking all unsolicited incoming connexions</title>
		<link>http://thibauld.com/2010/02/configuring-iptables-to-allow-internet-surfing-while-blocking-all-unsollicited-incoming-connexions/</link>
		<comments>http://thibauld.com/2010/02/configuring-iptables-to-allow-internet-surfing-while-blocking-all-unsollicited-incoming-connexions/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 00:57:42 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=273</guid>
		<description><![CDATA[I'm so used to connect to the Internet through network masquerading (NAT) that I was really surprised today when I realised that my laptop was actually receiving a lot of unsollicited connexions attempts from random external machines. Then I remembered that, by default, a freebox gives you a public ip ! 
It could not have [...]]]></description>
			<content:encoded><![CDATA[<p>I'm so used to connect to the Internet through network masquerading (NAT) that I was really surprised today when I realised that my laptop was actually receiving a lot of unsollicited connexions attempts from random external machines. Then I remembered that, by default, a freebox gives you a public ip ! </p>
<p>It could not have been an issue if I was not doing web development on my laptop using a local (badly configured) webserver which happened to be worldwide accessible... oOops <img src='http://thibauld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A few iptables commands later, everything was secured :<br />
<code><br />
iptables -P INPUT DROP<br />
iptables -P FORWARD DROP<br />
iptables -P OUTPUT ACCEPT<br />
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT<br />
iptables -A INPUT -s 127.0.0.1 -j ACCEPT<br />
</code><br />
The above lines configure iptables (the firewall) to drop every incoming connexions except the ones corresponding to a connexion I established with a remote server. Indeed, the server you're connecting to needs to be able to send information back to your machine in order for you to get it (blocking all incoming traffic is the same as unplugging the network connection).</p>
<p>I thought it might be useful to some of you too...</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2010/02/configuring-iptables-to-allow-internet-surfing-while-blocking-all-unsollicited-incoming-connexions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google real time search results</title>
		<link>http://thibauld.com/2009/12/google-real-time-search-results/</link>
		<comments>http://thibauld.com/2009/12/google-real-time-search-results/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 22:10:15 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[realtime search]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=267</guid>
		<description><![CDATA[I've just noticed beautiful live search results integrated into google search results tonight. I had never seen them before so I thought I'd share this news-to-me with you   Here's what I saw when I looked for "2010 resolutions" :

And then, a few seconds later, without refreshing anything on my side :

I love it [...]]]></description>
			<content:encoded><![CDATA[<p>I've just noticed beautiful live search results integrated into google search results tonight. I had never seen them before so I thought I'd share this <i>news-to-me</i> with you <img src='http://thibauld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Here's what I saw when I looked for "2010 resolutions" :<br/><br />
<a href="http://www.flickr.com/photos/thibs/4232312462/" title="google_live_search_results by thibauld, on Flickr"><img src="http://farm5.static.flickr.com/4042/4232312462_b517bdeff2.jpg" width="500" height="301" alt="google_live_search_results" /></a></p>
<p>And then, a few seconds later, without refreshing anything on my side :</p>
<p><a href="http://www.flickr.com/photos/thibs/4232312502/" title="google_live_search_results1 by thibauld, on Flickr"><img src="http://farm3.static.flickr.com/2615/4232312502_82c7f50431.jpg" width="500" height="313" alt="google_live_search_results1" /></a></p>
<p>I love it <img src='http://thibauld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Now let's go party for 2010!<br />
Happy new year everybody!</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2009/12/google-real-time-search-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP function to draw nice looking XY plot charts with google chart API</title>
		<link>http://thibauld.com/2009/07/php-function-to-draw-nice-looking-xy-plot-charts-with-google-chart-api/</link>
		<comments>http://thibauld.com/2009/07/php-function-to-draw-nice-looking-xy-plot-charts-with-google-chart-api/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 00:30:36 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[google chart api]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[xy plot]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=225</guid>
		<description><![CDATA[Creating nice charts used to be a hard task. Lately, I dug a little bit into Google chart API to see what they had to offer and how they could help me draw nice looking charts easily.
In theory, using Google chart is dead simple: just build an URL with the right parameters and Google will [...]]]></description>
			<content:encoded><![CDATA[<p>Creating nice charts used to be a hard task. Lately, I dug a little bit into Google <a href="http://code.google.com/intl/fr/apis/chart/" target="_blank">chart API</a> to see what they had to offer and how they could help me draw nice looking charts easily.</p>
<p>In theory, using Google chart is dead simple: just build an URL with the right parameters and Google will return you an image with your nice looking chart. However, in practice, it turned out a little bit more tricky. If you only want to draw a pie charts then it is pretty straight forward. But if you want to build an XY plot chart, then it gets harder!</p>
<p>Indeed, you should not use Google chart API like you'd use a spreadsheet. Keep in mind that Google chart API is about drawing an image: the X axis and the Y axis are treated completely independantly of your points coordinates.  If you do not pay enough attention, you'll end up with a chart with a completely wrong scale.</p>
<p>I tried to find some PHP libraries to help me draw my XY chart but found nothing satisfactory, so I finally decided to write my own little PHP function. Let me share it with you:<br />
<code><br />
function getChart($chart) {<br />
    $y_max = $chart['y_max'];<br />
    $y_min = $chart['y_min'];<br />
    $y_step = $chart['y_step'];<br />
    $y_grid_step = $chart['y_grid_step'];<br />
    $x_max = $chart['x_max'];<br />
    $x_min = $chart['x_min'];<br />
    $chart_size = $chart['chart_size'];<br />
    $title = $chart['title'];<br />
    $x = $chart['x_axis'];<br />
    $x_nb = count($x);<br />
    $x_int = 100/$x_nb;<br />
    $first = 0;<br />
    if ($chart['x_labels_centered']) $first = $x_int/2;<br />
    for($i=0;$i<=$x_nb-1;$i++) { $positions[] = floor($first + ($i * $x_int));  }<br />
    foreach($positions as $n => $pos) { $x_values[$pos] = $x[$n]; }<br />
    $x_range = implode(',',array_keys($x_values));<br />
    $x_labels = implode('|',$x);<br />
    $grid_step = $y_grid_step*100/$y_max;<br />
    $url = "http://chart.apis.google.com/chart?";<br />
    $cht = "cht=lc";<br />
    if (!empty($chart['data_y'])) $cht="cht=lxy";<br />
    $chd = "chd=t:".implode(',',$chart['data']);<br />
    if (!empty($chart['data_y'])) $chd.="|".implode(',',$chart['data_y']);<br />
    $chg = "chg=$x_int,$grid_step,1,5";<br />
    $chxt = "chxt=x,y";<br />
    $tmp = array();<br />
    for ($i=0;$i<=$y_max;$i+=$y_step) { $tmp[] = $i; }<br />
    $y_labels = implode(',',$tmp);<br />
    $chxp = "chxp=0,".$x_range."|1,".$y_labels;<br />
    $y_labels = implode('|',$tmp);<br />
    $chxl = "chxl=0:|".$x_labels."|1:|".$y_labels;<br />
    $chxr = "chxr=1,$y_min,$y_max,$y_step";<br />
    $chtt="chtt=".str_replace(' ','+',$title);<br />
    $chs = "chs=".$chart_size;<br />
    $chds = "chds=$y_min,$y_max";<br />
    $chm="chco=0000FFFF&#038;chm=B,76A4FB,0,0,0";#|s,0000FF,0,-1,10";<br />
    if (!empty($chart['data_y'])) $chds ="chds=$x_min,$x_max,$y_min,$y_max";<br />
    $url .= implode('&#038;', array($cht,$chd,$chg,$chm,$chxt,$chxl,$chxp,$chxr,$chtt,$chs,$chds));<br />
    return $url;<br />
}<br />
</code></p>
<p>Dont' get me wrong: this is really a quick and dirty function and not meant to be beautiful code. Here is an invokation example:<br />
<code><br />
$data_x = array(0,4,5,9,10);<br />
$data_y = array(20,5,7,9,10);<br />
$months_x = array('Jan','Fev','Mar','Avr','May');<br />
$chart_xy = array(<br />
    'title'=>"Chart Title",    // CHART TITLE<br />
    'data'=>$data_x,           // CHART DATA (X)<br />
    'data_y'=>$data_y,         // CHART DATA (Y)<br />
    'x_axis'=>$months_x,       // X AXIS LABELS LIST<br />
    'x_labels_centered'=>true, // SHOULD LABELS ON X AXIS BE CENTERED?<br />
    'y_min'=>0,                // MIN VALUE OF Y AXIS<br />
    'y_max'=>25,               // MAX VALUE OF Y AXIS<br />
    'y_step'=>5,               // Y AXIS INTERVAL (NUMBERS ON THE AXIS)<br />
    'y_grid_step'=>5,          // Y AXIS GRID INTERVAL (HORIZONTAL LINES ON THE GRID)<br />
    'x_min'=>0,                // MIN VALUE OF X AXIS<br />
    'x_max'=>10,               // MAX VALUE OF X AXIS<br />
    'chart_size'=>'300x300'    // CHART DIMENSIONS<br />
);<br />
$url = getChart($chart_xy);<br />
</code><br />
This code would result in the following graph:</p>
<p style="text-align:center;"><img src="http://chart.apis.google.com/chart?cht=lxy&#038;chd=t:0,4,5,9,10|20,5,7,9,10&#038;chg=20,20,1,5&#038;chco=0000FFFF&#038;chm=B,76A4FB,0,0,0&#038;chxt=x,y&#038;chxl=0:|Jan|Fev|Mar|Avr|May|1:|0|5|10|15|20|25&#038;chxp=0,10,30,50,70,90|1,0,5,10,15,20,25&#038;chxr=1,0,25,5&#038;chtt=Chart+Title&#038;chs=300x300&#038;chds=0,10,0,25"></p>
<p>And if I change :<br />
<code><br />
$months_x = array('Jan','Fev','Mar','Avr','May');<br />
</code><br />
by<br />
<code><br />
$months_x = array('Jan','Fev','Mar');<br />
</code><br />
I get the following graph:</p>
<p style="text-align:center;"><img src="http://chart.apis.google.com/chart?cht=lxy&#038;chd=t:0,4,5,9,10|20,5,7,9,10&#038;chg=33.3333333333,20,1,5&#038;chco=0000FFFF&#038;chm=B,76A4FB,0,0,0&#038;chxt=x,y&#038;chxl=0:|Jan|Fev|Mar|1:|0|5|10|15|20|25&#038;chxp=0,16,50,83|1,0,5,10,15,20,25&#038;chxr=1,0,25,5&#038;chtt=Chart+Title&#038;chs=300x300&#038;chds=0,10,0,25"></p>
<p>What is important to note here is that it is up to you to make your X and Y axis consistent with your data, ortherwise, you'll end up with a totally meaningless chart. </p>
<p>Of course, this code is adapted to my needs so please feel free to copy this PHP function and adapt it so that it fits your particular needs!</p>
<p>Hope it will be useful for some of you...</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2009/07/php-function-to-draw-nice-looking-xy-plot-charts-with-google-chart-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web application implementation: a bad example</title>
		<link>http://thibauld.com/2009/04/web-application-implementation-a-bad-example/</link>
		<comments>http://thibauld.com/2009/04/web-application-implementation-a-bad-example/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 15:35:25 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=166</guid>
		<description><![CDATA[I recently went to a website which is a perfect example of what *not* to do if you want your web app to feel fast and responsive from a user perspective, especially when it is the first this user comes to your site! Indeed, the first time you go to a website, your web browser [...]]]></description>
			<content:encoded><![CDATA[<p>I recently went to a website which is a perfect example of what *<strong>not</strong>* to do if you want your web app to feel fast and responsive from a user perspective, especially when it is the first this user comes to your site! Indeed, the first time you go to a website, your web browser will have to download everything: html code, css stylesheets, javascript files, images... and it takes time so you'd better limit the number of files to download if you want the user first experience with your web app to be user friendly.</p>
<p>This is clearly not what <a title="moblin solution zone" href="http://moblinsolutionzone.com" target="_blank">moblin solution zone</a> is doing! When you first go to moblin solution zone, you have to wait 25 seconds (!!) before anything displays on your web browser... and what is funny is that there is finally not much to see <img src='http://thibauld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>If you fire up your brave little <a title="Firebug firefox extension" href="http://allmyapps.com/app/firebug-firebug-extension-for-firefox" target="_blank">firebug</a> and take a look at what is happening behind the scene, you quickly realize that your web browser has to make 40 (fourty) requests before displaying the full page!</p>
<p style="text-align: center;"><a href="http://thibauld.com/wp-content/uploads/2009/04/moblin_example.png"><img class="aligncenter size-full wp-image-167" title="file requested to display the page" src="http://thibauld.com/wp-content/uploads/2009/04/moblin_example.png" alt="file requested to display the page" width="518" height="306" /></a></p>
<p>Even though each request is relatively small, at the end you wait 25 seconds only to see this:</p>
<p style="text-align: center;"><a href="http://thibauld.com/wp-content/uploads/2009/04/moblin_sz.png"><img class="aligncenter size-full wp-image-171" title="moblin solution zone" src="http://thibauld.com/wp-content/uploads/2009/04/moblin_sz.png" alt="moblin solution zone" width="453" height="261" /></a></p>
<p>In conclusion, if you want your users to have a good experience when they first visit your website, you'd better minimize the number of requests needed by grouping js files, css files and using CSS sprites. CSS sprites are a technique which consists in grouping all images like icons into 1 unique image and then use css to only display the image needed. This is really important for the user first visit to your web app since when he comes back, his web browser will have cached a lot of the needed static files which will vastly improve the response time! Provided you set your apache default_expire setting correctly of course...</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2009/04/web-application-implementation-a-bad-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to recursively rename directories using a regexp</title>
		<link>http://thibauld.com/2009/02/how-to-recursively-rename-directories-using-a-regexp/</link>
		<comments>http://thibauld.com/2009/02/how-to-recursively-rename-directories-using-a-regexp/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:36:14 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[rename]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=158</guid>
		<description><![CDATA[Just a very quick post because I just figured out a command to recursively rename directories. As it is the kind of useful commands you don't want to loose and as it might be of interest for others, I thought I would share it here. So here is the command:
 find -type d -name '*-test' [...]]]></description>
			<content:encoded><![CDATA[<p>Just a very quick post because I just figured out a command to recursively rename directories. As it is the kind of useful commands you don't want to loose and as it might be of interest for others, I thought I would share it here. So here is the command:<br />
<code> find -type d -name '*-test' | while read A; do OLD=$(basename $A); NEW=$(echo $OLD | sed s/-test//); mv $A $(dirname $A)/$NEW; done;</code></p>
<p>In this example, the command recursively finds all directories named &lt;anything&gt;-test and renames them &lt;anything&gt;  (removing the trailing '-test'). I hope it will be useful for some of you...</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2009/02/how-to-recursively-rename-directories-using-a-regexp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web application implementation step 6: make it fast!</title>
		<link>http://thibauld.com/2009/02/web-application-implementation-step-6-make-it-fast/</link>
		<comments>http://thibauld.com/2009/02/web-application-implementation-step-6-make-it-fast/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 13:21:50 +0000</pubDate>
		<dc:creator>Thibauld</dc:creator>
				<category><![CDATA[en]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[kcachegrind]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://thibauld.com/?p=148</guid>
		<description><![CDATA[To continue in the "how to implement great web apps" series, here the step 6: make it fast! This is a vast subject and I'll not try to be exhaustive, I'd rather make a list of checkpoints with clues on how to improve each point. Making its web app fast is key for user adoption, [...]]]></description>
			<content:encoded><![CDATA[<p>To continue in the "how to implement great web apps" series, here the step 6: make it fast! This is a vast subject and I'll not try to be exhaustive, I'd rather make a list of checkpoints with clues on how to improve each point. Making its web app fast is key for user adoption, as there is nothing more frustating than a slow web application.</p>
<p>Just to be clear, when I say "fast", I mean "fast from the user perspective" because what's really important in the end is how responsive your app will feel from the user perspective. To illustrate this point, let's take the example of a web page that requires 5 secondes to load, it could be acceptable if the web page becomes usable after 1 second (from the user perspective). What would be unacceptable is a page that would require 5 seconds to be finally usable by the end user. Now what should you do to make your app fast?</p>
<p>Slowness can come either from :</p>
<ol>
<li> <em>the backend</em>: the server takes too much time to process the request</li>
<li> <em>the network</em>: transporting the response from the server to the client (the user web browser) takes too much time</li>
<li> <em>the rendering</em>: actually displaying the response received from the server takes too much time</li>
</ol>
<p>Today we'll tackle the backend part:</p>
<p><strong>Profile your application</strong>. It is necessary to measure how fast is your app and where lie the problems if it is too slow. If you're developing on a LAMP stack, there is an awesome tool for that called <a title="awesome tool to profile lamp web applications" href="http://www.xdebug.org/" target="_blank">Xdebug</a>. Once you have <a title="install xdebug for php5" href="http://allmyapps.com/app/php5-xdebug-ubuntu.com" target="_blank">installed xdebug</a>, all you need to do is to enable it in /etc/php5/apache2/conf.d/xdebug.ini, here's my configuration:<br />
<code>zend_extension=/usr/lib/php5/20060613+lfs/xdebug.so<br />
xdebug.profiler_output_dir = "/tmp/"<br />
xdebug.profiler_enable = Off<br />
xdebug.profiler_enable_trigger = 1</code></p>
<p>The output dir must be writable by apache and I encourage you to enable it only via trigger. Now if you want to profile a screen of your web application, just append the argument XDEBUG_PROFILE=1 to the list of arguements. Example:<br />
<code>http://dev.domain.com/a/screen/path?XDEBUG_PROFILE=1</code></p>
<p>Now, when you access the above url, a file gets created in the output dir (here /tmp/). Just open this file with <a title="install kcachegrind profiling data visualizer" href="http://allmyapps.com/app/kcachegrind-ubuntu.com" target="_blank">kcachegrind</a> and you'll be able to visualize exactly what has happened behind the scene to process your request.</p>
<p style="text-align: center;"><a href="http://allmyapps.com/app/kcachegrind-ubuntu.com"><img class="size-medium wp-image-150 aligncenter" title="install kcachegrind" src="http://thibauld.com/wp-content/uploads/2009/02/kcachegrind-300x220.jpg" alt="kcachegrind" width="300" height="220" /></a></p>
<p>It will be easy then to answer the following questions:</p>
<ul>
<li>what is being called? how many times?</li>
<li>how much time does my request take?</li>
<li>is my caching system working as expected?</li>
<li>why is this request so slow?</li>
<li>are my sql requests fast enough?</li>
<li>is the framework I use adding too much overhead?</li>
<li>etc....</li>
</ul>
<p style="text-align: left;">Kcachegrind provides an incredible value to profile your web application. In the next article, we'll stay in this 'make it fast' step and talk about how to make your web app network efficient.</p>
<p style="text-align: left;">Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://thibauld.com/2009/02/web-application-implementation-step-6-make-it-fast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

