<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>//_Semicolon;</title> <atom:link href="http://www.semicolon.co.za/feed" rel="self" type="application/rss+xml" /><link>http://www.semicolon.co.za</link> <description>Will code for food; The ramblings of Talifhani Luvhengo;</description> <lastBuildDate>Sun, 20 Nov 2011 10:31:55 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Moving On</title><link>http://www.semicolon.co.za/uncategorised/moving-on.html</link> <comments>http://www.semicolon.co.za/uncategorised/moving-on.html#comments</comments> <pubDate>Sun, 20 Nov 2011 10:16:26 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Uncategorised]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=28136</guid> <description><![CDATA[I recent resigned from Jobs.co.za, by recently i mean a month ago I&#8217;ve since started a new adventure as a Seniour Developer at Liquorice in Cape Town. Joburg to Cape Town, yeah big move. But it was time for a change. Change is good. I had a great time at Jobs.co.za. Got to do a [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/uncategorised/moving-on.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Funcategorised%2Fmoving-on.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Funcategorised%2Fmoving-on.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p><img
src="http://www.semicolon.co.za/wp-content/uploads/2011/11/Untitled-1.png" alt="" title="Untitled-1" width="650" height="133" class="alignright size-full wp-image-28152" /></p><p>I recent resigned from Jobs.co.za, by recently i mean a month ago <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br
/> I&#8217;ve since started a new adventure as a Seniour Developer at Liquorice in Cape Town. Joburg to Cape Town, yeah big move. But it was time for a change. Change is good.<br
/> I had a great time at Jobs.co.za. Got to do a lot of crazy stuff on the website. I still say to this point that that&#8217;s the nest job i&#8217;ve had in my entire career.</p><p>At Jobs.co.za i learnt that i can always get better if i pushed my self.  Got to play with a lot of cool technology like sphinx. Got to deal with MySQL scaling issues, Optimisation issues. I became a better developer. Made lots of awesome friends. But the time comes to move on.</p><p>Anywho, two weeks at Liquorice and I think i&#8217;m gonna love it here. Not too sure about Cape Town, but the company, Definitely. The team is great, everyone seems to love their job, Gung-ho, suspiciosly so <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br
/> This is the first time i&#8217;ve worked in such a streamlined production process. It takes some getting used. Updating tickets, Branch that repo, merge that repo, update Active Collab. Which by the way is a great Project management application. Worth the licence. I&#8217;ve learnt it can mean the difference between a project being on time or a month late.</p><p>Have a look at my first project here -&gt;  realitycheck.co.za. Its both web and mobile. Depending on your device.</p><p>Will keep you posted on any new developments.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/uncategorised/moving-on.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Developing m.Jobs.co.za (Jobs.co.za Mobile)</title><link>http://www.semicolon.co.za/php/developing-m-jobs-co-za-jobs-co-za-mobile.html</link> <comments>http://www.semicolon.co.za/php/developing-m-jobs-co-za-jobs-co-za-mobile.html#comments</comments> <pubDate>Fri, 19 Aug 2011 13:29:23 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Mobile]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=456</guid> <description><![CDATA[Introduction About a month or two ago I took on the task of developing the Jobs.co.za mobile(m.jobs.co.za). For those of you that don&#8217;t know. I work for Jobs.co.za. A Job Portal like no other. We do a lot of cool stuff. A topic for a whole &#8216;nother post. With the barrage of mobile web frameworks [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/php/developing-m-jobs-co-za-jobs-co-za-mobile.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fdeveloping-m-jobs-co-za-jobs-co-za-mobile.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fdeveloping-m-jobs-co-za-jobs-co-za-mobile.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><h1>Introduction</h1><p><strong><a
href="http://www.semicolon.co.za/wp-content/uploads/2011/08/jobsmobile.jpg"><img
class="alignright size-medium wp-image-479" align="right" title="Jobs.co.za Mobile site" src="http://www.semicolon.co.za/wp-content/uploads/2011/08/jobsmobile-143x300.jpg" alt="" width="143" height="300" /></a></strong>About a month or two ago I took on the task of developing the Jobs.co.za mobile(<a
title="Jobs.co.za Mobile Site" href="http://m.jobs.co.za">m.jobs.co.za</a>). For those of you that don&#8217;t know. I work for Jobs.co.za. A Job Portal like no other. We do a lot of cool stuff. A topic for a whole &#8216;nother post. With the barrage of mobile web frameworks out there it was easy to make a decision on which one to use. Non of them. I&#8217;m a fan of mobile frameworks but I believe they have their place on the mobile web. They are perfect for &#8220;mobile web applications&#8221; where your target is more likely smart phone users(iPhone, Androids). But we decided to target your everyday Tom, Dick and Harry. Or is it Thabo, Pule and Jabu. Whatever your school of thought. But at the same time you don&#8217;t want to compromise your high end user&#8217;s experience.<strong></strong></p><h2>Technology</h2><p><strong>No Javascript(Zero, Non)<br
/> </strong>Well except for the registration page. We used javascript to try and get your current location(From your GPS) so you don&#8217;t have to go and search through the drop down for your location. Works pretty well especially if your GPS is enabled.</p><p><strong>No device capability detection</strong><br
/> There is no device capability detection libraries like Wurfl or Device Atlas. These are really awesome tools. I&#8217;ve only ever used Wurfl in the past. It gives you all kinds of details from screen width to supported images. But I personally think if you can do it without them then do it. So the approach I took was to develop an &#8220;adaptive site&#8221;. So instead of trying to get the device&#8217;s width and adjust time the web pages width, I simple gave it a width of 100%. Which means it will grow and shrink with the device.</p><p><strong>Geolocation API</p><p>http://en.wikipedia.org/wiki/W3C_Geolocation_API</p><p></strong>The <a
title="Wikipedia: Geolocation API" href="http://en.wikipedia.org/wiki/W3C_Geolocation_API">Geolocation API</a> can be used to locate devices. But obviously it will request permission from the user. This was used in the registration page to automatically select your location. Of-cause this assumes you are currently in the area where you live. Which is probably untrue. But any excuse to play with the API. <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> This is the only javascript that was used on the site.</p><p><strong>Relative measures</strong><br
/> There are no absolute measures like px, pt and so forth. The problem with these measures is that 1px to a Nokia&#8217;s screen will not look the same as 1px on an iPhone&#8217;s screen. So all dimensions are defined using the <a
href="http://en.wikipedia.org/wiki/Em_%28typography%29"><em><strong>em</strong></em></a> unit of measurement. This means that the font-size will be defined in relation to the device its being viewed on. 1em the default size. For example, most web browsers(firefox, ie) default to 16px=1em</p><p><strong>Images</strong><br
/> Tried our best to avoid images unless absolutely necessary, opting to use CSS creatively instead. On the home page only 2 images load. The logo, and rounded navigation bar, even that is a 1px wide images repeated using CSS(338bytes). The image dimensions are also defined using ems.<br
/> NOTE: Also playing around with <a
href="http://en.wikipedia.org/wiki/Data_URI_scheme">DATA-URIs</a> to reduce the number of requests on the home page from 4 to 2. This would result in a significant reduction in loading time but possibly an increase on the page size. The problem at the moment is that some phones just don&#8217;t support them.</p><p><strong>UX Design</strong><br
/> User experience is a HUGE thing for me. I love websites where as soon as hit the page, I know what the current state of the system is, what other states can be achieved and how these states can be achieved. I think we managed to achieve simplicity and didn&#8217;t compromise too much on functionality.</p><p><strong>No Mobile frameworks<br
/> </strong>Firstly let me just clarify, I love Jquery mobile, its brilliant. But its also Beta. Beta 2 at the time of writing. My biggest issue is that it doesn&#8217;t <a
href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript">degrade as gracefully as it should</a>. So your non smart phone users are loosing out on the experience. So the one solution is to have multiple sites. Which Facebook did for a long time, until they <a
href="http://fallonnugen.typepad.com/blog/2011/05/facebook-launches-unified-mobile-site-announces-250-million-mobile-users.html">realised some of the flaws in that architecture</a>. With one code base you can roll out new features to all devices. Which enables you to be more creative.</p><p>So go ahead and play around on http://m.jobs.co.za</p><p>This is a very draft post. Will be adding more stuff soon. Just wanted to get it out of the way or else I&#8217;d never write it <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/php/developing-m-jobs-co-za-jobs-co-za-mobile.html/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Wow, good golly me. My uncle&#8217;s dead?</title><link>http://www.semicolon.co.za/random/wow-good-golly-me-my-uncles-dead.html</link> <comments>http://www.semicolon.co.za/random/wow-good-golly-me-my-uncles-dead.html#comments</comments> <pubDate>Fri, 19 Aug 2011 13:15:14 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Random]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=466</guid> <description><![CDATA[Wow, good golly me. My uncle&#8217;s dead? And my poor cousins. Oh my dear Aunt. How can I carry on. I love these scams. They are getting really creative with them too. And the fact that they keep sending them means people do fall for it.  Thought it&#8217;d make for some good laughs. &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Barrister [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/random/wow-good-golly-me-my-uncles-dead.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Frandom%2Fwow-good-golly-me-my-uncles-dead.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Frandom%2Fwow-good-golly-me-my-uncles-dead.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p>Wow, good golly me. My uncle&#8217;s dead? And my poor cousins. Oh my dear Aunt. How can I carry on. I love these scams. They are getting really creative with them too. And the fact that they keep sending them means people do fall for it.  Thought it&#8217;d make for some good laughs.</p><p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p><p>Barrister Serge P. SOUZA</p><p><span
style="font-size: medium;"><strong>01 BP 4452Cotonou-Benin<br
/> Tel: <a
href="tel:%28%2B229%29%2098967503" target="_blank">(+229) 98967503</a></strong></span></p><p><span
style="font-size: medium;"><strong>ATTN: Luvhengo</strong></span></p><p>I&#8217;mBarrister Serge P. SOUZA<span
style="font-size: medium;"><strong>, Private lawyer to Late Michael Luvhengo ,a national of your country, who used to work as the Director of petroliers (TOTAL BENIN) in Benin Republic West Africa Here in after shall be Referred to as my client.</strong></span></p><p>On 27th of May 2008 my client also His wife and their three Children were involved in a car accident Along Grossi express-road. All occupants of the vehicle Unfortunately lost their lives. Since then I have made several enquiries to your embassy to locate any of my clients extended relatives this has also proved Unsuccessful.</p><p>After these several unsuccessful attempts, I decided to track His Surname over the Internet, to locate any member of the Family with the last name, that is why I contacted you. I have contacted you to assist in Repatriating the money and property left behind by my client before they get confiscated or declared unserviceable by the bank here. These huge deposits were lodged particularly, with the &#8220;BANQUE ATLANTIQUE DU BENIN (BAB)&#8221; An affiliate of Commercial Bank of Africa where the Deceased had an account valued at about $9.7 million dollars.</p><p>The Bank has issued me a notice to provide the next of kin or have the account confiscated. Since I have been unsuccessful in Locating the relatives for over four years now I seek your consent To present you as the next of kin of the deceased since you have The same last name so that the proceeds of this account valued at $9.7 million dollars can be paid to you and then you and me can Share the money.50% to me and 50% to you I will procure all Necessary legal documents that can be used to back up any claim we may make. All I require is your honest cooperation to enable us seeing this Deal through.</p><p>I guarantee that this will be executed under a legitimate arrangement that will protect you from any breach of the law. And the way we are going to achieve this is.<br
/> I will need the following important information from you,<br
/> Your Full Name&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<wbr>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br
/> Your Address&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<wbr>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br
/> Your Age&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<wbr>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br
/> Your Occupation&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<wbr>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br
/> Your Position&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<wbr>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br
/> Your Telephone and Mobile&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<wbr>.<br
/> For Communication Purpose.<br
/> I await your reply ASAP.</wbr></wbr></wbr></wbr></wbr></wbr></p><p>Best Regards.</p><p>Barrister Serge P. SOUZA</p><p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/random/wow-good-golly-me-my-uncles-dead.html/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Xdebug styling is missing</title><link>http://www.semicolon.co.za/uncategorised/xdebug-styling-is-missing.html</link> <comments>http://www.semicolon.co.za/uncategorised/xdebug-styling-is-missing.html#comments</comments> <pubDate>Wed, 17 Aug 2011 08:02:24 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Uncategorised]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=461</guid> <description><![CDATA[I&#8217;m just putting this up so I don&#8217;t forget, if someone finds it useful awesome. When i upgraded to PHP5.3 a lot of thing that were enabled by default in previous version were disabled. When I install XDebug I expect to see my pretty orange tables with errors and a stack trace. That feature has [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/uncategorised/xdebug-styling-is-missing.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Funcategorised%2Fxdebug-styling-is-missing.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Funcategorised%2Fxdebug-styling-is-missing.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p>I&#8217;m just putting this up so I don&#8217;t forget, if someone finds it useful awesome. When i upgraded to PHP5.3 a lot of thing that were enabled by default in previous version were disabled. When I install XDebug I expect to see my pretty orange tables with errors and a stack trace. That feature has also been disabled.</p><p>To enable it just find the the line</p><p><strong>html_errors=Off</strong></p><p>and change it to</p><p><strong>html_errors=On</strong></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/uncategorised/xdebug-styling-is-missing.html/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>PHP Function/Method Overloading</title><link>http://www.semicolon.co.za/php/php-functionmethod-overloading.html</link> <comments>http://www.semicolon.co.za/php/php-functionmethod-overloading.html#comments</comments> <pubDate>Wed, 13 Jul 2011 10:24:15 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=445</guid> <description><![CDATA[&#8220;Function overloading or method overloading is a feature found in various programming languages such as Ada, C#, VB.NET, C++, D and Java that allows the creation of several methods with the same name which differ from each other in terms of the type of the input and the type of the output of the function.&#8221; [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/php/php-functionmethod-overloading.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fphp-functionmethod-overloading.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fphp-functionmethod-overloading.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p><strong>&#8220;Function overloading</strong> or <strong>method overloading</strong> is a feature found in various <a
title="Programming language" href="http://en.wikipedia.org/wiki/Programming_language">programming languages</a> such as <a
title="Ada (programming language)" href="http://en.wikipedia.org/wiki/Ada_%28programming_language%29">Ada</a>, <a
title="C Sharp (programming language)" href="http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29">C#</a>, <a
title="VB.NET" href="http://en.wikipedia.org/wiki/VB.NET">VB.NET</a>, <a
title="C++" href="http://en.wikipedia.org/wiki/C%2B%2B">C++</a>, <a
title="D (programming language)" href="http://en.wikipedia.org/wiki/D_%28programming_language%29">D</a> and <a
title="Java (programming language)" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a> that allows the creation of several <a
title="Subprogram" href="http://en.wikipedia.org/wiki/Subprogram">methods</a> with the same name which differ from each other in terms of the type of the input and the type of the output of the function.&#8221; &#8212; <a
title="Function Overloading Wikipedia" href="http://en.wikipedia.org/wiki/Function_overloading">Wikipedia(http://en.wikipedia.org/wiki/Function_overloading)</a></p><p>I&#8217;m sure by now you have realised that PHP does not natively support function overloading. It can get annoying, especially if like me you are from a Java(Or whatever Full OO language you&#8217;re from) background. I doubt its coming to PHP anytime soon, haven&#8217;t really looked at the road map but from first glance it would be too big a change and render function like __call(), __get(), __set() a bit useless. So what is a developer with too much time in his hands to do? Well come up with a way to simulate this behavior of cause <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Lets have a quick look at a scenario:</p><p>So you write a function to <strong>add two numbers</strong> and return the sum. Lets call it <strong>sum():</strong></p><pre class="brush: php; title: ; notranslate">
function sum($a, $b){
return $a + $b;
}
echo sum(3,5); //8 <img src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  works
</pre><p>And then you decide you want a function to<strong> <em>&#8220;add&#8221;(concatenate)</em> two strings</strong>, lets call it <strong>concatenate()</strong>:</p><pre class="brush: php; title: ; notranslate">
function concatenate($a, $b){
return $a . $b;
}
echo concatenate(&quot;Hello &quot;, &quot;World&quot;); //Hello World
</pre><p>So now we have out two awesome functions that do exactly what we expect them to do. But now you figure you should just have one function, lets call it <strong>add()</strong> to do those two tasks depending on the parameters submitted. That&#8217;s where the problems begin with PHP. In Java for example you could just define two function with same name but that take different parameters. e.g: int <strong>function add(int a, int b)</strong> and another <strong>string function add(string a, string b)</strong>. In PHP we need to do some heavy lifting ourselves:</p><p>So the solution lies in the native functions <a
title="Function Overloading" href="http://www.php.net/manual/en/function.func-get-args.php">func_get_args()</a> and <a
title="Function Overloading" href="http://www.php.net/manual/en/function.func-num-args.php">func_num_args()</a>. PHP Lets you declare functions that take an arbitrary number of arguments/parameters and use <a
title="Function Overloading" href="http://www.php.net/manual/en/function.func-get-args.php">func_get_args()</a> and <a
title="Function Overloading" href="http://www.php.net/manual/en/function.func-num-args.php">func_num_args()</a> to retrieve and count the arguments respectively.</p><p>The solution:</p><pre class="brush: php; title: ; notranslate">
function add(){
  //Make sure that exactly two parameters are sumitted
  if(func_num_args() == 2){
    $args = func_get_args();
    $a = $args[0];
    $b = $args[1];
  }else{
    trigger_error(&quot;Incorrect parameter count for function &quot; . __FUNCTION__ . &quot;()&quot;, E_USER_ERROR);
  }
  /** Check if two integers where submitted **/
  if(is_int($a) &amp;&amp; is_int($b)){
    return sum($a, $b);
  }elseif(is_string($a) &amp;&amp; is_string($b)){
    /** Check if two strigns where submitted **/
    return concatenate($a, $b);
  }else{
    /** Otherwise give an error **/
    trigger_error(&quot;Incorrect parameter type for &quot; . __FUNCTION__ . &quot;()&quot;, E_USER_ERROR);
  }
}
echo add(&quot;Hello &quot;, &quot;World&quot;); //Hello World
echo add(5, 4); //9
echo add(&quot;Hello&quot;, 3);//Error
echo add(3, &quot;World&quot;);//Error
echo add(&quot;HELLO&quot;, NULL);//Error
</pre><p>I don&#8217;t think i&#8217;d ever use it really. Seems like a lot of work for something that you could do other quicker ways. But use it, don&#8217;t use it <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br
/> The function above is commented so just follow the comments if you don&#8217;t understand anything.</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/php/php-functionmethod-overloading.html/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Different Definitions of Quality</title><link>http://www.semicolon.co.za/web-development/different-definitions-of-quality.html</link> <comments>http://www.semicolon.co.za/web-development/different-definitions-of-quality.html#comments</comments> <pubDate>Mon, 09 May 2011 07:13:29 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=436</guid> <description><![CDATA[Came across a very interesting post on &#8220;Quality&#8221; by Paul-M-Jones post via the phpdeveloper.org feed(That you should subscribe to). Here a little extract from the post below. Read the full post. While the above analysis may be true, I realized later that I was approaching the problem from the wrong angle. It’s not that one [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/web-development/different-definitions-of-quality.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fweb-development%2Fdifferent-definitions-of-quality.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fweb-development%2Fdifferent-definitions-of-quality.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p>Came across a very interesting post on &#8220;Quality&#8221; by <a
href="http://twitter.com/#!/pmjones" target="_blank">Paul-M-Jones</a> post via the <a
title="PHP Developer" href="http://phpdeveloper.org" target="_blank">phpdeveloper.org</a> feed(That you should subscribe to). Here a little extract from the post below. <a
href="http://paul-m-jones.com/archives/1874" target="_blank">Read the full post.</a></p><p>While the above analysis may be true, I realized later that I was  approaching the problem from the wrong angle. It’s not that one cares  more about quality than the other.  Instead, it is that they have two  different definitions regarding project quality.</p><ul><li>The programmer’s “quality” relates to the what he sees and works with  regularly and is responsible for over time (the code itself).</li><li>The payer’s “quality” relates to the what he and the customers see  and work with regularly and are responsible for over time (what is <em>produced</em> by running the code; i.e., the product, not the program).</li></ul><p><a
href="http://paul-m-jones.com/archives/1874" target="_blank">Read the full post&#8230;</a></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/web-development/different-definitions-of-quality.html/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Hello World module in Drupal 6 Tutorial – Part 2</title><link>http://www.semicolon.co.za/mysql_tutorials/create-hello-world-module-drupal6-part2.html</link> <comments>http://www.semicolon.co.za/mysql_tutorials/create-hello-world-module-drupal6-part2.html#comments</comments> <pubDate>Sun, 06 Feb 2011 13:06:34 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Drupal]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=409</guid> <description><![CDATA[Hey all, welcome to part 2, a continuation of the Hello World module in Drupal 6 &#8211; Part 1 I know what you&#8217;re thinking: &#8220;A full 8 months later? wtf?&#8221;. If you werent thinking that then you are now. Or something along those lines. I apologise for the delay(if you can even call it that). [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/mysql_tutorials/create-hello-world-module-drupal6-part2.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fmysql_tutorials%2Fcreate-hello-world-module-drupal6-part2.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fmysql_tutorials%2Fcreate-hello-world-module-drupal6-part2.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p>Hey all, welcome to part 2, a continuation of the <a
href="http://www.semicolon.co.za/php/hello-world-module-in-drupal-6-part-1.html">Hello World module in Drupal 6 &#8211; Part 1</a> I know what you&#8217;re thinking: &#8220;A full 8 months later? wtf?&#8221;. If you werent thinking that then you are now. Or something along those lines. I apologise for the delay(if you can even call it that). Blah blah blah</p><pre class="brush: php; title: ; notranslate">{begin: excuse}
//TODO: enter excuses here
{end: excuse}</pre><p>Now that we&#8217;ve got that out of the way, Shall we then get to the <a
href="http://www.semicolon.co.za/wp-content/uploads/2011/02/semicontacts.tar.gz">Semicontacts Module</a> tutorial. Right.</p><p>In this tutorial we are going to learn the following</p><p>1. How to use the <a
href="http://api.drupal.org/api/group/database/6">Drupal Database Abstraction Layer</a>.<br
/> 2. How to use the <a
href="http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/7">Drupal Form API</a> to create and validate forms.<br
/> 3. How to use the <a
href="http://drupal.org/node/146843">Drupal Schema API</a> to create a database table during module installation.</p><pre class="brush: php; title: ; notranslate">NOTE: Please note that this tutorial is used for educational purposes only.&lt;br /&gt;
 It is nowhere near production ready. Also what we are doing here can be done&lt;br /&gt;
 without any coding at all using the &lt;a href=&quot;http://drupal.org/project/cck&quot;&gt;CCK module&lt;/a&gt;. This is just meant to show you actual Drupal Code</pre><p>Our module is an address book much like the one you have on your phone. It will require a first name, last name, phone number. These will then be saved in a database in a table called <strong>semicontacts</strong> that we will create.</p><p>We will also create a page to list all these contacts.</p><p>Okay less yada yada more code you say? Say no more. So were going to create module folder and the two required files like in part one.</p><p>So now I have a folder in sites/all/modules/ called <strong>semicontacts</strong>(the name of my module):</p><p>-sites/all/modules/semicontacts<br
/> &#8212;semicontacts.info<br
/> &#8212;semicontacts.module</p><p>Let&#8217;s start by telling Drupal about our module in the <strong>semicontacts.info</strong> file:</p><pre class="brush: php; title: ; notranslate">
; $Id$
name = Semicolon Contacts Module
description = Contact Management Module(CMM <img src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  )
core = 6.x
package = Semicolon
</pre><p>Now Drupal knows about our module. If you actually go into modules list you will see this new module.</p><p>Now lets edit the <strong>semicontacts.module</strong> file and add a page(tell Drupal the URL for the module), you will remember we do this by using a <a
href="http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_menu/6">hook_menu()</a> hook. If you remember in part 1, hooks naming follows nameofmodule_hookname() what does this mean for us?:</p><pre class="brush: php; title: ; notranslate">
&lt;?php
function semicontacts_menu(){
$items = array();
$items['semicontacts'] = array(
'title' =&gt; t('Semicontacts - Form'),
'page callback' =&gt; 'semicontacts_page',
 'access arguments' =&gt; array('access content'),
'type' =&gt; MENU_CALLBACK,
 );
 return $items;
}
</pre><p>As you can see the module will be accessible from the <strong>http://mysite.com/semicontacts</strong> page. The page call-back is the function that will be called when this URL is accessed. So lets go ahead and create that. This page will contain our form. We will use the Form API to create the form.</p><pre class="brush: php; title: ; notranslate">
function semicontacts_page($argument) {
    $content = &quot;Hello World! Wow It really works
    This is a simple module to save contacts to the database.
    Enter Contact Details.&quot;;
    $content .= drupal_get_form('semicontacts_form');
    return $content;
}
</pre><p>There&#8217;s our function. So we put a little into text at the top and we add a form to that using the <a
href="http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_get_form/6">drupal_get_form()</a> function, which takes a form function as a parameter. So we need to create this form function that will return our form.</p><pre class="brush: php; title: ; notranslate">
function semicontacts_form(){
 $form = array();
 //create a text field called firstname with label First Name
 $form['firstname'] = array(
 '#type' =&gt; 'textfield',
 '#title' =&gt; t('First Nmae'),
 );
 //create a text field called lastname with label Last Name
 $form['lastname'] = array(
 '#type' =&gt; 'textfield',
 '#title' =&gt; t('Last Name'),
 );
 //create a text field called phonenumber with label Phone Number
 $form['phonenumber'] = array(
 '#type' =&gt; 'textfield',
 '#title' =&gt; t('Phone Number'),
 );
 //create submit button
 $form['submit'] = array(
 '#type' =&gt; 'submit',
 '#value' =&gt; t('Save Contact'),
 );
 //return the form
 return $form;
}
</pre><p>The Form API makes creating our form simpler and cleaner. The form is declared as an array of arrays(the fields are themselves arrays). By the ways this function can be called whatever you want. As long you fetch the right form in the page function above.</p><p>So now we should have a form. Lets try access the page. Go to http://www.my-site.com/semicontacts You should be greeted with a form which at the moment does absolutely nothing. Try click submit. It should just redirect you to the same page.</p><p>Okay. Now lets get to the fun stuff. Lets create a table in our database called semiccontacts to store our contacts:</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE `semicontacts`.`helloworld_contacts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`firstname` VARCHAR( 255 ) NOT NULL ,
`lastname` VARCHAR( 255 ) NOT NULL ,
`phonenumber` VARCHAR( 255 ) NOT NULL
)
</pre><p>Copy sql query above and run in a mysql client(i use phpMyAdmin). Be sure you have already selected your drupal database.</p><p>Now we just need to create a function to save our form. We do this by implementing form api&#8217;s _submit() function</p><pre class="brush: php; title: ; notranslate">
function semicontacts_form_submit($form_id, &amp;$form_data){
 db_query(&quot;INSERT INTO semicontacts (firstname, lastname, phonenumber) VALUES ('%s', '%s', '%s')&quot;, $form_data['values']['firstname'], $form_data['values']['lastname'],  $form_data['values']['phonenumber']);
 drupal_set_message(t('Your contact has been saved to the database.'));
}
</pre><p>The data submitted by the form is stored in an array $form_data['values'] with field names as keys so to fetch the value of firstname field just $form_data['values']['firstname'], simple enough right? Yep.</p><p>In Drupal 7, We use the <a
href="http://api.drupal.org/api/drupal/includes--database--database.inc/function/db_insert/7">db_insert</a> to save our data. The API allows for method chaining, much like <a
href="http://ar.rubyonrails.org/">RUBY&#8217;s active record pattern</a> or Jqeury. Looks better and makes the code easier to follow.</p><p>So to save this in drupal 7 we would use:</p><pre class="brush: php; title: ; notranslate">
db_insert('semicontacts')-&gt;fields($form_data)-&gt;execute();
</pre><p>So now our form should be saving to the database. Try it now. Works? Yes? No? If it doesnt then something went wrong up there. You or i(i hope not) missed something.</p><p>Wait don&#8217;t we need to validate our form data? We do. Lets. Form validation is done using the form api _validate() function. It means our function will be called semicontacts_validate().</p><pre class="brush: php; title: ; notranslate">
function semicontacts_form_validate($form_id, &amp;$form_data){
 //var_dump($form_value);
 if(!is_string($form_data['values']['firstname'])|| empty($form_data['values']['firstname'])){
 form_set_error('firstname', t(&quot;Please Enter a valid First Name&quot;));
 }elseif(!is_string($form_data['values']['lastname']) || empty($form_data['values']['lastname'])){
 form_set_error('lastname', t(&quot;Please Enter a valid Last Name&quot;));
 }elseif(!is_numeric($form_data['values']['phonenumber']) || empty($form_data['values']['phonenumber'])){
 form_set_error('phonenumber', t(&quot;Please Enter a valid Phone Number&quot;));
 }
}
</pre><p>We used the the form_set_error function to set errors if any for the field we are currently validating. the method takes a fieldname and an error message. You will also notice like the submit function we did not have to call them. This is the beauty of hooks. They&#8217;re like that little kid in class with his hand up going &#8220;me,me,me, pick me sir&#8221;. And the class wont continue until they get picked. I thought that was deep. You should write that down <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><p>So hooks break drupal flow of execution cause drupal will first check if there are any relevant hooks in your module before continuing to the next task. So its almost like you modified the Drupal core without really needing to see the core code.</p><p>Okay now try submitting without entering any values. You should get the error messages we defined above.</p><p>But wait would&#8217;nt it be cool if we had a page to list contacts? Lets go ahead and do that.</p><p>Remeber that secontacts_menu function up there, the one that defines our modules urls? Yeah that one. Lets add another url there. Say&#8230; http://www.my-site.com/semicontacts/list</p><pre class="brush: php; title: ; notranslate">
function semicontacts_menu(){
$items = array();
$items['semicontacts'] = array(
'title' =&gt; t('Semicontacts - Form'),
 'page callback' =&gt; 'semicontacts_page',
 'access arguments' =&gt; array('access content'),
'type' =&gt; MENU_CALLBACK,
 );
 $items['semicontacts/list'] = array(
 'title' =&gt; t('Semicontacts - List'),
 'page callback' =&gt; 'semicontacts_list_page',
 'page arguments' =&gt; array(&quot;1&quot;),
 'access arguments' =&gt; array('access content'),
 'type' =&gt; MENU_CALLBACK,
 );
return $items;
}
</pre><p>Easy enough. If at this point you are thinking we need to create the call back function you are indeed correct young grasshoper <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> Here it is:</p><pre class="brush: php; title: ; notranslate">
function semicontacts_list_page($argument) {
 $content = t(&quot;List of contacts&lt;br /&gt;&lt;br /&gt;&quot;);
 $content .= t(l(&quot;Add New Contact&quot;,&quot;semicontacts&quot;));
 $result = db_query('SELECT c.id, c.firstname, c.lastname, c.phonenumber FROM semicontacts c order by
lastname asc');
 $content .= &quot;&lt;ul&gt;&quot;;
 while ($contact = db_fetch_object($result)) {
 $content .= &quot;&lt;li&gt;$contact-&gt;lastname, $contact-&gt;firstname - $contact-&gt;phonenumber&lt;/li&gt;&quot;;// Perform
operations on $node-&gt;body, etc. here.
 }
 $content .= &quot;&lt;/ul&gt;&quot;;
 $content .= l(t(&quot;Add New Contact&quot;),&quot;semicontacts&quot;);
 return $content;
}
</pre><p>At this point our module is fully functional. But we dont wan&#8217;t the end-user to always run a sql command to create the semicontacts table. We need this to happen during module installation. Enter the</p><p>semicontacts.install module with the Schema API Create a new file in the semicontacts folder called semicontacts.install with the following contents:</p><pre class="brush: php; title: ; notranslate">
&lt;?php
//$Id
/**
 * Implement hook_schema()
 */
function semicontacts_schema(){
 $schema['semicontacts'] = array(
 'description' =&gt; t('Store .'),
 'fields'=&gt;array(
 'id'=&gt;array(
 'type'=&gt;'serial',
 'unsigned'=&gt;TRUE,
 'not null'=&gt;TRUE
 ),
 'firstname'=&gt;array(
 'type'=&gt;'varchar',
 'length'=&gt;255,
 'default' =&gt; '',
 'not null'=&gt;TRUE
 ),
 'lastname'=&gt;array(
 'type'=&gt;'varchar',
 'length'=&gt;255,
 'default' =&gt; '',
 'not null'=&gt;TRUE
 ),
 'phonenumber'=&gt;array(
 'type'=&gt;'varchar',
 'length'=&gt;255,
 'default' =&gt; '',
 'not null'=&gt;TRUE
 ),
 ),
 'primary key'=&gt;array(&quot;id&quot;),
 );
 return $schema;
}
/**
 * Implement hook_install()
 */
function semicontacts_install(){
 drupal_install_schema('semicontacts');
}
/**
 * Implement hook_uninstall
 */
function semicontacts_uninstall(){
 drupal_uninstall_schema('semicontacts');
}
</pre><p>This file contains implementation of 3 drupal hooks, <a
href="http://api.drupal.org/api/drupal/developer--hooks--install.php/function/hook_install/6">hook_install()</a>, <a
href="http://api.drupal.org/api/drupal/developer--hooks--install.php/function/hook_uninstall/6">hook_uninstall()</a>, <a
href="http://api.drupal.org/api/drupal/developer--hooks--install.php/function/hook_schema/6">hook_schema()</a>.</p><p>hook_install() is used to run any configuration during install like say creating a database table for our module.</p><p>hook_uninstall() is used to run any configuration during install like say deleting a database table for our module.</p><p>hook_schema() is where we define our database table. The fields about are clearly self explanatory. Check a full list and description.</p><p>To test your new install file you must remove the module from Drupal system table. This makes sure that Drupal will run hook_install() since this only runs the first time a module is installed. To do that I usually just run this query</p><pre class="brush: sql; title: ; notranslate">
delete from system where name =&quot;semicontacts&quot;
</pre><p>Not the best way, not even advisable. to execute queries directly on the database, but it should suffice since we are on our localhost.</p><p>So now you need to package your module in to a .tar.gz file. If you are on windows download <a
href="http://www.7-zip.org/download.html">7zip</a>.<br
/> To create the file just right click on the semicontacts folder, go to the 7zip submenu and click on &#8220;add to archive&#8221;, on the window that pops up,choose &#8220;tar&#8221; format. you should have a newfile semicontacts.tar. Right click this file and do the same as above but choose gzip as the archive format. Good luck.</p><p>Comments welcome positive and negative. I apologise for the lenghth of the tutorial, was just so much stuff to cover. We are going to improve and extend semicontacts in the next tutorial(Part 3)</p><p><a
href="http://www.semicolon.co.za/wp-content/uploads/2011/02/semicontacts.tar.gz">Download Source Code</a></p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/mysql_tutorials/create-hello-world-module-drupal6-part2.html/feed</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Why your developer sucks</title><link>http://www.semicolon.co.za/web-development/why-your-developer-sucks_.html</link> <comments>http://www.semicolon.co.za/web-development/why-your-developer-sucks_.html#comments</comments> <pubDate>Tue, 07 Dec 2010 19:55:09 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=386</guid> <description><![CDATA[1. He/She has a &#8216;God&#8217; Complex Web Development by its very nature is a creative field. It&#8217;s a field were the developer invests themselves. The Developer looks at a problem and solves it the best way they know how. If anybody dares question how the problem was solved, it is considered as a personal attack [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/web-development/why-your-developer-sucks_.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fweb-development%2Fwhy-your-developer-sucks_.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fweb-development%2Fwhy-your-developer-sucks_.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><h2>1. He/She has a &#8216;God&#8217; Complex</h2><p><a
href="http://www.semicolon.co.za/wp-content/uploads/2010/12/dwight.jpg"><img
class="alignright size-medium wp-image-391" title="dwight" src="http://www.semicolon.co.za/wp-content/uploads/2010/12/dwight-218x300.jpg" alt="" width="218" height="300" align="right" /></a>Web Development by its very nature is a creative field. It&#8217;s a field were the developer invests themselves. The Developer looks at a problem and solves it the best way they know how. If anybody dares question how the problem was solved, it is considered as a personal attack on the developer skills. I see this in myself every day. When somebody fails at completing a task with the software, the natural response for a developer is &#8220;god you are the most retarded person I know&#8221;. But of cause this is not true. <a
href="http://en.wikipedia.org/wiki/Donald_Norman" target="_blank">Donald Norman</a> in his Book <a
href="http://books.google.co.za/books?id=FRd2QgAACAAJ" target="_blank">&#8220;The Design Of Everyday things&#8221;</a> says &#8220;If an error is possible, somebody will find a way to make it&#8221; (Not a word for word quote, Great book by the way). And it’s not because they are stupid, it&#8217;s because your application allows for that error/failure to occur. Design for errors. Developers should never test their own software.</p><h2>2. He/She worships his/her Code</h2><p>This one is closely tied to the number one above. Your developer loves his/her code, therefore it is the best code it can be, it will never need re-factoring, if anybody writes it different they are stupid. This sort of attachment leads to low quality work and developers that don&#8217;t grow. Be wary of developers that think they write the best code in the world.</p><h2>3. 70% coding, 30% planning</h2><p>Most developers get a problem and the first thing they do is start coding. Adding and removing stuff as they go along. Creating new functions as they go along. But the truth is if they took more time in planning, their development time is decreased dramatically. And the quality and structure of their work is improved. So aim for a 70% planning, 30% coding. **This is just my personal opinion.</p><h2>4. Bad time estimates</h2><p>Your developer will usually go over their time estimates; the trick is never believe a developer&#8217;s time estimate <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> , cause we lie. And we don’t lie to you, we lie to ourselves. And we believe it. The lie to you is just a by-product. We over estimate our skills and we live in a purple fluffy world with Smurfs and Teletubbies where everything goes according to plan and there are not unexpected errors or events. Giving time estimates is a skill on its own and a developer does not have that skill <a
href="http://www.semicolon.co.za/uncategorised/bad-bosses-weve-all-had-some.html" target="_blank">as i had to learn</a> it might make them unhappy with their job. Again planning goes a long way. Also be wary of the &#8216;project managers from hell&#8217; pressurising your developers unnecessarily to score some points with you.</p><h2>5. No desire to learn new things</h2><p>A developer should always be growing, improving, finding new/better ways of doing the same stuff he&#8217;s been doing for years. And there is nothing worse than a developer who cannot learn new things by themselves. Team work is fine and all, but a developer that cannot learn by themselves is going to cost you time and money and frustrate your development team. I happen to think when it comes to learning a new system, discovering things on your own is the best way to learn, breaking things and fixing them and finding out why they broke, etc. I have my own little list on <a
href="http://www.semicolon.co.za/css_tutorials/how-to-become-a-web-developer.html">What a Web Developer should know.</a></p><h2>6. You give him unclear instructions</h2><p>Never tell a web developer &#8220;Go build me a rocket please&#8221;, you will get a flying saucer. Be specific with what you want. It is best to get a trained business analyst if you cannot do this yourself, someone who will understand the requirements of the users and the desired behaviour and outcomes of the system. So yes your developer sucks because you think you speak &#8216;developer&#8217; but are you are just human&#8230;or are you dancer <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /></p><h2>7. Being a perfectionist(Thanks James)</h2><p>I had missed this one but thanks to <a
href="http://twitter.com/jamiebarrow" target="_blank">@jamiebarow</a> for pointing this out. &#8220;I am a perfectionist&#8221;, Yes it was cute he/she said it in his/her interview. Its great to have great attention to detail, but too much attention to details can cripple a project. Some developers write and re-factor at the same time(I feel an infinite loop coming on). Which sorta takes us back to number 2 above. Code worshipping is blasphemy.</p><h2>8. He/She has no idea WTF he/she&#8217;s doing</h2><p>Sometimes you just get stuck with a developer that has no idea what they are doing, just good old fashioned &#8216;stupid&#8217; for lack of a better word. I’m kidding nobody is stupid, but some developers should have been mechanics. Just saying. <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> . James says not knowing is fine as long you are willing to learn. True story.</p><h2>9. Conclusion</h2><p>Although this sounds like it’s meant for your boss, Its really meant for you. Stop sucking at your job. Be approachable, be sincere, be wrong, be willing to help others get better. Understand you are not perfect and quite possibly might suck. As long as you are willing to learn and driven. I’m still working on some of these things myself. Will keep you posted. I wrote <a
href="http://www.semicolon.co.za/css_tutorials/how-to-become-a-web-developer.html">another article</a> on <a
href="http://www.semicolon.co.za/css_tutorials/how-to-become-a-web-developer.html">How to become a web developer.</a> Take a look and let me know. Enjoy.</p><p>Adios<br
/> Tali</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/web-development/why-your-developer-sucks_.html/feed</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Installing Sphinx Full-Text Search on linux</title><link>http://www.semicolon.co.za/mysql_tutorials/installing-sphinx-full-text-search-on-linux.html</link> <comments>http://www.semicolon.co.za/mysql_tutorials/installing-sphinx-full-text-search-on-linux.html#comments</comments> <pubDate>Tue, 24 Aug 2010 07:55:10 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=340</guid> <description><![CDATA[Sphinx is a full-text search engine. It currently works with MySQL and PostgreSQL better known as Postgres. The two most popular options when its comes to open source databases if not databases in general. Both MySQL and PostgreSQL have full-text search capabilities. So why bother with sphinx? Control &#8211; With sphinx you get more control [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/mysql_tutorials/installing-sphinx-full-text-search-on-linux.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fmysql_tutorials%2Finstalling-sphinx-full-text-search-on-linux.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fmysql_tutorials%2Finstalling-sphinx-full-text-search-on-linux.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p><a
href="http://www.sphinxsearch.com/">Sphinx</a> is a <a
href="http://en.wikipedia.org/wiki/Full_text_search">full-text search</a> engine. It currently works with MySQL and PostgreSQL  better known as Postgres. The two most popular options when its comes to open source databases if not databases in general. Both MySQL and PostgreSQL have <a
href="http://en.wikipedia.org/wiki/Full_text_search">full-text search</a> capabilities. So why bother with sphinx?</p><ol><li><strong>Control</strong> &#8211; With sphinx you get more control over filtering, for example you can set a certain column to have a higher weight by using just one function</li><li><strong>Speed</strong> &#8211; Sphinx is about 40-100 times faster at indexing. It&#8217;s also up a 1000 times faster at searching than MySQL and Postgres depending on the data.</li><li><strong>Relevance</strong> &#8211; You get much more relevant results with sphinx. i.e Accuracy is greatly improved</li><li><strong>Scalability</strong> &#8211; Sphinx indexes can be stored on distributed servers. You can also search multiple sites at one go.</li></ol><p><span
id="more-340"></span>I could go on but those are probably the most important reasons to switch to Sphinx SE. Besides the fat that there are <a
href="http://sphinxsearch.com/powered.html">loads of &#8220;big&#8221; sites</a> already using it. The Api currently supports PHP, Perl, Ruby, and Java.</p><p>So down to the important bits. Btw this tutorial is based on Sphinx 0.9.9 but it shouldn&#8217;t matter</p><p>Step 1: Download sphinx<br
/> The latest stable release at the time of this article is Sphinx 0.9.9 (r2117; Dec 02, 2009) I prefer to use wget so in the terminal I type</p><pre class="brush: plain; title: ; notranslate">$ cd ~
$ mkdir sphinxtemp
$ cd sphinxtemp
$ wget http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz
</pre><p>Step 2: Unzip Sphinx</p><pre class="brush: plain; title: ; notranslate">
$ tar -xvf sphinx-0.9.9.tar.gz
$ cd sphinx-0.9.9
</pre><p>Step 3: Install Sphinx</p><p>Ones in the directory sphinx-0.9.9 type</p><pre class="brush: plain; title: ; notranslate">
$ ./configure
</pre><p>At this point you might get an error like this</p><pre class="brush: plain; title: ; notranslate">
**
ERROR: cannot find MySQL include files.
Check that you do have MySQL include files installed.
The package name is typically 'mysql-devel'.
If include files are installed on your system, but you are still getting
this message, you should do one of the following:
1) either specify includes location explicitly, using --with-mysql-includes;
2) or specify MySQL installation root location explicitly, using --with-mysql;
3) or make sure that the path to 'mysql_config' program is listed in
 your PATH environment variable.
