Home | Log In Not Logged In
12/24/2008 @ 11:30 pm
Comment (1) | Share | Link
PHP In Action writes on the use of comments in code, specifically citing Eli White's Commenting on Commenting over at PHP Advent. They are critical of Eli's advice, saying that comments should be unnecessary, and that code should be clean enough to easily understand it.

There's a lot of good advice, especially about writing clean code. But the article fails to address a good number of really critical details and to some degree misses the point of Eli's article.

  1. Writing comments beforehand can help articulate the why/how/what of an application. I've written comments many times that spell out the logic step by step. This invaluable process helps a developer think (and rethink) the business logic, and often refactor the code in ways that speed up its execution or development, before any code is actually written.
  2. Descriptive, important comments make editing code easier. I've edited code where a big "Hey! Don't Touch This!" would have been useful to me. Descriptive function names are helpful, but sometimes you can't describe exactly what something does with a function name. Comments are helpful.
  3. Getting in the habit of writing comments helps create to-do items. If you're in the habit of writing comments already you're more likely to leave a "todo" item behind so the next developer can clean something up. You'll leave helpful notes on your thinking, and maybe even spark an idea for re-factoring, something that "descriptive code" can't do.
  4. Leaving good comments helps other members of your team understand your level of understanding, helping them help you improve those skills. Part of working on a team is improving each others skills and helping each other and a big part of that is knowing where each team member is. For the same reason that regular code check-ins and code review should be part of the development process, leaving notes that indicate where you struggled should be part of your process.

PHP in Action points out that writing good, self-descriptive code is important. I do not dispute that. Writing clear, concise code is important, and not filling in too many comments is critical. But self-documentation can only carry you so far; there has to be something else sometimes. That's why PHP has comments at all.

Keywords: comments, php
12/22/2008 @ 6:56 pm
Comment (0) | Share | Link
Sometimes I have to check an array for the existence of a value; for example, I may want to parse an array for a value and then include (or exclude) that value fro an SQL query. I quickly found out that using in_array() is slower than using isset(). For example:

  1. <?php
  2.  
  3. $exclude = array(
  4.         'submit',
  5.         'go',
  6.         'do',
  7. );
  8.  
  9. foreach($_POST as $k => $v)
  10. {
  11.         if(in_array($k,$exclude))
  12.                 unset($_POST[$k]);
  13. }
  14.  
  15. ?>

In the above example, in_array() must walk the entire length of the array to check for the value, which may (or may not) be there. However, if we use isset() it doesn't have to do that. We just have to write our array a bit differently:

  1. <?php
  2.  
  3. $exclude = array(
  4.         'submit' => true,
  5.         'go' => true,
  6.         'do' => true,
  7. );
  8.  
  9. foreach($_POST as $k => $v)
  10. {
  11.         if(isset($array[$k]))
  12.                 unset($_POST[$k]);
  13. }
  14.  
  15. ?>

On large arrays, this has the benefit of being faster (though not more elegant). In the event that you need to put valid data in the "value" portion of the array you can duplicate the data if necessary (though this does slow it down somewhat but not considerably).

12/20/2008 @ 4:49 pm
Comment (0) | Share | Link
I recently worked on an application I built some time ago. It was built before I had regard for performance or cared about how a MySQL database should be built. As such, it had no indexes.

That changed, especially when I started playing with old data that I wanted to migrate. The read time on 15 rows in a 325-row table was some 0.86 seconds (which isn't bad but isn't great). When indexes were applied, however, the read time went down to 0.01 seconds, an 88% decline in read time.

Indexes are easy to add. From your MySQL command prompt all you have to use is the ALTER command, like so:

ALTER TABLE tableName ADD KEY (columnNameHere);

That's it! Of course, you may want to have some more complex keys (UNIQUE, FULLTEXT, etc) and I recommend you read the MySQL documentation.

Indexes aren't for everything, but they can help with some things - especially on join clauses and WHERE clauses. So use them. You'll be thankful you did.

Keywords: MySQL, index
12/14/2008 @ 2:35 pm
Comment (0) | Share | Link
How many times have we heard it? Our bosses, colleagues, everyone, it seems, reminds us time and time again that we're actually customer service professionals, as well as developers. Seems we'd get it, right?

