Unrealistic Expectations in Job Posting

A funny Craigslist post (now deleted):

Web Designer/Programmer Needed
Reply to:
Date: 2007-11-19, 4:51PM EST
Must have specific database and Web-development experience to include in-depth database management and Web design services. Experience with government clients providing extensive data management and document tracking support a plus. Must have strong computer programming skills across a wide range of platforms/software programs to include:

• PHP5
• ColdFusion 5, ColdFusion MX
• Classic ASP, ASP.NET
• Visual Basic, VB.NET
• Adobe Flex
• JavaScript and VBScript
• Zend Studio
• ColdFusion Studio
• Visual Studio .NET
• Dreamweaver MX
• Front Page
• Acrobat PDF
• Content Management
• Photoshop / Image Ready
• Quark Xpress
• Flash MX
• Fireworks MX
• SQL Server 2005
• Access
• Oracle
• Paradox
• Informatica Data Analyzing and Procedural Mapping
• PC (Windows XP)
• MAC (OS X Tiger)
• Novell Netware5
• Internet Information Server 5
• SQL Server
• MS Windows Server 2003
• ColdFusion Server & Administrator
• Microsoft Office User Specialist
• Corel OfficeSuite

Please email resume and links to websites you have created or on which you have collaborated, to be considered.

* Location: Williamsburg Area
* Compensation: Negotiable
* Telecommuting is ok.
* This is a part-time job.
* This is a contract job.
* OK to highlight this job opening for persons with disabilities
* Principals only. Recruiters, please don’t contact this job poster.
* Please, no phone calls about this job!
* Please do not contact job poster about other services, products or commercial interests.

That’s like pretty much every single web technology plus random experience with Corel.



Today, I wanted to go over a relatively simple MySQL feature that a lot of people don’t understand: SQL_CALC_FOUND_ROWS. To use this mystical keyword, simply put it in your query right after the SELECT statement. For example:

SELECT * FROM USER WHERE id > 10 LIMIT 2,1 --see just second record



This won’t change your results. It may, however, make your query run slower than when you select just one row the regular way. What this statement does is tell MySQL to find out just how many total records exist that match your criteria (in this case, where id is bigger than 10). For example, let’s assume that the user table has 100 records that have an id bigger than 10, then the query will take as long as it would have taken for the engine to find those 100 records.

The returned result will still be one the records you are expecting (in this case, the second record it found). But here is where the magic starts: If the very next query you run is a special select statement, you will have access to the total that was found. As in:

SELECT FOUND_ROWS(); --returns 100

The MySQL documentation on this subject says:

[SELECT FOUND_ROWS()] returns a number indicating how many rows the first SELECT would have returned had it been written without the LIMIT clause. In the absence of the SQL_CALC_FOUND_ROWS option in the most recent SELECT statement, FOUND_ROWS() returns the number of rows in the result set returned by that statement.

No matter what your LIMIT clause looks like (such as LIMIT 10, 1), this second query will still return the same number (in this example, 100). Why is this useful? Pagination. Often times, beginners (including me a few years ago) are stuck doing something like this:

SELECT count(*) FROM USER WHERE id > 10 --figure out how many total records there are
SELECT * FROM USER WHERE id > 10 LIMIT 50, 1 --get to record #50

People do this because you need the total to know if other matching results exist or what the last page number is.

This requires the engine to run the same query twice. This can be disastrous in cases where that query already takes a very long time to run. By including SQL_CALC_FOUND_ROWS, the overhead of running that count is grouped up with the process of actually retrieving the row of interest. So while the initial query might take a little longer to run than if you hadn’t tried to do a count, it is definitely faster than running the same query twice.

To take this to the next level, your pagination code should omit the use of SQL_CALC_FOUND_ROWS in subsequent page loads by caching the total count in the URL or session.

Happy hunting!


A Great Web Developer is a Great Application Developer