</pre><p>You need to install mysql-devel. I think it also goes my different names also. I think Ubuntu calls it libmysqlclient15-dev asdf</p><p>In Centos linux all i had to was type</p><pre class="brush: plain; title: ; notranslate">
$ yum install mysql-devel
</pre><p>Ubuntu 9.04</p><pre class="brush: plain; title: ; notranslate">
$ sudo aptitude install libmysqlclient15-dev
</pre><p>After install the above package, the following commands</p><pre class="brush: plain; title: ; notranslate">
$ ./configure
$ make
$ make install
</pre><p>Voila! You now have sphinx installed</p><p>There will be three new binaries stored here /usr/local/bin/ namely:</p><ul><li> indexer &#8211; this is the indexer you will run with configuration settings to index a database</li><li> searchd &#8211; this is the search damon that will be listening to connection from your script(php, phython&#8230;), it has to be running for anything to happen</li><li>search &#8211; this is used to run search in the terminal</li></ul><p><strong>Step 4: Configure Sphinx</strong></p><p>The installation will also create a bunch of files in <strong>/usr/local/etc</strong><br
/> <em>example.sql, sphinx.conf.dist, sphinx-min.conf.dist</em></p><p><strong>SubStep 4.1 Create Sphinx config file</strong><br
/> Copy /usr/local/etc/sphinx-min.conf to /usr/local/etc/sphinx.conf (In the same folder)</p><pre class="brush: plain; title: ; notranslate">
cp /usr/local/etc/sphinx-min.conf /usr/local/etc/sphinx.conf
</pre><p><strong>SubStep 4.2 Create Index</strong><br
/> Open up /usr/local/etc/sphinx.conf in you favourite editor(vi, gedit, kate, whatever).<br
/> Configure this part in the source to represent your server configuration</p><pre class="brush: plain; title: ; notranslate">
	sql_host				= localhost
	sql_user				= test
	sql_pass				=
	sql_db				        = test