The subject may have been flogged to death, but I'm going to bring it up one more time. Why? Two reasons: first, because we all need the reminder from time to time. And second, because I need the reminder on a daily basis.

It's easy to believe as developers that the focus of our jobs ought to be on writing applications and reading through spec documents. It's not. All of us are customer-focused, and customer facing. Even those of us who develop internal applications or who develop for client services teams (like I do), we have customers: the people who commission the things we build.

With that in mind, there are a few things that we (I) should remember when dealing with customers:

  • Our customers are often less technical than we are. It's nice when we have a customer who understands code or is hiring us because they're overloaded and need some work done; but that's rare. This brings me to the next point...
  • Our customers trust us. They've placed an enormous amount of trust in the developer that they've selected. We need to show that we've earned that trust, and that we deserve it. A great developer should always exude confidence, show the client that they understand, ask intelligent questions, and demonstrate that they have a full, professional-level understanding of the issues at hand.
  • Our customers want us to help them make decisions. There's an old saying that the customer is always right. Not in development. Often times a customer doesn't know what they want, so how can they be right about their choices? It seems developers have the hardest time with this: their client will say "we don't know how we want this to work, can you show us some ideas?" The developer, who is much more comfortable demonstrating his solutions in code than in words, will fumble around and sometimes even make a bad recommendation. Don't do this. Even if it means taking time and saying "let me get back to you," a great developer will be able to give a client options, and then help the client pick the best one.
  • Customers don't understand what we do, or how we do it. A client will rarely say "I think this will take five hours" and be right. It's not that the client has high expectations, or is stupid. They just don't do what we do. We have to help them understand. When we say "well this will actually take 25 hours" we better be able to show them why. Here's where the architecture goes, here's database optimization, etc. We should never bloat our estimates to enrich ourselves; that's not the point here. But we should always be sure that the client understands specifics, and that we show them why, not just tell them.

These tips are not just for the world, but for me too. I need to remember every day that I'm first and foremost a customer service professional. The client is my client, and I work for them.

Keywords: clients, customer service
12/5/2008 @ 1:41 pm
Comment (0) | Share | Link
Have you ever written code like this?

  1. <?php
  2.  
  3. class VerifyLogin extends UserObject
  4. {
  5.         function verifyCredentials()
  6.         {
  7.                 $username = mysql_real_escape_string($_POST['username']);
  8.                 $password  = mysql_real_escape_string($_POST['password']);
  9.                 $passwordhash = MD5($username . $password); // Salt our PW Hash
  10.                 $sql = 'SELECT id FROM userTable WHERE username = ' . $username . ' AND password = ' . $passwordhash . ' LIMIT 1';
  11.  
  12.                 $resource = mysql_query($sql);
  13.                
  14.                 if(mysql_numrows($resource) > 0)
  15.                 {
  16.                         $array = mysql_fetch_row($resource);
  17.                         $this->userID = $array[0];
  18.                         $this->loggedIn = true;
  19.                         return true;
  20.                 }
  21.                 else
  22.                         return false;
  23.         }
  24. }
  25.  
  26. ?>

The problem here ought to be clear: we're using a class exactly like we would in some procedural code. This is a problem.

Let's ignore the security implications of the above code for just a moment, and focus on just the use of the superglobal. By using the $_POST superglobal array, we're effectively doing two things:

  1. We rely on our form fields always being called 'username' and 'password,' and our class breaks if they're not.
  2. This object cannot ever be used for processing any other types of data, limiting code reuse.

This isn't what objects are for. Objects are designed to take data and hold it, then act on that data. For example, our user object should information about that user. You might have methods that can act on that user, like promoting them to administrator or verifying their login credentials. In the latter case, you would need to take $_POST data but it would be much better to pass it in directly than to rely on the superglobal inside the object itself.

