PHP Tip of the day: Just say ‘no’ to absolute file paths

When dealing with file paths in your scripts, it’s best to not specify the absolute path. Keep it simple and specify a relative path. What’s the difference? Check out the example below:

Example: In your index.php file you are using the php include() statement to include a file named “includeme.php” located in the “includes” directory. Two methods of doing this are found below:

Method 1: Relative paths: include(“includes/includeme.php”);
Method 2: Absolute paths: include(“/var/www/html/project/trunk/includes/includeme.php”);

Notice how the first include() statement refers to a file in the “includes” directory, one directory down from the file calling it (in this case index.php). In the second, the include() statement has the entire path to the file right from root.

Why choose option 1 over option 2? Well …

#1. It makes server management easier, faster, and cheaper.

During the lifetime of a web server, the web files may need to be moved and/or directories renamed. Imagine what would happen to your website if you were to rename the “project” directory to “old_project”? You’d have to go through all of your scripts and rename the project directories in the include() statements in all of your scripts.

Using method 1, everything keeps on working with no updates to your scripts.

#2. It makes moving your site to another server easier, faster, and cheaper.

If while maintaining your website you end up switching which VPS company you host with or you change the operating system on your server, you could find yourself in a position where instead of having your web files located in the /var/www directory like most Linux distributions you have them located in the /usr/local/www directory like some BSD installations.

In this case you could use symlinks to forward requests of /var/www to /usr/local/www, change your apache configuration to put your web files to /var/www, or update all of your scripts so that they have the correct path. For now.

All of those things feel like hacks.

Best thing to do is just to code from the start with relative paths, thereby avoiding all of these path problems.

The Optimistic Programmer

Recently in the world of programming blogs there has been a string of articles by disenfranchised developers bemoaning their current work environment in a sarcastic and ultimately unproductive manner. I understand and appreciate sarcasm and tongue-in-cheek humor but what I have seen lately goes above and beyond simple satire to a new level of pessimism that in the end is more about self-serving venting than anything enjoyable to read or to learn from.

At first I shrugged off the first article, which was a negative play on a post I made last week, thinking that perhaps the writer had a bad day and was simply going a bit over-the-top. But then another post by a different author came up on DZone in the same light. And then another.

I then started to wonder why there was this growing trend into negative venting blog posts, where their only function is to belittle other peoples’ efforts and cause as much controversy as possible surrounding that subject.

When I started this blog I made a choice: I wanted to prepare and post articles that people could read and learn from or to be more realistic, to offer them alternative channels of thought so that they can continue their research until they find the solution they require.  I have made a personal choice to be an optimistic programmer, meaning I understand that while there will be times that I am incorrect or times where my example code was not the most efficient it is more important to accept that and learn to grown from it, moving onwards and upwards, than it is to be negative and post with the only intentions being to vent and complain without offering any sort of solution or assistance.

There have always been trolls on the internet. There always will be. The best thing I believe we can do as bloggers is to call it what it is and try to be above it by taking the good points of a negative experience and growing from it, not brooding over it.

UPDATE: Since posting this I have received E-Mails concering the troll label I have applied to these posts. Specifically to the first and last links. While I still disagree with the method of complaining or venting with no solutions presented, I have mistakenly grouped what the authors wanted to be humorous posts in with the negativity I was seeing at the outset. Perhaps troll was a bit harsh. I apologize :)

HTML Input Forms – Sending in an array in PHP

Arrays? Who need’s em?

If you’re into developing websites chances are there will be sometime during your life/career when you’ll need to have users enter data into a HTML form but you have no idea how many of a certain variable they’re going to be sending in or how much data they’re going to fill in of the same type.

An example would be a HTML form that has three input boxes, one for each of your friend’s names (first and last). You are able to enter between 1 and 3 friends into the boxes. For such an example your HTML form may look something like this:

<form method="post" action="">
  <p>Enter your friend's names (first, last):</p>
  <input maxlength="30" name="friend1" size="30" type="text" />
  <input maxlength="30" name="friend2" size="30" type="text" />
  <input maxlength="30" name="friend3" size="30" type="text" />
  <input type="submit" value="Submit" />
</form>

That all looks fairly normal. Keep in mind this is a simple example. But, what about if you’ve got the option to enter 10 friends. What about 20? You might have to re-work your form if you want to enter 20 friends. Any more than 10 and you might want to look at alternatives like importing from XML or CSV.

Let’s say you’ve got the option to enter up to 10 names. Your increasingly ugly form would then look like this:

<form method="post" action="">
  <p>Enter your friend's names (first, last):</p>
  <input maxlength="30" name="friend1" size="30" type="text" />
  <input maxlength="30" name="friend2" size="30" type="text" />
  <input maxlength="30" name="friend3" size="30" type="text" />
  <input maxlength="30" name="friend4" size="30" type="text" />
  <input maxlength="30" name="friend5" size="30" type="text" />
  <input maxlength="30" name="friend6" size="30" type="text" />
  <input maxlength="30" name="friend7" size="30" type="text" />
  <input maxlength="30" name="friend8" size="30" type="text" />
  <input maxlength="30" name="friend9" size="30" type="text" />
  <input maxlength="30" name="friend10" size="30" type="text" />
  <input type="submit" value="Submit" />
