<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkIDRnY7eip7ImA9WhRbEU8.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213</id><updated>2012-02-01T19:29:37.802Z</updated><category term="valid HTML" /><category term="bash script" /><category term="git" /><category term="php" /><category term="security" /><category term="Deployment" /><category term="HTML forms" /><category term="server" /><category term="coding standards" /><category term="ssh" /><category term="development profile Firefox add-ons" /><category term="JavaScript" /><category term="coding habits" /><category term="subversion" /><category term="error alert" /><title>smart code</title><subtitle type="html">Stamping out stupidity one line at a time.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://smartcode.simplewind.com/" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/simplewind/smartcode" /><feedburner:info uri="simplewind/smartcode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0QNRX4zeip7ImA9WhdbFUQ.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-3468621373609207825</id><published>2011-10-14T13:27:00.001+01:00</published><updated>2011-10-14T13:29:54.082+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-14T13:29:54.082+01:00</app:edited><title>Null, NaN, Infinity in JSON, CouchDB</title><content type="html">If you're getting null values where you don't expect them in CouchDB docs, note that JSON doesn't allow NaN or Infinity: these are converted into null.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(0/0 + " !== " + JSON.stringify(0/0));&lt;br /&gt;
NaN !== null&lt;br /&gt;
&lt;br /&gt;
console.log(1/0 + " !== " + JSON.stringify(1/0));&lt;br /&gt;
&lt;span class="objectBox objectBox-text " role="presentation"&gt;Infinity !== null&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-3468621373609207825?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BLMUvzqllMTxBz0fxdz68ht9WuE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BLMUvzqllMTxBz0fxdz68ht9WuE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BLMUvzqllMTxBz0fxdz68ht9WuE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BLMUvzqllMTxBz0fxdz68ht9WuE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/WYHWrxU54eI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/3468621373609207825/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2011/10/null-nan-infinity-in-json-couchdb.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/3468621373609207825?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/3468621373609207825?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/WYHWrxU54eI/null-nan-infinity-in-json-couchdb.html" title="Null, NaN, Infinity in JSON, CouchDB" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2011/10/null-nan-infinity-in-json-couchdb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcGQng8eip7ImA9Wx9WFkQ.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-8845516965237630968</id><published>2011-01-15T10:39:00.001Z</published><updated>2011-01-22T10:43:43.672Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-22T10:43:43.672Z</app:edited><title>Monitoring Apache httpd Error Logs</title><content type="html">Monitoring HTTP error logs can often help identify website issues you may not notice otherwise, from broken links to browser incompatibilities. They can also fill up with junk from script kiddie attacks.&lt;br /&gt;
&lt;br /&gt;
I tend to have cron run a simple script every night after the logs have been rotated, and email me the results:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;pre class="brush:bash"&gt;#! /bin/bash
date=`date -d yesterday +%F`
grep -i -v -f ignore_errors error_log.$date
&lt;/pre&gt;&lt;br /&gt;
Where the ignore_errors file is a list of things I really do not care about. For example: &lt;br /&gt;
&lt;br /&gt;
ignore_errors&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;.anti-sec:)$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/3rdparty$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/RAHAT$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/README$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/SSLMySQLAdmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/Tools$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/WS_FTP.ini$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/ZopeAttributionButton$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/_admin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/a$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/access_logs$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/adm$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/admin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/adming$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/administrator$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/apple-touch-icon-precomposed.png$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/application$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/ascils$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/b2b$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/bbs$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/blog$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/build$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/cart$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/catalog$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/config$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/core$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/cpanelsql$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/cpdbadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/crossdomain.xml$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/database$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/db$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/dbadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/default.php$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/ecommerce$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/eshop$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/extlink$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/extlink, &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/fastenv$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/fckeditor$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/genimg.php$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/hello$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/home.php$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/horde$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/horde-3.0.9$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/horde2$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/horde3$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/html$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/iphone$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/jc$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/labels.rdf$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/lamp$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/list$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/lists$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/loader$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/logs$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/m$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mail$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mobi$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mobile$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/myadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mydatabase$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mydb$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/myphp$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mysql$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mysql-admin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mysqladmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mysqladminconfig$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/mysqlmanager$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/negozio$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/os$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/osc$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/oscommance$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/oscommerce$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/p$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pda$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/php-myadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpadm$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phplist$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpma$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpmanager$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpmy$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpmy-admin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phpmya$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phppgadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/phppma$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2005$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2006$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2007$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2008$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2009$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pma2010$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pmaadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pmadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/pmy$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/program$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/proxy$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/public$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/qql$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/rc$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/roundcube$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/scripts$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/shop$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/shopping$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/shops$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sitemap.xml$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sl2$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sql$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sqladmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sqldatabase$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sqlmanager$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/sqlweb$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/store$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/text$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/typo3$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/user$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/web$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/webadmin$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/webdav$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/webdb$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/webmail$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/websql$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/wp-content$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/wp-login.php$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/xampp$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/xmlrpc.php$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/~$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;FCKeditor&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Invalid URI in request GET  HTTP/1.1&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Invalid URI in request GET HTTP/1.1 HTTP/1.1&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;MSOffice&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;RFC2616 section 14.23&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;_vti_bin&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;actionkit&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;apple-touch-icon.png&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;client sent invalid HTTP/0.9 request: HEAD HTTP/1.0&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;noexist_82ef98c2405c8c5e.html&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;php-my-admin&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;phpMyAdmin&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;phpadmin&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;phpmyadmin&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;proxy_test.php' not found or unable to stat$&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;request failed: error reading the headers&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tinymce&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;wp-login.php' not found or unable to stat$&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Feel free to copy this list if you want to use it as described above.&amp;nbsp;It can also be an indication of names&amp;nbsp;&lt;b&gt;not&lt;/b&gt; to call files and folders on your server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-8845516965237630968?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Gkwbq2BIvWipTNc0J7yGQm53ID0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gkwbq2BIvWipTNc0J7yGQm53ID0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Gkwbq2BIvWipTNc0J7yGQm53ID0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gkwbq2BIvWipTNc0J7yGQm53ID0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/xsT27Fru52g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/8845516965237630968/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2011/01/monitoring-apache-httpd-error-logs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8845516965237630968?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8845516965237630968?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/xsT27Fru52g/monitoring-apache-httpd-error-logs.html" title="Monitoring Apache httpd Error Logs" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2011/01/monitoring-apache-httpd-error-logs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAMR3s7fSp7ImA9Wx5TGU4.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-7909313496380508297</id><published>2010-08-04T16:46:00.000+01:00</published><updated>2010-08-04T16:46:26.505+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-04T16:46:26.505+01:00</app:edited><title>DG834G Negative Connection Time</title><content type="html">Checking the status of a Netgear DG834G wireless router today, I saw it had a negative connection time...&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Connection Time: -11230:00:-52&lt;/span&gt;&lt;/blockquote&gt;... which I'm sure is a very long time. But it can't be that long. The guys at Netgear must have either been seriously stingy with the storage allocated to this, or perhaps they never expected one of their routers to stay up for more than a few months!&lt;br /&gt;
&lt;br /&gt;
Disconnect/Connect, and all's back to normal...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-7909313496380508297?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YPRWUdZtlCt6IaOU1tlM_OxjNqw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YPRWUdZtlCt6IaOU1tlM_OxjNqw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YPRWUdZtlCt6IaOU1tlM_OxjNqw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YPRWUdZtlCt6IaOU1tlM_OxjNqw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/gecUtr-Kkcg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/7909313496380508297/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2010/08/dg834g-negative-connection-time.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/7909313496380508297?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/7909313496380508297?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/gecUtr-Kkcg/dg834g-negative-connection-time.html" title="DG834G Negative Connection Time" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2010/08/dg834g-negative-connection-time.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIBQHs6eyp7ImA9WxBWGU8.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-5829360360941022589</id><published>2010-02-11T21:23:00.002Z</published><updated>2010-02-11T21:25:51.513Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-11T21:25:51.513Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="development profile Firefox add-ons" /><title>Firefox Profile for Web Work</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_svLwm_xpSNU/S3R1L3moprI/AAAAAAAAAUw/zupEk5gJS60/s1600-h/firefoxes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="http://2.bp.blogspot.com/_svLwm_xpSNU/S3R1L3moprI/AAAAAAAAAUw/zupEk5gJS60/s320/firefoxes.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;If you're like me you often find new and exciting ways to crash your browser when developing websites. I use mostly &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; for development, given the wealth of useful plugins available (&lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt;, &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;, &lt;a href="http://users.skynet.be/mgueury/mozilla/"&gt;HTML Validator&lt;/a&gt;,&amp;nbsp;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/966"&gt;Tamper Data&lt;/a&gt;...). With Firefox, crash one page, and every window in the browser pukes: bummer. Yes, there's restore functionality after the crash, but with repeated crashes that gets really boring.&lt;br /&gt;
&lt;br /&gt;
However, If you run Firefox with a special "profile" for development, a crash will only take down windows in that profile. To bring up Firefox's profile manager:&lt;br /&gt;
&lt;pre class="brush:bash"&gt;$ firefox --no-remote -P
&lt;/pre&gt;Create a profile, call it something like "web_dev". Then to launch Firefox with this profile, call:&lt;br /&gt;
&lt;pre class="brush:bash"&gt;firefox --no-remote -P web_dev
&lt;/pre&gt;Actually I use a bash alias in ~/.bashrc so I just have to type "firefox_web_dev":&lt;br /&gt;
&lt;pre class="brush:bash"&gt;alias firefox_web_dev='/usr/bin/firefox --no-remote -P web_dev &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;'
&lt;/pre&gt;&lt;br /&gt;
Now when you crash Firefox in the web_dev profile, your regular instance of Firefox won't be affected.&lt;br /&gt;
But there's more.&lt;br /&gt;
Each profile has its own set of add-ons, search engines, etc. So you can set up the HTML Validator add-on in your web_dev profile, and &lt;a href="http://adblockplus.org/"&gt;Adblock Plus&lt;/a&gt; in your default Firefox profile: you won't slow down your regular browsing by validating the whole web's HTML, and you won't have to deal with Adblock hiding the ads you do want to see on the sites you're working on.&lt;br /&gt;
Win-Win?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-5829360360941022589?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DK4asKlHqj7Y1X2XvuTiWvKGX6U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DK4asKlHqj7Y1X2XvuTiWvKGX6U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DK4asKlHqj7Y1X2XvuTiWvKGX6U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DK4asKlHqj7Y1X2XvuTiWvKGX6U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/1aiSKQLa8e0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/5829360360941022589/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2010/02/firefox-profile-for-web-work.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/5829360360941022589?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/5829360360941022589?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/1aiSKQLa8e0/firefox-profile-for-web-work.html" title="Firefox Profile for Web Work" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_svLwm_xpSNU/S3R1L3moprI/AAAAAAAAAUw/zupEk5gJS60/s72-c/firefoxes.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2010/02/firefox-profile-for-web-work.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMNRH08fip7ImA9WxNbFEQ.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-1874317940368863213</id><published>2009-11-16T20:10:00.005Z</published><updated>2009-11-17T22:38:15.376Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-17T22:38:15.376Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="Deployment" /><category scheme="http://www.blogger.com/atom/ns#" term="ssh" /><category scheme="http://www.blogger.com/atom/ns#" term="coding habits" /><title>Colour Your Shells</title><content type="html">&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;You're doing some work on a database driven website...&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;You need to do some tests locally on real data from the production site's db...&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;No problem: just copy the latest db dump backup from the live server!&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;Copying...&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;span style="font-size: small;"&gt;Now just drop the db and reload the backup: &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;dropdb my_precious_data; reload...&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;Wait, you're still logged in on the production server... which means: &lt;b&gt;BAM!&lt;/b&gt; you just dropped the live database. Oops.&lt;/span&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Perhaps that scenario seems far-fetched given the way you develop and deploy your site. But when working on a command line, you'll still find it helpful to know at a glance whether you're logged into your development machine or a production server. I do this by having black text on a white background for my local machine, and light text with a black background for remote machines:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_svLwm_xpSNU/SwGssvtfsfI/AAAAAAAAAUU/LLec_NNTy6U/s1600/consoles.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_svLwm_xpSNU/SwGssvtfsfI/AAAAAAAAAUU/LLec_NNTy6U/s640/consoles.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I generally use &lt;a href="http://www.gnome.org/"&gt;gnome&lt;/a&gt;, but you should be able to find an equivalent on whatever system you use. Here's how I set things up in gnome:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://library.gnome.org/users/gnome-terminal/stable/gnome-terminal-usage.html.en#gnome-terminal-manage-profiles"&gt;Create one gnome-terminal profile per remote machine&lt;/a&gt;. Set the profile's background colour to black, the text colour to something very light; I use a different text colour for each remote machine as an additional visual cue. Set the profile's command to "ssh" to the remote machine, e.g.: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ssh www.blackbox.com&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_svLwm_xpSNU/SwGvIyc9faI/AAAAAAAAAUc/e5OYzBzw4go/s1600/editing_profile2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_svLwm_xpSNU/SwGvIyc9faI/AAAAAAAAAUc/e5OYzBzw4go/s640/editing_profile2.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://library.gnome.org/users/user-guide/stable/gospanel-34.html.en"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://library.gnome.org/users/user-guide/stable/gospanel-34.html.en"&gt;Add a custom application launcher&lt;/a&gt; for each remote machine to the gnome panel. Give the launcher an icon you'll associate with the remote server, and a "command" to launch gnome-terminal with your new profile, e.g.: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;gnome-terminal --window-with-profile=BlackBox&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_svLwm_xpSNU/SwGwAXPXfgI/AAAAAAAAAUk/k8RfQTft3mw/s1600/launcher_properties.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_svLwm_xpSNU/SwGwAXPXfgI/AAAAAAAAAUk/k8RfQTft3mw/s640/launcher_properties.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
That's it! Now, whenever you want to do something on the remote machine, just click the application launcher. When switching between consoles you'll immediately know which machine you're on just by glancing at the colour of the background and text.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-1874317940368863213?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/k2mCHjCdz_HRdLPYxZ22nfXMYFc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k2mCHjCdz_HRdLPYxZ22nfXMYFc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/k2mCHjCdz_HRdLPYxZ22nfXMYFc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k2mCHjCdz_HRdLPYxZ22nfXMYFc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/sUFl4jBVhLk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/1874317940368863213/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/11/colour-your-shells.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/1874317940368863213?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/1874317940368863213?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/sUFl4jBVhLk/colour-your-shells.html" title="Colour Your Shells" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_svLwm_xpSNU/SwGssvtfsfI/AAAAAAAAAUU/LLec_NNTy6U/s72-c/consoles.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/11/colour-your-shells.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIFQHY-fyp7ImA9WxNVEEo.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-5905999918963170027</id><published>2009-10-07T15:29:00.005+01:00</published><updated>2009-10-20T23:41:51.857+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T23:41:51.857+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="Deployment" /><category scheme="http://www.blogger.com/atom/ns#" term="bash script" /><title>Website Deployment</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_svLwm_xpSNU/SsyPt5iyrRI/AAAAAAAAATM/QJthncgbhCA/s1600-h/parachute.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_svLwm_xpSNU/SsyPt5iyrRI/AAAAAAAAATM/QJthncgbhCA/s400/parachute.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Deploying updates to your website is nothing like a military deployment, except for the fact that a little planning and automation can help you not make a complete ass of it.&lt;br /&gt;
&lt;br /&gt;
Say you have a one-server website, and a set of tested updates on your development machine you want to deploy to the production server.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;When are you going to deploy the changes?&lt;/b&gt;&lt;br /&gt;
During your website's quiet time, when it has the least number of users. If you don't know when this is, find out.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Will you have a partially working site during deployment?&lt;/b&gt;&lt;br /&gt;
Hell no, that's worse than having no website. You could bring the website down during deployment and ho hum, but that has the tendency to cause users not to come back. Instead block off the relevant areas with an "undergoing upgrade" page, and stop people logging in whist you deploy.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Which files are you going to deploy?&lt;/b&gt;&lt;br /&gt;
Don't try to remember which set of files you've changed for the update, let your computer do the work for you. Here's a bash script that will do just that:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:bash"&gt;#! /bin/bash

# Configuration
# The local dirs and remote dirs we need to sync
LOC_DIR[0]=/work/websites/dev_site1/ # Local development dir
REM_DIR[0]=/websites/site1/          # Corresponding production dir
LOC_DIR[1]=/work/libs/common/
REM_DIR[1]=/libs/common/
# Add more items to LOC_DIR and REM_DIR as required.

REMOTE_HOST=yourhost.com
REMOTE_PORT=22
REMOTE_USER=yourusername
OPTS="-a --delete --exclude '*~'"
# Done configuration

deploy=0

for i in $(seq 0 $((${#LOC_DIR[@]} - 1))); do
  RES[$i]=`rsync -ni -e "ssh -p ${REMOTE_PORT}" $OPTS ${LOC_DIR[$i]} ${REMOTE_USER}@${REMOTE_HOST}:${REM_DIR[$i]}`
  if [ "${RES[$i]}" != "" ] ; then
    deploy=1
    echo "Files from local ${LOC_DIR[$i]} to ${REMOTE_USER}@${REMOTE_HOST}:${REM_DIR[$i]}"
    echo "${RES[$i]}" # Double quotes needed to preserve newlines
  fi
done

if [ $deploy = 0 ] ; then
  echo "Nothing to deploy"
  exit 1
fi

&lt;/pre&gt;&lt;br /&gt;
This uses &lt;a href="http://samba.anu.edu.au/rsync/"&gt;rsync&lt;/a&gt; to display the differences between your local website files and those on the production server. Now you know what you need to deploy!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How are you going to deploy the changes?&lt;/b&gt;&lt;br /&gt;
By manually copying the files with your SFTP client? I think not, as that would be tedious and error-prone. Instead take the above bash script, and append the following:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:bash"&gt;echo -n "Above changes will be synced to production, proceed? [y/N]: "

read -n 1 proceed

echo

if [[ $proceed == [yY] ]]; then
  for i in $(seq 0 $((${#LOC_DIR[@]} - 1))); do
    if [ "${RES[$i]}" != "" ] ; then
      echo "Syncing from local ${LOC_DIR[$i]} to ${REMOTE_USER}@${REMOTE_HOST}:${REM_DIR[$i]}"
      rsync -v -e "ssh -p ${REMOTE_PORT}" $OPTS ${LOC_DIR[$i]} ${REMOTE_USER}@${REMOTE_HOST}:${REM_DIR[$i]}
    fi
  done
  echo "Done uploading"
else 
  echo "Operation Aborted"
fi
&lt;/pre&gt;&lt;br /&gt;
This will prompt you whether you want to upload the changes, and "rsync"hronise the lot for you: job done. Well, you might then want to do some testing...&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;Thanks to SmokedMidge and jai for contributions to this post. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-5905999918963170027?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yj2umf6JXi_L1RZGM1DjBD4xUpM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yj2umf6JXi_L1RZGM1DjBD4xUpM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yj2umf6JXi_L1RZGM1DjBD4xUpM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yj2umf6JXi_L1RZGM1DjBD4xUpM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/UkQumPOSXXI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/5905999918963170027/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/10/website-deployment.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/5905999918963170027?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/5905999918963170027?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/UkQumPOSXXI/website-deployment.html" title="Website Deployment" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_svLwm_xpSNU/SsyPt5iyrRI/AAAAAAAAATM/QJthncgbhCA/s72-c/parachute.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/10/website-deployment.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04FRn04cSp7ImA9WxNbEU0.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-2699530839689245672</id><published>2009-09-24T23:22:00.015+01:00</published><updated>2009-11-13T10:58:37.339Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-13T10:58:37.339Z</app:edited><title>Enterprise Pattern Syndrome</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sOXGPoTTqoQ/SrvxYRnRaGI/AAAAAAAADnA/wQ9nBV32eEE/s1600-h/dinner+party.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_sOXGPoTTqoQ/SrvxYRnRaGI/AAAAAAAADnA/wQ9nBV32eEE/s320/dinner+party.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5385163178798835810" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;“Let’s have a dinner party!” your wife informs you.  “It will be wonderful and fun and I want to invite all of our friends!  This time I’ll even do the cooking!  All you have to do is sort out the shopping.”&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“A piece of cake” you reply.  “I can manage that”.&lt;/div&gt;&lt;div&gt;So your wife hands you a list of ingredients and supplies to get: a joint of beef, some fresh baby carrots, new coffee coasters, that kind of thing.  Some of it is open to interpretation eg &lt;span class="Apple-style-span"  style="color:#CC33CC;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;‘snacks + sauce for afters... pos salsa?&lt;/span&gt;&lt;/span&gt;’ and some of it, eg the Shaoxing Wine, you’re not sure even sure where to get it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“Whoa!  Stop right there lady!” you exclaim. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“What’s the matter honey?” she replies.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“Well, you haven’t told me where to get all this stuff.  And for some of it you haven’t said how much you want.  Also we don’t have an approved suppliers list drawn up yet.  We can’t start without this infrastructure in place.”&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“Well just go down to the shops, and if you can’t find it then give me a call back.  No problem”.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“Sorry”, you reply.  “But that’s not the way to do it.  I need to examine all the stores first, and then draw up an approved suppliers list of stores that I deem reputable.  That way, I can minimise your chances of getting faulty goods, and also provide you with pre-defined returns policies.  After this is in place, you will need to specify precisely what you want, assuming it is available for the stores.  But don’t worry about which store, I can abstract that for you, providing we both agree on a store-to-item mapping configuration (in XML of course!) which I can draw up and we can both share via use of the NoticeBoard pattern in the front room”&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Your wife looks at you completely baffled.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;“That’s the way we do it at the office honey” you say.  “It works there!” &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;~&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;What you have here is a chronic case of &lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Enterprise Pattern Syndrome&lt;/span&gt;.  This is the notion that a particular design or process that provides benefits to large scale systems should be applied like a brick to the face to solve smaller scenarios as well. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The pattern of an approved suppliers list is a familiar one for large companies.  And yes, when you are large company, especially if you are reselling what you buy as part of a larger product, then for sure, you want to be careful whom you buy from.  After all, if your diode supplier goes bust mid-way through your production cycle and you have designed your circuit boards &lt;i&gt;specifically &lt;/i&gt;for their diodes, then, wow, that’s a problem.  This happened on a project I worked on, diodes and all.  We learned it the hard way.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;But do you need an approved suppliers list for going to the shops?  No.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Recently I was asked to do a software review of a mid-tier web application being built by one of the project teams in our large software house.  This application would run on a single mid-range server and handle say, 500 users tops.  The whole stack, database through to presentation layer was being developed by a small team of Java devs who had recently rolled off a much larger Enterprise banking system.  All the system had to do was read data from the database, maybe change a few fields here and there, and then display it.  Read, Update, Display.  Here is what they had come up with:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sOXGPoTTqoQ/SrvyP9i3YiI/AAAAAAAADnI/mCjmThLuvtY/s1600-h/techstack.gif"&gt;&lt;img src="http://4.bp.blogspot.com/_sOXGPoTTqoQ/SrvyP9i3YiI/AAAAAAAADnI/mCjmThLuvtY/s320/techstack.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5385164135484318242" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 318px; height: 320px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Can you spot the problem here?  The whole top two bespoke layers are doing absolutely nothing.  Nada.  Zilch.  Or to use Enterprise speak, they are correctly implementing the SFA pattern.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Now, there is nothing inherently wrong with having four layers of abstraction.  The VO layer, (Value Objects for those that don’t speak Java) is a valuable pattern.  It is used in much larger applications when your ‘nouns’ of the system (Entity Beans), like Customers, or Hedge Funds are huge bloated objects perhaps with large memory footprints, or perhaps partially obscured (for example for security reasons).  Either way, you don’t want to be creating copies of them, so you make a light weight access class called a VO which is mainly used for examining the properties of the class it refers to.  You can then juggle these smaller fellas around like a circus clown.  But here there is no need for such abstraction.  There is 500 Users objects each with a password and a few fields.  Are you really going to run out of memory when making a copy of these?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I asked the lead developer to walk me through the process of adding a new database table to the application, one that could be seen on the GUI.  He started to build it from the bottom up, beginning with Hibernate and 12 classes later, he had finally reached Struts.  12 classes!  And that’s before he even started programming any display logic.  I asked him what benefit he was getting from having 12 classes here instead of, say 2.  Or, lets go way into left field, maybe just 1.  “It’s cleaner this way”.  He said.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Quick pub quiz:  What’s the best design pattern there is?&lt;/div&gt;&lt;div&gt;Yep, you heard me, the best one.  No, not the best for abstracting business logic.  No, not the best for providing safety critical functions.   I mean the best pattern full stop.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_sOXGPoTTqoQ/Srvyevki3RI/AAAAAAAADnQ/hUYI0nkPRKs/s1600-h/kiss.jpg"&gt;&lt;img src="http://2.bp.blogspot.com/_sOXGPoTTqoQ/Srvyevki3RI/AAAAAAAADnQ/hUYI0nkPRKs/s320/kiss.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5385164389431303442" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 259px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Yes.  In case you weren’t listening at the back, here it is again:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_sOXGPoTTqoQ/SrvytbCOvII/AAAAAAAADnY/W2y_xp4szWU/s1600-h/kiss2.jpg"&gt;&lt;img src="http://1.bp.blogspot.com/_sOXGPoTTqoQ/SrvytbCOvII/AAAAAAAADnY/W2y_xp4szWU/s320/kiss2.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5385164641616706690" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 300px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;K.I.S.S.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;“Things should be made as simple as possible, but not simpler”&lt;/i&gt;.  And that is the truth of the matter. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Every time you use an Enterprise pattern (and by Enterprise pattern, I chiefly mean a pattern that adds complexity to the design), you should know why you have chosen to implement this pattern.  What benefit to the design is this added complexity providing? You should be able to explain this, clearly and succinctly, to both your colleagues, and most importantly to yourself. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;And if you can’t explain it, you probably don’t need to use it.  It’s as simple as that.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-2699530839689245672?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RigL0pssWIICoNIKonFZDC-v8xQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RigL0pssWIICoNIKonFZDC-v8xQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RigL0pssWIICoNIKonFZDC-v8xQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RigL0pssWIICoNIKonFZDC-v8xQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/D9t7QXeceY0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/2699530839689245672/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/09/test.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/2699530839689245672?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/2699530839689245672?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/D9t7QXeceY0/test.html" title="Enterprise Pattern Syndrome" /><author><name>Wunderkind</name><uri>http://www.blogger.com/profile/07410462640941621186</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="26" src="http://www.elsew.com/data/crawd76.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_sOXGPoTTqoQ/SrvxYRnRaGI/AAAAAAAADnA/wQ9nBV32eEE/s72-c/dinner+party.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/09/test.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIHQns4eyp7ImA9WxNQF0k.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-6608208121414797284</id><published>2009-09-23T23:22:00.000+01:00</published><updated>2009-09-23T23:22:13.533+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-23T23:22:13.533+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="subversion" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Security Through Asceticism</title><content type="html">There's a recent &lt;a href="http://www.techcrunch.com/2009/09/23/basic-flaw-reveals-source-code-to-3300-popular-websites/"&gt;story&lt;/a&gt; about several thousand websites revealing their source code due to version control directories being present along with the web content files. For example, if you use &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt;&amp;nbsp;to manage your web content, it creates .svn directories in each and every subdirectory of your project. If you do a fresh upload of your site and forget to remove these directories, or have had the not so bright idea of having your production site directly under version control so you can update it with &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;"svn update"&lt;/span&gt;, then you're revealing the source code to your site.&lt;br /&gt;
&lt;br /&gt;
Maybe that's not a big deal. Everyone can see your HTML source anyway... But it could be a big deal if you're running a dynamic site: revealing your PHP code or your database schema can make it much easier for a malicious hacker to successfully attack your site. Either way, if you include world-readable version control directories in your web space as a matter of course, you're breaking one of cardinal security rules: &lt;b&gt;"Have Nothing More Than You Need On Your Server"&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
If there are any files on your production server that aren't meant to be accessed: remove them. If there's software installed on your production server that you don't run and never will: uninstall it. Even if you can't think of any way the extra files or programs could compromise your server, chances are someone else can.&lt;br /&gt;
&lt;br /&gt;
So, what should you do about .svn directories? You could have a look at the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;"&lt;/span&gt;&lt;a href="http://svnbook.red-bean.com/en/1.0/re10.html"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;svn export&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;"&lt;/span&gt; command. You could use an &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;rsync&lt;/span&gt; command to update your site, telling it to &lt;a href="http://blog.gungfu.de/archives/2005/09/25/using-rsync-together-with-subversion/"&gt;ignore .svn/*&lt;/a&gt;. Or you could use a version control system like &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; which only creates one .git directory at the root of your project, instead of spreading itself around all your subdirectories like a plague.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-6608208121414797284?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/voXE_GkYvZ5LV_P0-AwxLhYLsqE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/voXE_GkYvZ5LV_P0-AwxLhYLsqE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/voXE_GkYvZ5LV_P0-AwxLhYLsqE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/voXE_GkYvZ5LV_P0-AwxLhYLsqE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/KYC4prClwBw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/6608208121414797284/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/09/security-through-asceticism.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/6608208121414797284?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/6608208121414797284?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/KYC4prClwBw/security-through-asceticism.html" title="Security Through Asceticism" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/09/security-through-asceticism.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IFSXw8fSp7ImA9WxNRFks.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-8126545779056557563</id><published>2009-09-03T17:24:00.006+01:00</published><updated>2009-09-11T12:45:18.275+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T12:45:18.275+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="valid HTML" /><title>Compliant Code is Easier to Debug</title><content type="html">Debugging JavaScript can be much nicer if you're coding for a site that is &lt;a href="http://validator.w3.org/"&gt;W3C compliant&lt;/a&gt;. There are other reasons to always write valid HTML, like making your site &lt;a href="http://www.webstandards.org/learn/faq/#p3"&gt;accessible&lt;/a&gt; to the greatest number of people and software clients. The case has also been made for the &lt;a href="http://www.adaptivepath.com/ideas/essays/archives/000266.php"&gt;business value of web standards&lt;/a&gt;. Note that the detecting and fixing invalid HTML is unlikely to change the appearance of your site in your browser. The reason there is so much dodgy HTML in the wild is because browsers are extremely permissive and try to compensate for most HTML errors. You'll find cases where a page "works fine" up until you try to make it a little easier to use with a touch of JavaScript magic, and get some pretty weird behaviour. Chances are, broken HTML has been used for years and nobody noticed... then it suddenly becomes a problem. Your problem.&lt;br /&gt;
&lt;br /&gt;
I'll give a couple examples of how generally having valid HTML can help debug JavaScript, but first I need to introduce an excellent Firefox add-on: &lt;a href="http://users.skynet.be/mgueury/mozilla/"&gt;HTML Validator&lt;/a&gt;. This add-on displays a small icon to tell you whether your page is standards compliant, and can pinpoint exactly where in a page's source any nasty non-compliance is going on. The HTML Validator also supports site filters: you can set it up to only validate automatically the sites you work on.&lt;br /&gt;
&lt;br /&gt;
So how does this help debug JavaScript? Here are a couple scenarios...&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Duplicate IDs&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The HTML specification requires that each tag's "id" be unique. HTML Validator will warn you if you've inadvertently used the same "id" twice; it's icon will change to a warning symbol, and clicking on it will show you an error something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_svLwm_xpSNU/Sp_oLuRZMJI/AAAAAAAAASM/i6cQjhcKtiU/s1600-h/error1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_svLwm_xpSNU/Sp_oLuRZMJI/AAAAAAAAASM/i6cQjhcKtiU/s400/error1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
If you spot this, you'll not spend time banging your head on your desk trying to figure out the element returned by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;document.getElementById()&lt;/span&gt; isn't giving you the result you expected...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Broken DOM&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
All kinds of interesting JavaScript behaviour can occur if you've managed to seriously break the Document Object Model, e.g. with &amp;lt;div&amp;gt;s that are never closed, or code outside the &amp;lt;html&amp;gt; tags. This can be surprisingly tricky to spot if you're not checking the HTML for compliance, especially if the DOM-breaking code has been around for years: you might be working on a completely different part of the page in question. However, if you're paying attention to the HTML validator, you'll notice right away something is wrong with the page, and go straight for the fix, rather than trying to debug you own, perfectly correct, code!&lt;br /&gt;
&lt;br /&gt;
Write valid HTML: some of your users will thank you, and you'll save yourself a great deal of hassle in the long run.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-8126545779056557563?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aAV0vlYJgHjj6HzaQe97qv1RRJM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aAV0vlYJgHjj6HzaQe97qv1RRJM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aAV0vlYJgHjj6HzaQe97qv1RRJM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aAV0vlYJgHjj6HzaQe97qv1RRJM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/HS1MIGSBPdk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/8126545779056557563/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/09/compliant-code-is-easier-to-debug.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8126545779056557563?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8126545779056557563?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/HS1MIGSBPdk/compliant-code-is-easier-to-debug.html" title="Compliant Code is Easier to Debug" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_svLwm_xpSNU/Sp_oLuRZMJI/AAAAAAAAASM/i6cQjhcKtiU/s72-c/error1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/09/compliant-code-is-easier-to-debug.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMBQXo-fyp7ImA9WxNRFko.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-1735858890394032009</id><published>2009-09-01T21:30:00.012+01:00</published><updated>2009-09-11T13:00:50.457+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T13:00:50.457+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="HTML forms" /><title>JavaScript Snippets for Slicker HTML Forms</title><content type="html">Some simple JavaScript can make your website forms seem slicker, and easier to interact with. Here are a few examples to build from...&lt;br /&gt;
&lt;br /&gt;
You can use the &lt;b&gt;onfocus&lt;/b&gt; and &lt;b&gt;onblur&lt;/b&gt; attributes to guide users, for example in a search box where you have no room for a label:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:html"&gt;&amp;lt;input type="text" value="Search terms..."
  onfocus="if (this.value == 'Search terms...') this.value = '';"
  onblur="if (this.value == '') this.value = 'Search terms...';"
&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
This will give you an input like this, try clicking in and out of it:&lt;br /&gt;
&lt;br /&gt;
&lt;input onblur="if (this.value == '') this.value = 'Search terms...';" onfocus="if (this.value == 'Search terms...') this.value = '';" type="text" value="Search terms..." /&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;b&gt;onclick&lt;/b&gt; attribute can prevent accidental duplicate form submission, say if a user tends to double click everything:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:html"&gt;&amp;lt;input type="submit" onclick="this.disabled=true;"&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
This will give you a submit button that can only be clicked once, try it:&lt;br /&gt;
&lt;br /&gt;
&lt;input onclick="this.disabled=true;" type="submit" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Using &lt;b&gt;onchange&lt;/b&gt; to show a different input box depending on what a user selects from a drop down box.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:html"&gt;&amp;lt;select onchange="
var val = this.options[this.selectedIndex].value,
     en = document.getElementById('en'),
     fr = document.getElementById('fr');
if (val == 'English') {
  en.style.display = 'block'; 
  fr.style.display = 'none';
} else if (val == 'French') {
  en.style.display = 'none';
  fr.style.display = 'block';
} else {
  en.style.display = 'none';
  fr.style.display = 'none';
} "&amp;gt;
&amp;lt;option&amp;gt;Select your language...
&amp;lt;option&amp;gt;English
&amp;lt;option&amp;gt;French
&amp;lt;/select&amp;gt;
&amp;lt;input id="en" style="display: none;" type="text" value="Do you like cats?"&amp;gt;
&amp;lt;input id="fr" style="display: none;" type="text" value="Aimez-vous les chats?"&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Will give you:&lt;br /&gt;
&lt;br /&gt;
&lt;select onchange="var val = this.options[this.selectedIndex].value,
     en = document.getElementById('en'),
     fr = document.getElementById('fr');
if (val == 'English') {
  en.style.display = 'block';
  fr.style.display = 'none';
} else if (val == 'French') {
  en.style.display = 'none';
  fr.style.display = 'block';
} else {
  en.style.display = 'none';
  fr.style.display = 'none';
} "&gt; &lt;option&gt;Select your language...&lt;/option&gt; &lt;option&gt;English&lt;/option&gt; &lt;option&gt;French&lt;/option&gt; &lt;/select&gt;&lt;input id="en" style="display: none;" type="text" value="Do you like cats?" /&gt;&lt;input id="fr" style="display: none;" type="text" value="Aimez-vous les chats?" /&gt;&lt;br /&gt;
&lt;br /&gt;
These are just a few building blocks to make interacting with HTML forms a bit less painful. The less a user has to look at and interpret, and the less opportunities they have to screw things up, they happier they will be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-1735858890394032009?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2_oiI-0GzHHxu18BZA11hBh36Oo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2_oiI-0GzHHxu18BZA11hBh36Oo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2_oiI-0GzHHxu18BZA11hBh36Oo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2_oiI-0GzHHxu18BZA11hBh36Oo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/Wgcyod69yOo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/1735858890394032009/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/09/javascript-one-liners.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/1735858890394032009?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/1735858890394032009?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/Wgcyod69yOo/javascript-one-liners.html" title="JavaScript Snippets for Slicker HTML Forms" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/09/javascript-one-liners.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IBQns4eCp7ImA9WxNRFks.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-2956655203396048802</id><published>2009-08-26T17:19:00.011+01:00</published><updated>2009-09-11T12:45:53.530+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T12:45:53.530+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="coding standards" /><category scheme="http://www.blogger.com/atom/ns#" term="coding habits" /><title>Develop Good Coding Habits</title><content type="html">It's worth developing good coding habits, as they will make your life easier in the long run. You'll end up writing code that easier to read and maintain, that runs slightly faster and is more secure. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Legibility&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
To make your code easy to read, one good habit is to pick a format for your code and stick to it. Use indentation, braces and variable names in the way that suits you best, but stick to the same format across your whole project.&lt;br /&gt;
&lt;br /&gt;
Another good habit is to always perform equivalent operations in the same way. It might be obvious to you that all these do Perl statements do the same thing:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:perl"&gt;$huh or die "no!";
if (!$huh) { die "no!"; }
die "no!" unless $huh;
&lt;/pre&gt;&lt;br /&gt;
... but it might not be so obvious to your future newby apprentice: indeed if you use these interchangeably, he'll probably think the statements are different for a reason! You care about this, because you don't want to have to get out of bed one night to fix your apprentice's mistake, which was due to you showing off your knowledge of Perl syntax variations...&lt;br /&gt;
&lt;br /&gt;
Also, if you think you've just done something really clever, stop. Write a comment about it. Half the time, you'll realise the code is actually not that clever by writing the comment. If it really is clever, then the comment will help the next person who comes around to look at the code (which could be you, in a year's time).&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Speed&lt;/b&gt;&lt;br /&gt;
How do you choose a set of standards for a new project? You could pick whatever you're most familiar with. Or if you have no strong preference, you might as well pick whatever works fastest, if there is a difference to be found.&lt;br /&gt;
&lt;br /&gt;
For example, in PHP, you could write either of:&lt;br /&gt;
&lt;pre class="brush:php"&gt;print "Welcome " . $name;
echo 'Welcome ', $name;
&lt;/pre&gt;&lt;br /&gt;
If you select the second form as standard, you'll get a small speed boost each time you display a string, in three different ways:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;echo&lt;/span&gt; is faster than &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;print&lt;/span&gt;, as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;print&lt;/span&gt; returns a value but &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;echo&lt;/span&gt; doesn't;&lt;/li&gt;
&lt;li&gt;Single quotes are faster than double quotes, as PHP parses double-quoted strings to expand any variables therein;&lt;/li&gt;
&lt;li&gt; Note the comma rather than the period in the second statement: rather than appending strings to display, the comma causes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;echo&lt;/span&gt; to just output one string, then the next. This is &lt;a href="http://www.electrictoolbox.com/php-echo-commas-vs-concatenation/"&gt;slightly faster&lt;/a&gt;.&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;Note, however, that the speed increase is going to be tiny. It would never make sense to re-write existing code with optimisations like these, but if you're starting from scratch this isn't a bad way to go.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Security&lt;/b&gt;&lt;br /&gt;
When coding, you should always have a process running somewhere in your brain called "How could I hack this?". If you can think of a way you could hack your application or site in a damaging way without any of your privy information, you have a problem. To reduce the CPU usage of this thought process, try to develop habits automatically rule out some kinds of attacks.&lt;br /&gt;
&lt;br /&gt;
For example, one essential habit is to always sanitise your inputs and outputs no matter how benign they might appear. If the PHP statement above was to be used on a website,  to protect against XSS attacks it should really have read:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:php"&gt;echo 'Welcome ', htmlspecialchars($name);
&lt;/pre&gt;&lt;br /&gt;
Another obvious good habit that will keep your site secure is to always make sure you're using the latest stable version of any programs or libraries you are using. Strange that so many people run versions of software with known vulnerabilities...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It's Boring&lt;/b&gt;&lt;br /&gt;
You got this far, but found all the above kind of boring? Well, it kind of is. It's not really helping you make your code do things. But if you try to develop some good habits and set standards at the start of a project, your job will be so much easier updating and maintaining the project down the line.&lt;br /&gt;
&lt;br /&gt;
Furthermore, if you're lucky, any other programmer that joins you on working on the project will notice the care and consistency that's gone into the code, and try to match it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-2956655203396048802?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Gr-ttNrBGfW_TTHR_Klaw0FFrwU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gr-ttNrBGfW_TTHR_Klaw0FFrwU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Gr-ttNrBGfW_TTHR_Klaw0FFrwU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gr-ttNrBGfW_TTHR_Klaw0FFrwU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/tnSK_OSLxME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/2956655203396048802/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/08/develop-good-coding-habits.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/2956655203396048802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/2956655203396048802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/tnSK_OSLxME/develop-good-coding-habits.html" title="Develop Good Coding Habits" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/08/develop-good-coding-habits.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IMR3oyfyp7ImA9WxNRFks.&quot;"><id>tag:blogger.com,1999:blog-6162838103231793213.post-8601556377468478505</id><published>2009-08-24T21:37:00.005+01:00</published><updated>2009-09-11T12:46:26.497+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T12:46:26.497+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="error alert" /><category scheme="http://www.blogger.com/atom/ns#" term="php" /><title>Be the First to Catch Your Mistakes</title><content type="html">&lt;blockquote&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;To:&lt;/span&gt;&lt;span style="font-size:85%;"&gt; web developer&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;From:&lt;/span&gt;&lt;span style="font-size:85%;"&gt; sales&lt;br /&gt;
Dear developer, please see message below from our top customer.&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;To:&lt;/span&gt;&lt;span style="font-size:85%;"&gt; sales&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;From:&lt;/span&gt;&lt;span style="font-size:85%;"&gt; top customer&lt;br /&gt;
John, I've been trying to log in to your website all day. It's seriously broken. I'm fed up - and leaving!&lt;br /&gt;
Ciao, ex-Customer&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;
As a web developer for a small business, that kind of email ranks pretty high on the list of emails you don't want to see. Of course you might think people should contact you earlier about this kind of issue. Of course you can fantasize all you like.&lt;br /&gt;
&lt;br /&gt;
So, you rush to your development machine and test the login code you updated and deployed yesterday: it works fine. You login with a test account on the live server: that works fine. You start thinking the top customer's "Internet is broken".&lt;br /&gt;
&lt;br /&gt;
Hmm...&lt;br /&gt;
&lt;br /&gt;
You check the PHP error log (of course you log errors to file on the production server, and don't display them in the browser, right?).&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;# less &lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;/web/logs/php/php_error_log&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=";font-family:courier new;font-size:78%;"  &gt;Warning: pg_query(): Query failed: ERROR:  syntax error at or near "cret1" LINE 1: ... WHERE login = 'customer1' AND password = md5('ze'cret1' || ...&lt;br /&gt;
Warning: pg_query(): Query failed: ERROR:  syntax error at or near "cret1" LINE 1: ... WHERE login = 'customer1' AND password = md5('ze'cret1' || ...&lt;br /&gt;
Warning: pg_query(): Query failed: ERROR:  syntax error at or near "cret1" LINE 1: ... WHERE login = 'customer1' AND password = md5('ze'cret1' || ...&lt;/span&gt;&lt;br /&gt;
&lt;span style=";font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Bingo! There's an apostrophe in the customer's password, and that's breaking the login SQL query.&lt;br /&gt;
&lt;br /&gt;
Somehow the recent code update removed a call to pg_escape() for the password field. That's not a particularly easy error to catch. You curse yourself for not using &lt;a href="http://www.php.net/manual/en/function.pg-query-params.php"&gt;pg_query_params()&lt;/a&gt; or a prepared statement in the first place, as both automatically escape variables.&lt;br /&gt;
&lt;br /&gt;
However, even if you made that mistake, you still should have caught that error much earlier. In fact, you should have been alerted after the first failed login attempt. A simple bash script run with cron could have done the trick:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;# cat /web/tools/rotate_php_log.sh:&lt;/pre&gt;&lt;pre class="brush:bash"&gt;#! /bin/bash

PHP_LOG=/web/logs/php/php_error_log

if [[ -f $PHP_LOG ]]; then
  cat $PHP_LOG;
  mv $PHP_LOG /web/logs/php/old/php_error_log_`date +%F_%H-%m-%S`
fi
&lt;/pre&gt;&lt;pre&gt;# crontab -l:&lt;/pre&gt;&lt;pre class="brush:bash"&gt;MAILTO=youremail@....com
# Rotate and output any PHP logs
*/4                * * * * /web/tools/rotate_php_log.sh
&lt;/pre&gt;&lt;br /&gt;
Setting up this simple cron job would have alerted you of the login problem in under 5 minutes with an email from the server. If you think you'll get too many emails because your logs fill up with notices and warnings... go fix your code! You'll make it so much easier to debug and so much more portable...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6162838103231793213-8601556377468478505?l=smartcode.simplewind.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/55FPtyAu6IATz7m52S9jHZZC6YY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/55FPtyAu6IATz7m52S9jHZZC6YY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/55FPtyAu6IATz7m52S9jHZZC6YY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/55FPtyAu6IATz7m52S9jHZZC6YY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/simplewind/smartcode/~4/q1b_-iZLAkc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://smartcode.simplewind.com/feeds/8601556377468478505/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://smartcode.simplewind.com/2009/08/be-first-to-catch-your-mistakes.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8601556377468478505?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6162838103231793213/posts/default/8601556377468478505?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/simplewind/smartcode/~3/q1b_-iZLAkc/be-first-to-catch-your-mistakes.html" title="Be the First to Catch Your Mistakes" /><author><name>Jackson</name><uri>http://www.blogger.com/profile/05698362178521384646</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-_9UGl-knDGM/TW-fOx6ctxI/AAAAAAAAAXs/VKeg3ofmB_w/s220/twit.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://smartcode.simplewind.com/2009/08/be-first-to-catch-your-mistakes.html</feedburner:origLink></entry></feed>