A better code snippet from a user object would look something like this:

  1. <?php
  2.  
  3. class VerifyLogin extends UserObject
  4. {
  5.         function verifyCredentials($username,$password)
  6.         {
  7.                 $username = mysql_real_escape_string($username);
  8.                 $password  = mysql_real_escape_string($password);
  9.                 $passwordhash = MD5($username . $password); // Salt our PW Hash
  10.                 $sql = 'SELECT id FROM userTable WHERE username = ' . $username . ' AND password = ' . $passwordhash . ' LIMIT 1';
  11.  
  12.                 $resource = mysql_query($sql);
  13.                
  14.                 if(mysql_numrows($resource) > 0)
  15.                 {
  16.                         $array = mysql_fetch_row($resource);
  17.                         $this->userID = $array[0];
  18.                         $this->loggedIn = true;
  19.                         return true;
  20.                 }
  21.                 else
  22.                         return false;
  23.         }
  24. }
  25.  
  26. ?>

In this example, we get to select where the $username and $password variables come from. Likely they'll come from a posted form, but we have the ability to determine that for ourselves. This class is much better, because it is a true blueprint of an object.

There are some legitimate uses of superglobals in classes. One example is the use of the $_SESSION superglobal, which is often used for things like a user object. But I urge you to do so sparingly, when appropriate, rather than relying heavily on superglobals which are subject to change and may not give you the data you expect.

Keywords: superglobals, classes, objects php 5
12/1/2008 @ 8:18 pm
Comment (0) | Share | Link
The browser wars did not end with the fall of Netscape and the triumph of Internet Explorer. Indeed not; there is still a fierce competition out there for the supreme browser on the internet. This post was mostly spurred by a recent post done by Keith Parnell which asserts that 73.04% of all internet traffic is viewed on Internet Explorer. Well, that should settle the debate, right?

Not so fast.

Last week, Keith Casey wrote about some statistics that are coming out of W3 Schools that show Internet Explorer in decline. I've included their stats below:

2008 IE7 IE6 Chrome Fx Moz S O
October 26.9% 20.2% 3.0% 44.0% 0.4% 2.8% 2.2%
September 26.3% 22.3% 3.1% 42.6% 0.5% 2.7% 2.0%

According to W3 Schools, Internet Explorer makes up 47.1% of all internet traffic, only 3.1% better that Firefox, and 26 points lower than Keith Parnell's stats.

But as I've learned, often the information you get about browser usage is based not on some actual proportion of users but on the users who visit your site, or sites where you gather statistics. For example, 63.5% of the users of this website use Firefox; however, 59.5% of you use Windows as your primary operating system. If I were to make an assertion about the world, I'd have to presume that browser traffic was 2/3rds Firefox. But we all know that's not the case (especially since 11.6% of you use Linux and 24.5% of you use Mac OS X, which is 2 to 3 times above average).

So the browser wars will continue. The fight will persist and it will not be settled easily.

However, as Keith Casey points out, we will soon be free of Internet Explorer 6. And for that, we can all be thankful.

Keywords: browsers
11/24/2008 @ 10:12 pm
Comment (0) | Share | Link
There's no such thing as a perfect application...or so they say. That's why we version, and improve, and add features, and innovate. Nothing is ever perfect.

Or is it?

I started thinking about this when I started looking at some of my code for my blog. I've written a custom blogging application, and I've written it exactly how I like it. I've been meaning to rewrite it to incorporate all I've learned in the last year. But in terms of features, I believe it has arrived.

Certainly it's not perfect, by any stretch, because it isn't as efficient, as organized, as user-friendly as it could be. But it works. It satisfies. And, I've added no new features in over four months - a record, considering that when I first built it I made about 200 revisions in two weeks.

I think that's the point at which an application reaches perfection - when you don't want to add anything else. Though the application or its peripherals may evolve, when you no longer need to edit the application to make it easier to use, you've arrived.

Then the application is perfect.

11/18/2008 @ 5:19 am
Comment (4) | Share | Link
A few months ago I switched over to Slicehost for web hosting. I have to say, I don't think I could have made a better choice.

I'm not sure what I was expecting, but what I got was pretty amazing. Slicehost works by offering virtual servers for each account - that is, for each account they offer, you get your own box.