After being a part of the developer hiring process for a while now, I have begun to see what distinguishes an exceptional web developer (the ones that get hired faster than we can even make an offer) and everybody else. Things have changed since 1995 – web development requires actual knowledge of programming!

The problem is that people think web development is somehow easier than other types of development. Nothing is inherently easier about developing an application in PHP than in C++. While I could accuse people who say this as being naive, the truth is that web developers themselves seem to hold this as the truth. In order to excel at being a web developer, one must understand how to develop an application. In other words, there are very different skills required in programming something like Facebook or Digg than for updating Mom’s store website.

First, you must actually understand object oriented programming (OOP). Everybody these days says they “know” OOP. I don’t mean “you read about it in a book” or that you can use a class when necessary; I mean being able to write extensible, modular libraries. This takes time and practice. When people first begin writing classes, they mistake the process for “grouping up functions under one class name in one file.” This is dead wrong and actually counter productive in some cases.

Classes are about automation and simplification. The classic analogy for OOP is a car because it has many parts that make it a whole. But just like the driver has no idea what a crank shaft, piston, or fuel injector does, people using your class should have no idea (nor need to learn why) about the inner workings of your class. All they need to know is that calling one of the few public methods (turn_ignition(), step_on_pedal(), steer()) does a whole lot of cool stuff behind the scenes that makes their life easier. And just like how you wouldn’t want the entire car engine welded together (instead of using bolts and screws), you shouldn’t write humongous class methods that do 1000 things — break it up into digestible parts so that other people can enhance just the pieces they want (see “overloading” below).

When you design a class, you start by listing out things that the class will be used for. Then, you figure out the lowest common denominators between these actions to remove “special, one time cases.” You now have a list of your primary public functions. Everything else in your class should pretty much remain protected or private (discretion is learned with experience). The entire point is that classes are not a group of similar functions, but rather a single conceptual unit.

And when you’re all done with understanding why object oriented programming exists, you must then learn to use Inheritance, and Overloading (some languages) and Interfaces.

Second, you must understand and demonstrate competency with design patterns. At the very least, you should be aware of the Singleton and Factory patterns, which are very commonly used, and for (arguably) good reasons. Knowledge of basic design patterns goes a long way because a time will come when you may need to borrow from one of these concepts when developing your web application. It also means you have a wider exposure to the different types of architectures available to someone writing a library or application.

Last, you must understand scaling issues in growing web applications and how to resolve them. This is probably the rarest trait, but if you have it, you will shine like a rock star. It is important to realize that certain operations are much more costly than others. In today’s world, the CPU is rarely the bottleneck, but there are still bottlenecks. A common instance of this problem is when Word Press blogs go offline because it is slammed by a spike in traffic. That said, the most common type of bottleneck involves the database and often manifests in one of three ways:

  • Each query sent to the database involves some small amount of lag between the web server and the database server. Hundreds of queries on a page will slow down your page loads. On high traffic pages, one less query means thousands of queries a second. Make sure you learn how to do JOIN statements.
  • Each query must use an index in the database. Without this index, a query looking at a large table will bottleneck the hard drive (because it has to search large portions of the disk). Learn how to use the MySQL command: explain.
  • Database tables using MyISAM (instead of InnoDB) risk facing table locking issues. When you run a big or complex update on MyISAM, no other updates can occur on that table until the first one is done. If that table is very large, this may mean someone’s page sits there and loads for a long time (or times out). Typically, one should use a transactional database such as InnoDB.

Other types of common scaling issues are:

  • Session management on the database instead of letting PHP handle it. This is an issue because any large web application has more than one web server which means when a person hits a new page they might be loading from a different web server each time.
  • Managing files generated on the server – such as when a user uploads a file. The issue here is that if a file is created on one server (in a cluster of 100), how do the other servers know it exists? Obviously the solution is to somehow centralize this with a synchronization process or store all of the files somewhere else.
  • How queries can start acting different (much slower) when your tables reach 1M+ rows without proper precautions. Larger tables change things because indexes sometimes stop getting used or slowness that wasn’t apparent before is now very noticeable. (A book could be written here…)