</form>

When you submit this form then you’ve got to check each input box to first ensure they entered a variable and then check to see what that variable is. With so many input boxes to check from it becomes a repetitive and arduous task.

Example PHP code:


// Good God.. okay let's start this horrible task
if ($_POST['friend1']) {
  doSomething($_POST['friend1']);
} else {
  complain();
}
if ($_POST['friend2']) {
  ...
} else {
  complain();
}
if ($_POST['friend3']) {
  ...
} else {
  ...
}
...
...
// There's got to be a better way!

Save time with arrays.

Using PHP and HTML, the HTML form code can be re-written to have the server create a PHP array of your friends’ names, like this:

HTML Form:

<form method="post" action="">
  <p>Enter your friend's names (first, last):</p>
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input maxlength="30" name="friend[]" size="30" type="text" />
  <input type="submit" value="Submit" />
</form>

Server-Side PHP:

// Loop through the friend array
foreach ($_POST['friend'] as $value) {
  // Do something with each valid friend entry ...
  if ($value) {
    echo $value."<br />";
     ...
  }
}

Let’s walk through that PHP code.

It’s fairly simple. We walk through the php $_POST['friend'] array that we retrieved from the HTML form using foreach and for all of the entries on the form that the user typed in we do something with (in this case we simply echo them to the screen).

This simple foreach loop will save you time and the good part is that you can have any number of friends on your form (I’m sure there’s a maximum somewhere though.. 256 maybe?) and this block of code will still work.

In the next article I’ll show you how to do the same thing with ColdFusion.

PHP Tricks: Eliminate any unwanted characters from a string

Hi all.

I’ve been looking for a handy/graceful way to do this for a while and I thought I’d share this little php trick with you in the hopes that it’ll save you some time if you ever need it. If anyone reading this can quickly convert this example into other languages such as perl, coldfusion, ruby, c, c++ please be my guest and post it as a comment or as a trackback to this blog.

What I wanted to do

I wanted to scrub any characters out of a string that were not alphanumeric. That is, not “a” to “z” and “0″ to “9″. Thankfully, PHP has extensive regular expressions support so that’s what we’ll use.

Why

I needed to store files uploaded through PHP on my Linux machine using a filename chosen by the user. A web site I’m working on requires users to upload media (images, video, music, et. al) and in order to save the files on the hard disk. This functionality prevents code failure by making the filename valid in UNIX filesystems.

The Code

/**
 * Converts a string to a valid UNIX filename.
 * @param $string The filename to be converted
 * @return $string The filename converted
 */
function convert_to_filename ($string) {

  // Replace spaces with underscores and makes the string lowercase
  $string = str_replace (" ", "_", $string);
  $string = str_replace ("..", ".", $string);
  $string = strtolower ($string);

  // Match any character that is not in our whitelist
  preg_match_all ("/[^0-9^a-z^_^.]/", $string, $matches);

  // Loop through the matches with foreach
  foreach ($matches[0] as $value) {
    $string = str_replace($value, "", $string);
  }
  return $string;
}

Usage

Simply call the convert_to_filename function and pass the filename/string along. For example:

$valid_filename = convert_to_filename ($original_filename);

How it works

Almost the entire function is self-explanatory as long as you have a bit of experience with PHP. The part that does the actual deed may need some explanation, however. Especially if you’re relatively new to regular expressions. The part that strips the bad characters from the filename string is started first by this line, which uses a regular expression to make an array called $matches of all of the characters that are NOT a-z, 0-9, a period, or an underscore:

preg_match_all ("/[^0-9^a-z^_^.]/", $string, $matches);

Then, we simply walk through the array replacing the offending character with nothing using the PHP function str_replace.

Functions Used

The functions/constructs used in this article are

PHP Smarty Tip: Speed Up Your Site With ‘trimwhitespace’

If you use the Smarty template engine for your site then you can take advantage of the included output filter Smarty plugin called trimwhitespace. Trimwhitespace is an output filter, which is basically a plugin that runs after your source code has been created but before it gets displayed or put into a cache file.

The premise for trimwhitespace is simple. Most HTML source code for most websites includes whitespace put there by the web developer for readability. Since this whitespace is not required for the website to display and takes up needed bandwidth, we can eliminate it. Enter trimwhitespace.

To enable trimwhitespace, place this command before your Smarty display() function:

$smarty->load_filter('output','trimwhitespace');

An added benefit is that while the user recieves a trimmed copy of your HTML source code, you can still see your source in its fully tabbed and spaced glory by examining your template files. It’s a win-win situation!

HTML Code Before ‘trimwhitespace’:

<table>
  <tr>
    <td>
      Content
    </td>
  </tr>
</table>

HTML Code After ‘trimwhitespace’:

<table>
<tr>
<td>
Content
</td>
</tr>
</table>

See the difference?