They don't give you a whole lot to start with. The box is a clean, basic installation of your chosen operating system (they offer Ubuntu Hardy or Intrepid, Gentoo, Fedora, Debian, CentOS, and Arch). You're responsible for putting anything on it you want.

And that's where the fun starts: you really can put anything you want on it.

Need a database server? No problem. Want a web server? Go for it. You can build a full LAMP stack or create a load-balanced full server setup yourself, from scrach, with whatever settings you want. You can create a VPN server, a file server, an Subversion server...if it runs on Linux you can run it on Slicehost. Period.

And it all starts at $20 a month.

I've got four slices under management for a number of clients, as well as for BrandonSavage.net and I've got to say I've never been happier. Upgrades happen when I want, I have full root access, and I get to decide how to build my server.

Sure, it's not for everyone. You've got to enjoy managing a server, and be willing to shell out some money for some of the higher-end options (a 512 MB server runs you $38/mo and a 1GB server is $70/mo). But, given the other options out there, Slicehost has served me well, and it will serve you well too.

Tell 'em I sent you.

Note: I am not an employee nor do I get a kickback from Slicehost of any kind for my review. Though they offer an affiliate program, it only applies if you provide a contact's email address.

11/14/2008 @ 5:03 pm
Comment (4) | Share | Link
Below are a list of my top five quick-and-dirty strategies for improving database performance in web applications. These suggestions are culled from recent experience and mixed with some ideas that I've implemented in my own code. They're not high level, but they are something we need consistent reminders about. Here they are...

1. Try caching. If you have something that doesn't change a whole lot, or data that can be stale for a period of time, consider caching it. This can be as simple as writing a function that writes it to a file. For example:

  1. <?php
  2.  
  3. function cacheData($filename,$time = 900)
  4. {
  5.  
  6.     if(file_exists($filename))
  7.     {
  8.         if(time() - filemtime($filename) > $time)
  9.         {
  10.             // execute some query here
  11.             file_put_contents($filename,$string);
  12.             return $string;
  13.         }
  14.     }
  15.     else
  16.     {
  17.         $string = file_get_contents($filename);
  18.         return $string;
  19.     }
  20. }
  21.  
  22. ?>

This function would check for a file's last modification date, and if the data is stale, it would replace it with new data. Since a file read is almost always faster than a database hit, this is a great solution.

2. Reduce the number of queries that run. For every query that you run, your database takes a hit. By reducing those queries, you improve the speed.

3. Use indexes. Learn how to use the EXPLAIN command, and then implement indexes to optimize your database. Do NOT index everything; index only where it is appropriate.

4. Optimize data usage. Ensure that data is kept once; make sure that you have frequently used data separate from infrequently used data or large data (read TEXT, LONGTEXT, BLOB). For example, you might consider keeping a blog's metadata separate from the entries and linking them through a foreign key; you could also consider having the entry text as a text file that is read from disk (up to you).

5. Avoid functions in WHERE statements. For example, this will cause problems:

SELECT * FROM MEMBER WHERE TO_DAYS(expiration) 
- TO_DAYS(CURDATE()) < 30

The optimizer cannot use an index on the 'expiration' column because it has to apply the function TO_DAYS() first; this negates the positives on the index.

A better SQL query would be this:

SELECT * FROM MEMBER WHERE expiration < 
DATE_ADD(CURDATE(), INTERVAL 30 DAY)

In this case, the optimizer can use the 'expiration' column index to help find our data faster. (Credit to Paul Dubois for these queries)

These are easy but important tips. The more they're written down, the more people will use them. Use them, and your life will be easier.

Keywords: MySQL optimization, database performance, caching, architecture, design
10/30/2008 @ 11:46 pm
Comment (0) | Share | Link
For the past three days I've been travelling to a roundtable in Palo Alto, California to meet with Ning, the developers of a platform that allows you to create any social network for any purpose. They brought together some of the most important and largest networks on Ning to solicit feedback, gain input, and tell us about the roadmap they're taking to development. And, I've got to say, their roadmap is both agressive and awesome.