Merely reading and understanding these issues has put you ahead of a bunch of people out there. 🙂

In conclusion, you must re-think the “web developer” as an application developer that happens to work in a browser. I often hear the excuse that these types of advanced concepts can’t be readily applied in small-time applications (such as a simple store-front), but I believe this is simply not true. Virtually every site requires a database connection or a template system (for easy inclusion of header/footer files). Database abstraction and template systems are probably the single best place to use OOP concepts. It simply makes no sense that one would use the raw mysql_query() function in any website, even if it’s just Mom’s baby pictures. Putting these ideas in classes reduces security vulnerabilities and makes development much faster. If the notion of abstracting templates or databases is totally foreign to you, I suggest you start by looking at Smarty or EzSQL.

Happy studying. 🙂


Why Being Hard to Replace is Bad

I read something I’ve always followed without realizing exactly why:

Don’t be irreplaceable; if you can’t be replaced, you can’t be promoted.

I once worked with two programmers who told me they purposely wrote convoluted code. When I asked why they would do that, they replied, “Job security.” I always wondered why that company let its employees do that despite the impending likelihood that they would eventually quit and leave their mess for someone else to clean up.

Ever since then, I’ve always advocated for strict adherence to coding standards and frequent code ownership swapping. I’d like to add to the advice:

Nobody will choose to promote an individual who screws the company over – on purpose – on a daily basis.

I thought that was a neat tip to share on a Friday. 🙂


Maybe Google Wanted to be Sued: YouTube and Plan B

No matter how you spun it, a lawsuit was waiting to pounce on YouTube. And when the lawsuit came, it would be from multi-billion dollar media conglomerates. Worst of all, people feared it would trigger a landslide of more lawsuits. Even still, Google bought YouTube. And now the billion dollar war has begun.

I wondered: Maybe Google actually wanted to be sued.

Backroom Discussions

First of all, in a perfect world, no, Google wouldn’t want this. And Google, hoping that the world is close enough to perfect, did buy YouTube. But somewhere during discussions, someone must have asked, “How is this different from Morpheus and Kazaa? Won’t we be sued into oblivion?”

The smart lawyers at Google probably mentioned something about the DMCA, but honestly, would you want to buy a company that would be hated, constantly, by the very people who own the content that keeps you afloat? Or better, how will such a site remain #1 if there is a (Edit: added link) unified effort by content owners to either displace or destroy you? Most of all, media companies, who have significant clout and money, wouldn’t let YouTube host their content for free without a fight. There was more to this purchase than meets the eye.

No matter how you look at it, the purchase came with a lot of legal risk. I believe nobody at Google is surprised that Viacom is suing and wants $1 billion, A.K.A. most of the sum Google paid for YouTube. This is all part of the expected road map in owning YouTube.

So plan A was to hope people would be nice and look the other way. That worked for a year so far, and Google hoped it would continue. Plan B was to get sued.

This isn’t any ordinary “get sued and win” plan. Waiting to get sued so you can win in court is a defensive move for most companies. But for Google, this is preemptive. This is about Google defending YouTube, instead of YouTube defending YouTube.

Why Getting Sued is a Preemptive Strategy

Let’s pretend that YouTube was not bought out because talks got delayed. Then realize that it would have probably been sued a lot sooner by a lot more people. Investors would flee and nobody would want the company now. If YouTube goes broke, that would have likely pushed Myspace Video to #1, giving News Corp a huge edge since it happens to own Fox Entertainment. Myspace Video would become whatever was in the best interest of Big Media. Probably a DRM infested piece of crap that sued its users for uploading copyrighted material.

Myspace is #2(Edit:) If you don’t think Myspace would have hopped into the throne, you may want to see this recent report that shows how Myspace video is #2 in the video market. And as the trend goes, Myspace is actually losing share in the video market (3% between December 2006 and January 2007). Seeing as how 16% of all YouTube traffic comes from Myspace, you can’t say YouTube isn’t causing serious harm to Myspace videos, keeping it from becoming #1.