</pre><p><em><strong>sql_query</strong></em> is what you want the <strong><em>indexer</em></strong> to index.</p><p>So say you have a table of books like this in your database:</p><table><tbody><tr><th>book_id (pk)</th><th>book_title</th><th>book_description</th></tr><tr><td>1</td><td>Blogging 101</td><td>Blogging 101 is the bestest blogging book ever. Awesome.</td></tr><tr><td>2</td><td>PHP Unleashed</td><td>PHP development book for total beginners</td></tr><tr><td>3</td><td>The Chicken and the Pig</td><td>This is a book about an unlikely love affair between a pig and a chicken</td></tr></tbody></table><p>Assuming you want to index all columns:</p><pre class="brush: plain; title: ; notranslate">
sql_query				= select * from books
</pre><p>and</p><pre class="brush: plain; title: ; notranslate">
sql_query_info			= select * from books where book_id=$id
</pre><p><strong>SubStep 4.3 Run the Indexer</strong></p><p>To run the indexer just type</p><pre class="brush: plain; title: ; notranslate">
$ indexer
</pre><p>make sure you stop the search daemon first like this</p><pre class="brush: plain; title: ; notranslate">
$ searchd --stop
</pre><p>In the Linux terminal. It should index at this point. If it doesn&#8217;t you missed something. And it will give an error message. Good luck.</p><p>After Indexing has completed start the Search Daemon again</p><pre class="brush: plain; title: ; notranslate">
$ searchd
</pre><p>To test sphinx, just type search  term e.g:</p><pre class="brush: plain; title: ; notranslate">
$ search chicken
</pre><p>This should return one row. &#8220;The chicken and the pig&#8221;</p><p>I will be writing a more detailed tutorial on the PHP API so you can integrate sphinx into your php code. The php api is</p><p>For now, Adios. <img
src='http://www.semicolon.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br
/> Tali</p><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/mysql_tutorials/installing-sphinx-full-text-search-on-linux.html/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>header() &amp; exit(). BFFs</title><link>http://www.semicolon.co.za/php/header-exit-bffs.html</link> <comments>http://www.semicolon.co.za/php/header-exit-bffs.html#comments</comments> <pubDate>Fri, 28 May 2010 10:58:26 +0000</pubDate> <dc:creator>Talifhani Luvhengo</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Web Development]]></category> <guid
isPermaLink="false">http://www.semicolon.co.za/?p=307</guid> <description><![CDATA[The PHP header(&#8220;Location: /&#8221;) function sends a redirect header to the browser. So thing about PHP is that it only sends headers to the browser once the page is parsed on the server. header(); will not stop the execution of code that comes after it. The script will continue to execute until it reaches the [...]
No related posts.]]></description> <content:encoded><![CDATA[<div
class="plus-one-wrap"><g:plusone href="http://www.semicolon.co.za/php/header-exit-bffs.html"></g:plusone></div><div
class="tweetmeme_button" style="float: left; margin-right: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fheader-exit-bffs.html"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.semicolon.co.za%2Fphp%2Fheader-exit-bffs.html&amp;source=talifhani&amp;style=normal&amp;service=bit.ly&amp;service_api=R_4b80d814c1a5ca0e96d52db3fd58f4a2&amp;b=2" height="61" width="50" /><br
/> </a></div><p>The PHP <a
href="http://php.net/manual/en/function.header.php">header(&#8220;Location: /&#8221;)</a> function sends a redirect header <strong>to the browser</strong>. So thing about PHP is that it only sends headers to the browser once the page is parsed on the server. header(); will not stop the execution of code that comes after it. The script will continue to execute until it reaches the end. At which point it will then redirect.</p><p>Take this example</p><pre class="brush: php; title: ; notranslate">
//Do stuff
//redirect to another page
if($user_loggedin){
    header(&quot;Location:  /login.php&quot;);
}
$_SESSION['page_views'] += 1;
/*
Display this page's content
*/
</pre><p>Although its quite clear to a human that if this user is not logged in, we should redirect to <em>login.php</em>, this script will actually continue to execute to the end and then redirect. which means although the page is never really viewed. it will still increment the $_SESSION['page_views'] variable.</p><p>So the headers are only sent back to the browser once PHP has completed rendering/building the page. At which point the browser redirects to the <em>login.php</em>. So to get the desired effect all you have to do is add a <a
href="http://www.php.net/manual/en/function.exit.php">exit()</a> function to stop script execution and force PHP to send the page to the browser as is.</p><p>So the code will now look like this:</p><pre class="brush: php; highlight: [8]; title: ; notranslate">
//Do stuff
//redirect to another page
if($user_loggedin){
    header(&quot;Location:  /login.php&quot;);
    //stop executing the script
    exit();
}
$_SESSION['page_views'] += 1;
/*
Display this page's content
*/
</pre><p>What I do is just write a function to do both steps like this:</p><pre class="brush: php; title: ; notranslate">
function redirect($url){
        header(&quot;Location: $url&quot;);
        exit();
}
</pre><p>usage:</p><pre class="brush: php; title: ; notranslate">
redirect(&quot;/login.php&quot;);
</pre><p>No related posts.</p>]]></content:encoded> <wfw:commentRss>http://www.semicolon.co.za/php/header-exit-bffs.html/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> </channel> </rss>
