A Single Article

Read it, comment, and share it with your friends

PHP techniques I use all the time

Posted November 9 in Technology.

Back in February, I was writing CSS every day and I decided to share some of the CSS techniques that I always use. Lately I’ve been writing more PHP than anything else and I’ve found myself using some very useful techniques all the time.

Now I know that PHP isn’t very “cool” these days; it’s probably the most misunderstood web language because all the script kiddies use it to include files on their webpages and put up forms that get hacked hours later. But I think PHP deserves a whole lot more credit than it gets; it’s fast, it integrates very nicely with Apache, it got all the right features in version 5, and even if you don’t like using it, there’s always a chance you might have to write some anyway. So, maybe these tips can help you out:

  • Use heredoc syntax for strings: If there’s one thing I got tired of fast, it was building long strings like this:
    $s = "This is something ";
    $s .= "that will make ";
    $s .= "a long string, with ";
    $s .= "a variable: $x.";
    If I am going to make a string with more than one line, and even sometimes when I’m not, then I use heredoc. It’s much, much cleaner than worrying about quotation marks, because it isn’t delimited with them. Here’s the same string as above, in one clean heredoc block:
    $s = <<<HEREDOC
      This is something 
      that will make 
      a long string, with 
      a variable: {$x}.
    HEREDOC;
    And, that delimiter can be anything; EOF, MYSTRING, ELEPHANT, etc. The only caveat is that the ending delimiter has to be all the way at the left; you can’t put any spaces or tabs before it. This is a slight nuisance if you are serious about maintaining indentation, but it’s a small compromise for having such a clean way of making strings.
  • Contain your variables in strings with curly braces. This goes along with the heredoc syntax above, but you can use it in double-quote delimited strings too. It looks like so:
    $x = "Something with {$y['key']} and {$z}.";
    It allows you to include array variables in strings and it makes the variables stand out better in most any text editor. Update 11/12: I should mention, for anyone who doesn’t know, that using curly braces in your strings is not recommended when you are working with user input. See this bug. Either validate the user input to make sure that there are no curly braces before plugging it in, or don’t use curly braces with user input at all.
  • Build arrays. Always. You probably won’t make just one of something. Sooner or later, you’ll realize you need two, and then you’ll have to go back and turn that variable into an array so you can store multiple things. I walked into this mistake too many times… I would be processing a form, and have a variable called $error to store a possible error, and then I realize 10 minutes later that there might be more than one error, and I need to make an array of errors, and I have to go back and rewrite things to use an array instead. Nowadays I don’t get into that mess anymore; I just start with arrays and save myself the trouble.
  • Use associative arrays. (These are called hashes too.) They make things easier to keep track of. This goes along with the previous tip, though if you are just making a linear list of things, there’s no need. Where associative arrays come in handy is when you need to remember the keys you use, because you can refer to the key with a variable. Say I have an array that I use to retrieve the address for a page, I can do the following (this is a horrible example though):
    $pages = array(
     'index' => 'startPage.php',
     'contact' => 'sendForm.php'
    );
     
    // could do some function here
    $thePage = 'contact';
     
    $theAddress = $pages[$thePage];
     
    // here I'll get sendForm.php
    I think that’s very convenient.
  • Shortcut the else.
  • I learned this with C and I use it in PHP. What’s the point of doing the following:
    if( this condition ) 
    {
      $x = 5; 
    }
    else 
    {
      $x = 10;
    }
    If the $x is going to be 10 by default, just start with 10. No need to bother typing the else at all. I just do this:
    $x = 10;
    if( this condition )
    {
      $x = 5;
    }
    And, that’s all there is to it. It’s a lot less typing.
  • Walk through arrays with foreach. Even arrays with numerical indexes. It’s just way easier than worrying about a counter, figuring out the size of the array, etc. Even if I need a counter for any reason, I tend to use foreach anyway, and add a counter as if it were a while loop. Update 11/12: As Jon H mentioned, this is only for when you want to retrieve the data in an array, like when you are getting the results from a database query. If you need to modify the data in the array, then you can’t use foreach should use this:
    $arr = array(0,1,2,3,4,5,6,7,8,9);
     
    foreach($arr as $key => $num) {
     if($num==5) {
      $arr[$key]=0;
     }
    }
    print_r($arr); 
    //5 got replaced to 0
    Thanks to Emilio for the tip!
  • Use switch, not a mess of if statements. It reads better, by far. Just don’t forget your breaks:
    switch($x)
    {
     case 'one': ...; break; 
     case 'two': ...; break;
     default: ...; break;
    }
    You can also combine multiple cases, if you want them all to have the same result:
    case 'one': case 'two': ...; break;
  • Use clean syntax elements. Here are some simple things you can do to keep your code clean: Going to print a single variable? Just do:
    <?= $out ?>
    Don’t like the ugly curly braces in your if-else statements? Just do:
    if( this condition ) : 
      ...
    else :
      ...
    endif;
    1
  • Process user input with a separate script. If a user is going to submit a form (and method='post' is always the way to go), then you should send it to a separate script that does all the work, then when it’s done, send it off to a different script with:
    header('Location: ' . $url);
    … where the actual $url can be relative or absolute. This way, the user can’t hit refresh and post the data all over again, which is annoying, and you can send the user off to different scripts depending on the outcome of the processing. Update: Andrew made a good point in the comments about reporting errors back to the user, which totally slipped my mind. I might write up something soon about a better way to handle forms.
  • Follow a strict order in your scripts. Even if you are just writing very simple functional code, it pays to have some order. If you are going to do everything in one file, try to follow something like this:
    1. Process user input.
    2. Query databases.
    3. Build and process all data, make arrays, strings, etc.
    4. Display everything, don’t do any more processing or retrieving in the markup!
    Then, when you have to go back and change things, it’s easy to remember where to look for, say, database queries. They will always be in the same relative part of your scripts.
  • Be consistent. This is the best piece of advice I can give. Just because occasionally you can cut corners, like writing an if statement without the curly braces because you only need one line, that doesn’t mean you should do it. Code is easiest to read when you are consistent about the way you do things, regardless of the exact way you decide on, and when you develop a habit for writing things one way, you reduce the chance of making stupid typos down the road, because you’ll have the correct method engraved into your head.