On the other hand, if YouTube didn’t go broke and fought the lawsuits, imagine if they had lost. Myspace Video gets to keep whatever edge it has, but virtually every other video site on the Internet becomes illegal overnight. Thousands of user records and IP addresses would get subpoenaed, and video sharing dies in one fell swoop.

Why Does Video Sharing Matter to Google?

What’s the next big thing on the net? Video. Google cares what happens in video sharing because it wants a slice of the video ad market. It doesn’t want to just be in the market, it wants to own it like it owns text ads. But that’s not the whole answer.

Google bought YouTube because it wanted to make sure of three things:

  1. Google has first dibs for video ads on the biggest video site on the Internet
  2. YouTube remains legal
  3. Expand and protect current fair use related provisions involving copying intellectual property

The first point is obvious, and the second point feeds into point #1.

But the third point is the most important for Google. If YouTube were to lose a lawsuit for hosting intellectual property, it would severely weaken Google’s position in a variety of current and future endeavors. Any aspirations Google has of someday crawling and indexing video content (nope, they don’t have this technology yet) would now be in legal limbo. It would also potentially re-introduce new arguments against their Google Image Search. And their book search program might suffer a similar fate once the YouTube precedent settles in. Google, being a company that spiders and indexes (stores) massive amounts of copyrighted information, would now be in serious legal jeopardy.

YouTube is Google’s Future

Thus, Google not only threw money at YouTube: it threw its lawyers at YouTube too. Google’s lawyers are some of the most well-versed copyright lawyers in the world since so many of their lawsuits deal with that issue.

The goal here is simple. Google wants to own the #1 video sharing site (completely legal), own 100% of the ads on that site, and clarify many currently-ambiguous copyright issues in their favor. If all of that goes as planned, the $1.5 billion paid to YouTube was a small price to pay. But if they had never gotten involved, the potential losses were far greater than a billion or two. Since Google has a market capitalization of over $130 billion, even a dip of 1% means losses of over $1 billion. But if entire sections of their business model became legally uncertain, you can bet they’d lose a lot more than 1%, especially with their insanely high P/E ratio (the ratio between what their stock is worth and how much they make).

By fighting a lawsuit, Google gets to prove the legitimacy of Internet video distribution – something that will probably never flourish under the “old media” regime. Unfortunately for them, the DMCA protects site owners from liability of what its users do — or at least that’s the general interpretation. Letting YouTube fight this battle alone with their own lawyers might have resulted in a very public and unnecessary loss that would have crippled Google’s video ambitions and possibly caused collateral damage to a bunch of related industries (especially search). This would have forced everybody to play by the conglomerates’ rules, and taken anyway any guarantee of Google getting any cut of the video ad pie. Video sharing needs this clarification before it can move forward. And if Google legitimizes it, they will have the biggest video site on the web for their video ads to play.

So let’s ask ourselves again: would Google pay $1.5 billion so it can fight the lawsuit on behalf of YouTube? Now that I think about it, it seems like a wise long term move.


9:01AM 3/22/2007: I’m on Slashdot. I think I survived the Slashdot Effect!


Five Things New First Time Employees Should Know