Ning has allowed our client, The Pickens Plan, to create their network called Push on Ning, at a reasonable cost (for the premium services), with some awesome features built in. Now that Ning is moving towards the OpenSocial model, developers will be able to create some great applications that can be distributed to the more than 500,000 social networks on Ning. And, since Ning is designed to let you create your own social network (rather than a group or a page like Facebook and Myspace), you can add a whole level of functionality and draw for a client's visitors without having to even write a single line of code.

So check Ning out. I think you'll be surprised and happy that you did.

10/21/2008 @ 9:32 am
Comment (0) | Share | Link
Have you ever been handed some code and told, "make it work"? If you haven't, chances are good you will some day. It's often a daunting task, especially since, as one programmer told me, "comments come when the second developer has to make changes." While this is likely bad coding practice, it's happened to me more than once.

Lucky for us, XDebug has a built-in tool that helps us evaluate code and figure out some of what is going on without spending all week reading the documentation or the code itself. It's called "function profiling."

Continue Reading...

Keywords: XDebug, PHP, bugs, fixing bugs
10/18/2008 @ 10:27 am
Comment (0) | Share | Link
Cal Evans sent around ratings from ZendCon sessions yesterday, and there seems to be a great deal of debate on Twitter about what they mean. Are they indicators of a person's suitability to speak? Are they indicators of where a person's weaknesses are?

Both Matthew Turland and Ben Ramsey wrote that they were less than excited about their personal ratings. Having heard both of them speak, I think the ratings are, shall we say, overrated.

It's certain that some individuals will get higher ratings, especially those who have a natural knack for speaking, or those who teach every day. There's nothing wrong with that. But the point of a conference is for those who speak to improve the body of knowledge for everyone else.

For those who got less than fantastic results, you still rock. And for those who got great results, we knew you rocked already. Thanks to everyone who spoke, enlightened, and contributed to ZendCon. It's what made it great.

Keywords: ZendCon, ratings
10/16/2008 @ 5:24 pm
Comment (0) | Share | Link
There are two really great experiences in my PHP life: the day I learned how to use PHP, and the day I installed XDebug. Ok, perhaps that's an overstatement, but XDebug is one of the best tools I've ever used. I think every developer should use it, and for the next part of this series we're going to talk about its features.

XDebug allows you to do a number of things: first, it provides styling to your stack traces and stack traces every error. Second, it allows for profiling. Third, it provides some variable output tools that are just necessary when working with PHP.

XDebug is an extension for PHP, and before you do anything you should probably download and install it from the XDebug website. Don't worry...I'll wait...

Continue Reading...

10/15/2008 @ 9:27 am
Comment (0) | Share | Link
PHP has a large number of tools for fixing bugs and resolving underlying issues. But many people don't know what they are, and some of them are extensions requiring installation in order to work. In this series, we'll explore some features for debugging PHP scripts, from the most basic to more advanced.

Today we will discuss tools that ought to be in your bug-fixing toolkit already. There are three tools that everyone should already have:

  • var_dump();
  • print_r();
  • var_export();

Continue Reading...

Keywords: var_dump(), var_export(), print_r(), debugging, Bug-Free
10/15/2008 @ 8:33 am
Comment (0) | Share | Link
PHP Appalachia 2008 came to a close yesterday, concluding four days of fun and friends.

We had great presentations by some of the best names in PHP, including Ben Ramsey, Brian DeShong, Matthew Turland, and lots of others. The evening ended with a RambleCast recording, and a viewing of The Goonies, a low-key end to a great weekend.

Elizabeth Naramore deserves the majority of the credit for a great event, since she spent most of the time and effort putting it on. Keith Casey receives honorable mention for his participation and planning as well.

For new friends and old companions, I'll miss you until next time. Four days wasn't nearly enough, but sadly real life must continue on. Thanks to everyone who came out, participated, and made it a great time. I'll never forget Cal Evans jumping in front of an angry Chris Shiflett (not really...just stepped on broken glass), or Elizabeth Naramore scaring the haunted house guy by screaming "TERRY CHAY! TERRY CHAY!" over and over again. Those memories can't be bought for any price.

Thanks PHP Appalachia. Until next time...

Keywords: Terry Chay, PHP Appalachia
 
Older Posts