That’s my list; if I think of more things, I’ll share them. In the meantime, share your PHP techniques, I would be very glad to hear them!

Also, don’t forget to read my previous post about easy form processing with PHP.

1 something disappeared here. Don’t know why it was there to begin with.

Meta

Useful things

Related Articles

These just might ring a bell

Get a Trackback link

5 Trackbacks/Pingbacks

Other blogs referencing this article
  1. Pingback: Sunday Weekly Roundup #15 - 11/11/2007 » Blog at veanndesign.com on November 12, 2007
  2. Pingback: Updates From Sam Jones » Blog Archive » links for 2007-11-13 on November 13, 2007
  3. Pingback: rascunho » Blog Archive » links for 2007-11-16 on November 16, 2007
  4. Pingback: Weekend Links - PHP Techniques, Regular Expressions, Ajax PageRank, PHP Downloads, Color Mathematics on November 17, 2007
  5. Pingback: This Weeks Top 7 Links | devjargon on July 19, 2008

46 Comments

Responses to my article
  1. Larixk November 10, 2007

    Nice stuff, a few comments:
    In the ‘Shortcut the else’ part:
    Why not use:
    $x = ( this condition )
    And skip the whole If-statement. Of course this only applies when setting $x to a boolean.

    In the part about clean syntax elements:
    Support for short open tags is often limited by hosts and considered a bad habit because it might cause a conflict with languages like xml.

    All the rest some nice advice, especially what you said about always needing an array.

  2. Yannick November 10, 2007

    Some pretty good tips . Thanks for sharing some of the techniques you use. Just like Larixk, one thing I’d question though is the use of short tags. Even though it does make life easier, it’s probably better you stick to doing it the long way. What if you need to move your code/application to a server that doesn’t have php short tags enabled? You’re going to have errors in your code and either have to edit the code or make modifications to the php.ini config file. This could be troublesome for some people, especial those not PHP savvy. It also conflicts with the XML prolog, if it is used.

    Oh and correct me if I’m wrong but I don’t think PHP short tags is a PHP5 only feature. I do believe it is in the 4.x.x branch as well.

  3. Andrew Ingram November 10, 2007

    Regarding the “processing user input with a seperate script” thing:

    My preference is to have the form POST go to the same page as the form and only use the redirect-after-post pattern on a success. The reason is, if you POST to the page you’re already on and there’s an error, you can easily prepopulate the form with the values that were entered first time round and highlight the mistakes. You can do this with a redirect-after-post but it requires saving things in a session, cookie or query parameters (you may be able to tell the browser to redirect with a POST but it’s not guaranteed to work since the spec says a browser is only required to handle redirects with a GET).

    Of course you could always get your separated POST handler to render the same page as the original form even though it’s a different URL, but that’s introducing an unnecessary URL and makes the app less RESTful.

    I also prefer multi-stage forms to always take place on the same page (the ideal persistence method varies based on the length of the form and number of fields) so that intermediate stages aren’t bookmarkable (you can save the current form stage in the session if you want people to be able to return to the same point later).

  4. Christian Montoya November 10, 2007

    Larixk: Yeah, I gave a bad example, it makes more sense when dealing with strings.

    As for the short tags, I guess I shouldn’t have mentioned them because I don’t actually use them at all, I know they are not good to use since they are definitely limited in support.

    Yannick: I didn’t say PHP short tags is PHP5 only, I said that the quick print, <?= $x ?> is.

    Andrew: That’s a good point. I think I have used sessions for errors in the past but admittedly I’ve done other things too. I had one case where I had a main script that handled the form processing and then included one of two different files, depending on whether the form was successful or not. I guess I should revise what I said then.

  5. she November 10, 2007

    “Don’t like the ugly curly braces in your if-else statements? Just do:”

    I dont think this will work.
    I know it exists but whenever I looked at stuff like phpBB and similar “big” projects, they do not use this.

    Anyway, I am saying this from afar, I have since quite long left the world of PHP, only do it for a very few things and hoping that I can one day completely move away from it, for a scripting language it feels extremely poor for general purpose tasks, and I would rather prefer to use one language that gives me optional GUI and can also be applied to the WWW - at best with a nicer syntax too. :-)

    Granted though, PHP is not hard to learn.

  6. Christian Montoya November 10, 2007

    she: Wordpress uses it, that’s where I learned it. It’s just a matter of preference, but being rare does not make something bad.

    I personally don’t care if I use one language for offline and another for the web. I’ve used so many languages, but I’m a web developer and everything I do lately is online so I can’t speak for your point. The merits, however, are more than just that it’s “easy to learn,” which really doesn’t say much because learning it and learning it well are two different things. What counts, though, is that PHP has to be the easiest scripting language to set up on a web server. That’s why almost every web server has it by default. I optimized some dedicated servers for my employer, and all I had to do was install some packages and restart Apache. I like that level of simplicity.

  7. Joe Louis November 10, 2007

    an even shorter if else statement:

    $foo = ($bar == 10) ? $bar : $x;

    that translates to:

    if ($bar == 10) {
    $foo = $bar;
    }
    else {
    $foo = $x;
    }

  8. Yannick November 10, 2007

    Christian: Hope you don’t mind me asking, but where did you see that the ‘quick print’ syntax is only available in PHP 5?

  9. Christian Montoya November 10, 2007

    Hmm, maybe I misspoke, I can’t find it anywhere. I guess it’s available in PHP4? That would be good to know.

  10. Josh November 11, 2007

    Another nifty use of short tags is the echo equivalent: which saves you some typing and looks very clean when used within HTML.

  11. Josh November 11, 2007

    oops! <?= $variable; ?> should work better.

  12. Ron November 11, 2007

    Regarding “shortcut the else”, I ran some timer tests, and got this (1 million iterations):

    if-else: 0.8151798248291 sec
    if: 0.9922239780426 sec
    tertiary: 0.93130898475647 sec

    That is, if($condition){ $x=5; }else{ $x=10; } is fastest, followed by $x=($condition ? 5 : 10);, followed by $x=10; if($condition){ $x=5; }. However, this is if $condition is true. If $condition is false:

    if-else: 0.82969498634338 sec
    if: 0.81288599967957 sec
    tertiary: 0.82582521438599 sec

    So, perhaps, one should choose a style depending on whether the condition is more likely to be true or false. I personally either define a default value immediately (as suggested in the article) or use tertiary. It’s nice to ensure that a variable is defined early on, rather than forgetting to write the else block.

    Speaking of speed, and in relation to your bit about loops, ++$i is consistently faster than $i++, but supposedly only in PHP.

  13. Christian Montoya November 11, 2007

    Ron, you have to share your setup. CGI or CLI? v. 4 or 5? FastCGI/Zend/APC/eaccel/Turk or no optimizer at all? Obviously the performance here would depend on how the code is compiled (or if it is not compiled at all).

  14. Yannick November 11, 2007

    Christian: Yeah I think the ‘quick print’ syntax is available in PHP 4 as well. At least that is the impression I get from the manual and of course as long as short open tags is enabled.

    In any case thanks again for sharing the techniques. :)

  15. Albert November 11, 2007

    Christian, you might remember this better than I do from the optimization class, but way down at the assembly level, I think the two methods should be the same. (Granted I didn’t screw up the assembly too bad, which I’ve completely forgotten the syntax for.)

    preload-if
    1. add 5 0 x (move 5 into $x)
    2. bgt/blt/beq 4 (the if statement)
    3. add 10 0 x (move 10 into $x)
    4. (continue)

    regular if/else
    1. bgt/blt/beq 4 (the if statement)
    2. add 5 0 x (move 5 into $x)
    3. jmp 5 (skip the else block)
    4. add 10 0 x (move 10 into $x)
    5. (continue)

    I seriously need to review my assembly again. Regardless, at the machine level, that should be what’s happening? In the preload case, it executes 2 commands if it’s true, and 3 commands if it’s false. In the if/else case, it executes 3 if the statement is true and 2 if the statement is false.

    Regardless, that’s is a great space saver in code. I fall into two syndromes that you listed above: I have having a bajillion short if/else statements, so I often cut corners and skip the consistency of putting curly braces. I think this trick will save me from my curly braces syndrome. =P

  16. Ron November 11, 2007

    Christian: I used PHP 4.x, CGI, no optimizer. I avoid optimizers whenever measuring the raw speed for a piece of code.

  17. Christian Montoya November 11, 2007

    Albert: Wow, I never wanted to see that kind of stuff ever again. I guess Ron would be correct, it depends which one is more likely.

    Ron: Would it matter if you used CLI instead of CGI?

  18. JGM November 12, 2007

    The quickprint syntax is available in both 4 and 5.

  19. Christian Montoya November 12, 2007

    Thanks JGM.

  20. Cornelius November 12, 2007

    I like using variable variables in my main nav file.

    At the top of every page I set a page id variable.

    In the nav file I set a variable variable to “selected”. Note the double dollar sign. This dynamically creates a variable with the same name as the current value of $page_id.

    Now for each item in the nav I just include the page id variables into the class of each item so I can style the selected link differently.


    <li class=''>Home
    <li class=”>About
    <li class=”>Contact

    It’s easy to lose track of where these variables names are coming from so I would suggest limiting it’s use to obvious cases like navigation. To help eliminate the possibility of one variable overwriting another with the same name, I’ve added ‘p_’ to the name of each id.

  21. Cornelius November 12, 2007

    Bah, the code tags were stripped!

    The variable variable syntax is: $$page_id.

    So, if

    $page_id = ‘p_home’

    and

    $$page_id = ’selected’

    then

    $p_home == ’selected’

  22. Rick November 12, 2007

    Oh my god….

    There are so many things wrong with these little pieces of advice I don’t even know where to begin. I had to read it twice to make sure it wasn’t meant as a joke. Literally everything you’ve written is wrong on so many levels it’s hard to believe this is meant a serious advice.

    It’s the PHP equivalent of telling people to build their layout exclusively with tables, putting div-tags around everything and naming your classes ‘bigredheadline’ and sticking their CSS definitions somewhere in between the HTML.

    In just a few examples you’ve just managed to show how to make even the most simple bits PHP-code utterly unreadable, impossible to maintain, non-portable and easy to hack.

    This kind of crap is exactly what gives PHP such a bad reputation.

  23. Christian Montoya November 12, 2007

    Cornelius: I remember doing that once, it’s cool that with PHP you can use $$x to reference a string as the name of a variable. Then I got into the habit, though, of storing navigation in an array where they key is the page name and the value is true/false, and putting that in a function that sets which one is true:

    $nav[$truepage] = true;

    Horses for courses :)

  24. Christian Montoya November 12, 2007

    Rick: Are you sure?

    There’s nothing in this article about security. It would have taken me hours to talk about that. Obviously you can’t just do:

    $page = $_GET['page'];

    You have to make your own function for validating it and run it through that first. I know my readers aren’t stupid, people know this stuff.

    AFAIK, that’s the only glaring concern in my code. If there’s something that you think is wrong, instead of making a poor analogy, why not educate me and the other readers here on why it’s wrong and why it should be done differently?

    There’s a lot of money depending on the “noobish” PHP that I write so sooner rather than later would be helpful.

  25. Ozh November 12, 2007

    All good tips I also came to over the years, except one: never ever use PHP short open tag (ie <? instead of <?php, or <?=)
    It is not always working, depending on server configuration (see ini.core on php.net for more info.

  26. Jon H November 12, 2007

    Regarding always using ForEach.

    ForEach is a loop construct designed for iterating collections. You can use it on any collection that implements the Iterator interface.

    ForEach is not a designed to replace “for”.

    If you need to modify the collection you are iterating, you never want to use foreach, because it can cause very strange results (and in most languages, throw an exception).

  27. Rick November 12, 2007

    Okay, let’s not take the easy targets like <?= (goodbye portability), omitting curly braces in if/then (try maintaining other peoples code, and you’ll find out soon enough why this is an awful idea), using flaky expensive constructs complex strings syntax and the ‘please inject malicious code’ $_GET.

    (Sorry, I don’t assume people you seem to have to explain to what associative arrays are to know about the dangers of using unsanitized GET parameters. Maybe you shouldn’t either.)

    Under “Build arrays. Always” you explain this by saying that it saves you time not having to rewrite the code when circumstances change. But your just shifting the problem, not solving it. Now the rest of your code needs to know that the errors are contained in an array, and has now been rewritten to address them as such. Same problem, different data type. This is why people much, much cleverer then you and me have thought of the notion of ‘abstraction’. There is no need for the piece of script to know how the errors are stored, as long as it can get at them. (This besides the fact that $error is wide open to change by pieces of code that have no business touching it.) So the smart thing to do for instance to create a simple class that stores and returns error messages through neutral interfaces like ‘ErrorHandler::getMessage()’. And whatever you do with your errormessages, (for instance make them multilingual) you won’t have to change the rest of your code. Ever.

    (Yes, this to is a gross oversimplification, but at least it sends people in the right direction instead of another dead end.)

  28. Christian Montoya November 12, 2007

    Jon H: Yes, I should have mentioned that, thanks.

    Rick: Do you seriously not prefer heredoc syntax?

    Also, please read the article again, you are ~12 hours behind here.

    As for abstraction, yes, I might write my code that way if I’m making something that’s really complex, but seriously, a lot of the stuff I do never needs to be that complex. Thanks for the tip though. You could have shared it without being so insulting.

    Anyone else: This is a damn discussion. Let’s share, ok?

  29. William November 15, 2007

    Regarding the use of foreach, you mentioned that you can’t use it to modify arrays. That’s only true if the contents of the array are native values, such as numbers or strings. If your array is full of objects or other arrays, you can do this:

    foreach ($arr as &$thing)
    $thing->var1 = 23;

    As a previous comment suggested, the use of iterators is probably preferred over this, but for those of you who are adventurous, give the above code a try.

  30. Toby November 15, 2007

    One thing to point out about the alternate “no-brackets” if-else syntax is that it doesn’t fold well in editors.

  31. Jason November 15, 2007

    Great Post! PHP Rocks. It’s fun, simple, and very powerful.

  32. brandy November 15, 2007

    hmmm… i’m pretty sure that the “default” and the end of a switch statement doesn’t need a break after it.

  33. Richard November 16, 2007

    Regarding “the bug” you mention. Following your link I see no comments since ~2001. Is this relevant.
    Anyway, it’s only mentioning “addslashes”. Does anyone use that these days? PHP security books I’ve read of late recommend the (thoughtful, not reflexive) use of HTMLENTITIES().
    Thoughts?

  34. Christian Montoya November 16, 2007

    Yes, htmlentities is much more useful, since turning < into &lt; really eliminates about 99% of injection hacks. Also, if you can white-list input rather than trying to clean it (like, you only allow letters and numbers), that’s much more safe.

  35. Jeena November 19, 2007

    In “Walk through arrays with foreach” you say you can’t modify values using foreach. Why?

    You could use something like
    foreach($array as $key=>$value)
    {
    $array[$key]=”new value”;
    }

  36. Tedd Sperling November 19, 2007

    Hi Chrisitan:

    Good to see your post and getting into php.

    However, I have to disagree with:

    Don’t do that.

    Use instead:

    Sure it’s a bit more typing, but using short tags is not recommended for a variety or reasons, one of which includes readability.

    Also, check out the use of heredoc with variables in css, as I show here:

    http://sperling.com/examples/pcss/

    It make doing css a bit easier.

    Cheers,

    tedd

  37. Tedd Sperling November 19, 2007

    Arrg:

    With above I meant:

    No:

    <?= $out ?>

    Yes:

    <?php echo($out) ?>

  38. Christian Montoya November 19, 2007

    I guess I need to break that habit now.

  39. Jeena November 19, 2007

    Anyway, I forgot to tell you: great post, man. Really useful,

  40. Jach December 4, 2007

    Some pretty good tips (I’ve grown fond of the Heredoc syntax myself), but in any case: “There should be one–and preferably only one–obvious way to do it.”

    Stuff like <?= is a bad idea. Just do

    As for the conditionals, I find it much nicer to just put the braces where they logically should go instead of on their own lines all the time:

    if (blah) {
    // something
    } else {
    // something
    }

    Switches are worthless if your condition has any complexity to it, and when you start putting cases and their predicates and the break on the same line readability severely drops.

    My own personal tip is to always validate your input, especially when you are inserting or retrieving things from a database. A function I’ve used:

    function escape_data($data) {
    global $dbc;
    if (ini_get('magic_quotes_gpc')) {
    $data = stripslashes($data);
    }
    return mysqli_real_escape_string($dbc, trim($data));
    }

    Which reminds me: if you have PHP >= 5, use mysqli stuff.

    As for using multiple files for form processing and the like, that brings in tricky things especially if you don’t consistently code against redirecting if the page is accessed directly. I love PHP Redux, Andrew made some good points for it. Besides, if the user is using Firefox it will ask them if they really want to resubmit the POST data if they decide to reload for some reason.

  41. What is PHP? December 7, 2007

    Thank you. Some of these tricks I know and use, some are new. The idea about everything being an array is great!

  42. Emilio July 13, 2008

    Talking about this point: “Walk through arrays with foreach”. Currently you CAN edit data in the array. Here is an example:

    $numericarray = array(0,1,2,3,4,5,6,7,8,9);

    foreach($numericarray as $key => $number)
    {
    if($number===5)
    {
    $numericarray[$key]=0;
    }
    }
    print_r($numericarray);//5 got replaced to 0

    Also, makes code unreadable and it won’t work with short-tags disabled.

  43. Emilio July 13, 2008

    In the last part, the short-tag code got removed. It should be:

    Also, makes code unreadable and it won’t work with short-tags disabled.

  44. Emilio July 13, 2008

    Arggg it won’t appear correctly :S the code is

  45. Emilio July 13, 2008

    Also, makes code unreadable and it won’t work with short-tags disabled.

  46. Christian Montoya July 13, 2008

    Emilio, how about you e-mail me what you are trying to post and I will add it to the post? Or, you could use Postable to sanitize your code.

Leave a comment

Share your thoughts with the world

You can use Markdown, or you can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Please keep comments respectful and on topic.

This form is guarded by Akismet, so don't waste your time trying to submit spam. It won't work. Ever.





Stay on top of new updates at this site: Subscribe to the Feed!