Just out of college? New to the workforce? Here’s five tip that you should keep in mind.

  1. Assume the world is tiny. Perhaps the biggest eye-opener is just how small the working world is. People in the same industry routinely work together at different companies over their career. But this also means your reputation at one company will likely follow you, and the likelihood of this increases as you work at more places. It doesn’t just stop there. Managers and executives at companies often know each other through their careers. This means one bad piece of history might haunt you at several potential jobs in the future. As such, don’t burn bridges. Even if you are the guy firing somebody, be nice. You never know if next time they’ll be your boss (no, seriously, this is more common than you think).
  2. Respect everybody, especially those below you. This sounds obvious, but sometimes you work with people that seem less intelligent, less capable, or less motivated than you. First of all, that’s based on your limited understanding, and second, you haven’t figured out the political state of the office. As such, don’t step on the toes of co-workers, regardless of their position. Sometimes, the people below you have the ears of the people above you. Besides, being nice is a Good Thing (and, see #1).
  3. Make your suggestions count by limiting them to a few good ones. As in, don’t give suggestions early at a new job. I know some people might disagree, but let me explain. You might see it as a cost reduction measure, but others might see it as a quality reduction or removal of an important sanity check. Anybody can walk into a bank’s mainframe and give a million reasons to upgrade the 20-year-old UNIX build to something more modern, but this only makes you look naive and misguided. Before you suggest using Ruby on Rails instead of ASP, it’s better that you yield the decision until you have a fuller understanding of everything happening beneath the business hood. Business decisions are often limited by constraints that result in less than ideal solutions – but this is the reality. The key is to understand which constraints can be manipulated. This can’t possibly be done effectively by somebody who just started.
  4. Assume your Internet activities are being watched. If you work for bigger companies, it is highly likely that the computer you are using has keylogging or other “big brother” software on it. How likely? According to PC World, 60% of companies monitor where you visit, 50% monitor your email, and 20% monitor IM chats!
  5. Don’t engage in side projects early on. When you’re still learning the ropes, it is expected that you are committing 100% of your professional time to the new job. So save yourself a headache and preemptively decline all side jobs for the first six months of your career. If you have time to be doing side jobs when you are just starting out, you are probably not focusing enough on your career. And this is exactly how your boss will feel if they catch wind (see #1) of this activity.

The Crazy Folders on Linux – Now You Can be Hardcore Too

I’ve always wondered what all of the folder names meant on Linux, and Saturday’s post on Slashdot about the /etc folder answered it.

From the responses:

All the system directories were kept to three letters, and all of the names are abbreviations — none are acronyms.

/adm = administrative (now found in /var/adm)
/bin – binaries
/sbin – system binaries
/dev – devices
/home – user home directories
/lib – libraries
/log = logs (now found in /var/log)
/mnt – temporary mount point
/root – root’s home directory in case /home is on another file system
/var – variable data, such as databases, news, and mail
/tmp – temporary files
/usr – mostly there because it wouldn’t fit on / 😛
/etc – stuff that doesn’t fit any of the above

Neat, huh?

Another neat factoid regarding “/etc”:

Lot of hardcore UNIX guys pronounce it “et-see” because you sound retarded saying, “It’s in “et-cetera-slash-init-period-d” rather than “et-see init-dee”. Same reason people transliterate Ess-Que-Ell (SQL) into “Sequel” …It’s quicker, and it sounds better.


Permission Denied in the PHP Destructor and the Current Folder

I learned something new today, so I’m going to share two cool things with you.

  1. File access is screwed up during a destructor call in PHP. I will show you how to get around this.
  2. How to create a universal absolute path variable that refers to the current folder you are in.

For the application I was working on today, we needed to add logging. This was a quick and dirty log that would (append) dump whatever was on the page into a file. I was working in a framework I wrote, where each page is actually a class. Neat, but not really necessary to understand the problem.

Here’s the code:

function __destruct() {
    $handle = fopen(CURRENT FOLDER . 'no_sync.response.log', 'a');
    fwrite($handle, '-- START -- (v.' . self::VERSION . ' ' . date('Y-m-d H:i:s') . ")n");
    fwrite($handle, ob_get_contents() . "n-- END --nnn");

Pay attention to that highlighted part and I’ll address it in a moment.

This code takes whatever is in the output buffer (which ultimately gets shown to the user) and chucks it in a file. Cool.

So how does it execute? I don’t call it explicitly. The __destruct is a special PHP function that gets automatically called when an instance of a class is about to get erased. It is rarely used by novice programmers because of its cryptic nature. But this is a good example where you might.

Since it triggers when the class instance gets destroyed, I just need to unset the variable that contains the instance. Near the bottom of my code I added:

unset($FRAMEWORK); // my class is a property inside this variable!

And, as expected, everything worked. Yes, second try! Wait, second??

This isn’t how the code looked when I tried it the first time. That highlighted portion, “CURRENT_FOLDER”, was missing. If I’m writing to the current folder, I shouldn’t have to specify a folder path… Usually. This failed, even though the same exact code in the constructor worked fine.

It turns out that when you try to do file-stuff during the destructor, PHP is no longer in the original folder you started out in. PHP has “forgotten” where your script is and has reverted to the root folder (AKA “/” or “C:”). This, in most systems, causes permission issues.

To get around this problem, you should be explicit about where you want to write the file. You can’t use relative paths (such as “…/logs/”). The “CURRENT_FOLDER” in my example happens to have the following value:

dirname($_SERVER['SCRIPT_FILENAME']) . '/'

The great part about this is that it is not relative. It will be the fully qualified path to the folder the script was run from.

Note: from the command line, you should always type in the full path to the script. Failure to do so will render PHP unable to figure out an absolute path to your script. Just a tip for you people writing cron scripts. 😉

I hope that helps!


Programming Contract Work – Tips on Protecting Yourself

I did contract work for three or four years before I finally threw in the towel. It’s a lot of work, and very frustrating at times. I was very fortunate in that I never got screwed over, but many people have. Here’s my tips on the subject:

  • Everything must be in writing. Especially the points in this list. You don’t need a contract; just make sure things such as pay, deadlines, support, and features are written down for reference in the future during a dispute.
  • If you can get hourly pay where you bill them what you work, do it.
  • If you can’t get hourly pay (99% of the time), take an entire extra day to think about how long the project will take in terms of hours. Don’t guesstimate – actually tally it up hour by hour, feature by feature. Add in 10% for the fact that you will have to break up the work over many days, slowing down your train of thought. Add in another 30% for bug fixes (even if you already added it in, trust me). Add in another 10% for features they are going to toss after you’ve already decided on a “final” version. Don’t tell them about any of this extra time you are calculating. Demand that many hours paid for the project. You will very likely still end up going over what you expect.
  • Now work forwards and figure out by what day you will have the project completed. Add a week and round it forward to the nearest Tuesday and give them that day. Trust me. This gives you two extra weekends if you get caught up on something else.
  • If you are being paid a lump sum, be paid 1/2 up front with the rest, in writing, to be given on the date agreed (the Tuesday mentioned). Make sure you have their name and address in case you have to use the court system. Remember that if they didn’t keep their end of the bargain and pay you what was agreed upon, they are committing intellectual property theft.
  • Fight feature creep. Agree, in writing, on what constitutes “completion”. This requires a breakdown of all features and pages that must exist. Make sure it is very detailed, and make THEM do this work since creating the specifications for what the product should do is not your job! This will be the bible of your obligations to the other person. If they “forget” something, that’s not your problem. You will live and die by this list, and it will determine when you can say you are finished. Once you agreed on a price and start writing code this list is written in stone. Make sure you make this clear to them up front. Allowing them to add to this list is like letting them push back your pay day. This is not to say I never throw in free features, but at least I made them aware that next time, I might charge them.
  • If they insist on adding a major deadline-altering feature that is not on your feature list, they have two options: pay you on the original date so long as the original pieces are done, or tack it on as an additional project after your second pay day. The point here is that you want to make sure feature creep is as expensive to them as it is to you. One “little” feature goes a long way in delaying a project if it happens 30 times. This sort of talk will make them think long and hard before making you add in a new feature. I always give this sort of warning up front, and my clients have been very good about refraining from wanting new features that they think of. They’ll even say, “We can do it on the next version or something…” If you let your clients walk on you, that is your fault.
  • As for the rate to charge per hour, take your normal hourly salary that you get paid at your day job and multiply it by roughly two. Because you have to worry about your own taxes, the income is not steady, and the project might take longer than you anticipate, this is a very standard thing to do. Again, don’t reveal how you arrived at this number. Keep in mind that when you are first starting out, people will be weary of a high rate, so be sensitive to that when determining your price. As a point of reference, I had a friend who had to pay a sys admin $300 for two hours of work. Contract work is like that. A programmer should charge anywhere from $20/hr (high school student) and up. If you have kept a job as a professional programmer for long enough not to be “junior”, charge no less than $45 an hour.
  • If you get a weird feeling that they can’t be trusted, don’t do it.
  • Make it clear they are getting the code from you “as is”. They will know what this means. For your reference, it means you are not responsible for it breaking, being buggy, or not doing what they hoped. As a courtesy, I usually provide free bug fixes and support for the first two weeks. After that, I charge them hourly. Of course, all of this is also mentioned up front.
  • Don’t agree to make something you aren’t sure you can do in time. If it’s beyond your skills, tell them. They will either find someone else, change the specs, or let you lower your rate in exchange for more time. Things are always negotiable, but never agree until you know you have sufficient time.
  • If you are doing design work, agree up front on the number of “drafts” that will be reviewed before a final non-refundable revision is given. A typical number of drafts is two.
  • I have used the “draft” concept with programming work as well. This means presenting them with a half-working “draft” 3/4 of the way into the project. This helps to ensure I create what they are expecting. I usually allow for minimal improvements or suggestions to be made at this point, but if a big change is made, I always point back to the original document and ask that I be compensated for the new work. Usually, you will find people just shout out cool features without thinking about if they are worth paying money for. Putting it into perspective will always help in keeping feature bloat down.
  • Expect follow up support requests for months. Code is never 100% bug free. Just as an example, I had people emailing me about support requests three years later because they wanted the email address on the site changed! I only do free extended service when the bug is critical or due to my own oversight of the original specifications. The rest, I’m afraid, I can’t do for free. Neither should you. If you do it for free anyway, you’re either a chump or a really nice person — they’ll know the difference by this point. Let’s hope you do too.
  • Make the customer happy. I know the above makes it sound like you’re going to be a jerk to the customer, but in honesty, a customer will be happiest knowing all of the little details up front. Keep an open and accommodating line of communication and I promise your clients will be pleased. Remember that it’s not about who-needs-who, but rather, it is a symbiotic relationship. Bending the agreement in their favor (doing touch up work for free) is at your discretion, but always make sure they realize you’re doing it because you are a nice person, not because you are obligated to. Remember that they aren’t going to give you money just because you ask, just as they shouldn’t expect you to give them work for free.
  • Be prepared to get screwed if this is your first contract job. If you don’t know the ropes, you will underestimate the project difficulty, underestimate how often your client will change their mind, and miss your deadlines. Additionally, many of the hardliner approaches I list here will be more difficult when you have zero experience to prove you are trustworthy. On your first project, make sure you learn from your mistakes and be prepared to get stung a little. It’s normal.

I hope this helps! Don’t get scammed (NEVER WORK FOR FREE)!


Boolean and 0.00

ARG. I encountered another potential issue in PHP that is due to loose types that is common if you are using a database back end.

$amount = 0.00;


$amount = '0.00'; // how data from databases comes

Guess what happens. Well, most people might say both should be TRUE, but that’s not true!

The first one evaluates like this:

  1. 0.00 is the same as 0
  2. 0 is the same as FALSE.
  3. Evaluate the IF condition as FALSE.

The second one evaluates like this:

  1. “0.00” is a string.
  2. A non-empty string is the same as TRUE
  3. Evaluate the IF condition as TRUE.

This is a predictable problem, but highly annoying when working with databases. Most people forget that a float field in the database could equal 0.00, but would evaluate as a TRUE when placed in a condition.

As in, when you get results from the database, the NUMBER 0.00 becomes the WORD “0.00”.

So the lesson here is to make sure you always convert your variables before doing conversions like that. As in:

$amount = '0.00';

Of course, the best solution is always making comparisons explicit:

$amount = '0.00';
if(0 < floatval($amount))