7 More Mistakes Commonly Made by PHP Developers

Tweet

Back at the end of June, TopTal, the freelance marketplace, published a post about 10 Most Common Mistakes PHP Programmers Make. The list wasn’t exhaustive, but it was well written and pointed out some very interesting pitfalls one should be wary of – even if I wouldn’t personally list the mistakes as very common.

I encourage you to give it a thorough read – it has some truly valuable information you should be aware of – especially the first eight points. A couple days back, Anna Filina expanded on the list with seven new entries. While less specific and common, her points still carry weight and should be considered when developing.

7 More Mistakes PHP Developers Often Make

I was asked by someone from TopTal to take a look at their list and potentially contribute, and some of our followers on social networks expressed an interest in seeing the list continued, too, so I’d like to take this opportunity to add some of my own entries to this list that I repeatedly need to warn my team members or followers about.

1. Using the mysql extension

This news is quite old, but the number of developers oblivious to the fact is worrying. When using SQL databases, specifically MySQL, far too many developers still opt for the mysql extension. The mysql extension is officially deprecated. It’s insecure, unreliable, doesn’t support SSL and is missing some modern MySQL features. It also generates deprecation notices which don’t break your app, they just appear at the top of your app. Hilariously, what this means is that it’s also possible to simply Google for all the various sites that use this insecure setup by simply looking for this. The world of hurt those apps are exposed to due to this mess is staggering.

Instead of using mysql, opt for one of the alternatives: MySQLi, or PDO. For example, using MySQLi instead is almost as simple as adding the letter “i” to the end of the API calls:

$c = mysql_connect("host", "user", "pass");
mysql_select_db("database");
$result = mysql_query("SELECT * FROM posts LIMIT 1");
$row = mysql_fetch_assoc($result);

vs

$mysqli = new mysqli("host", "user", "pass", "database");
$result = $mysqli->query("SELECT * FROM posts LIMIT 1");
$row = $result->fetch_assoc();

That’s all it took to make the setup immeasurably more secure.

You should opt for PDO, though. More on that in point 2.

2. Not using PDO

Don’t get me wrong, mysqli is (quite literally) generations ahead of the ancient mysql extension. It’s kept up to date, secure, reliable and fast. However, it’s mysql specific. Using PDO instead would let you use some wonderfully practical object oriented syntax, and would prepare you for tango with other SQL databases like PostgreSQL, MS SQL, and more. What’s more, PDO will let you use named parameters, a feature so useful, few people can imagine going to anything else after having taken proper advantage of it. Last but not least, there’s this: you can inject fetched data directly into a new object, which is a delightful timesaver in large projects.

3. Not rewriting URLs

Another commonly ignored and easy to fix issue. URLs like myapp.com/index.php?p=34&g=24 are just not acceptable in this day and age. Due to it being incredibly difficult to write a good URL rewriting guide that would cover every server and framework out there, almost every framework has a guide on how to set up clean URLs (Laravel, Phalcon, Symfony, Zend) and any that don’t just aren’t worth using – they obviously don’t care about modern practices.

4. Suppressing errors

I wrote about this in a previous article, but it’s worth mentioning again. Any time you find yourself using the @ operator, reconsider and approach the problem from a different angle more carefully. Take my word for it when I say that 20 lines of boilerplate cURL code around an app’s functionality is better than a single line with the @ operator in front of it.

I’ve found through personal experimentation that a good approach is the one I advocate in the original post – turn all your notices into fatal errors. Making sure nothing gets logged into the error logs because there’s literally nothing to log is better than pretending poop isn’t hitting the fan by holding @ in front of your eyes.

We recently covered some Heroku add-ons for production ready PHP apps, and one of those was the excellent Papertrail – an add-on which lets you push all your app’s errors to their backend for easier searching, grouping, and elimination later on; so even if some errors do happen, it’s better to let them be logged and get rid of them by fixing your code, than silencing them and playing dumb in front of your users.

5. Assigning in Conditions

Even experienced developers sometimes have a slip of the finger and write if ($condition = 'value') { instead of if ($condition == 'value') {. Our hands will slip, our keyboards won’t register the keypress, we’ll end up pasting from another part of the code where the assignment actually happened – it happens, and we usually find out only when we run the app.

There are several ways to completely avoid this:

  1. Use a decent IDE. Any good IDE (like PhpStorm, for example) will warn you of “assignment in condition” issues when it detects them.
  2. Use “Yoda Conditions”. You’ll see these in many popular projects, even large frameworks. By inverting the comparison (as in, if ('value' = $condition) {), weaker IDEs will notice the problem, too. Some consider the Yoda syntax annoying and pointless, a lifeline where there should be none (“be more carefuly with your code, dammit”), but to each his own – if it helps someone, I’m all for it. If we were all elitists, WordPress and Zend Framework wouldn’t exist.
  3. By simply keeping it in mind, you’ll develop an eye reflex to check for it every time you write it. All it takes is practice, but it happens even to the best devs and that’s where 1. and 2. come in handy.

6. Being Too Transparent

Saying this might stir up some controversy, but here goes anyway. Unless you have 100% confidence in the framework’s developers, or don’t operate high-profit, high-traffic business critical applications, you should always strive to obscure your back-end ways – not broadcasting which framework your app is based on can actually help in preventing attacks, should a security vulnerability of that framework be discovered. For example:

In this tweet, knowledge of a serious code injection issue is being broadcast into public domain. This is great if you’re at work and can upgrade immediately without devops issues and getting the team huddled up first, but for most people and companies using Symfony, this is not the case. Even though Symfony can be upgraded via Composer (as Ryan mentioned in the comments below), it usually takes a while to get approval in large teams with multi-tier environments. All websites using this translator approach that are declared Symfony users were (are?) therefore exposed to this vulnerability until fixed.

Using Symfony in the example above was just that – an example. Similar situations have arisen with countless other software over the years. Back when I still used Zend Framework commercially, we had this happen too, and suffered an attack due to it. WordPress has had its share of security gaffes and we know how high of a percentage of websites out there they power. These things happen, and sometimes, open source and transparency aren’t the best approach when dealing with applications that carry the majority of a company’s revenue stream.

7. Not Removing Development Configurations

Last but not least, development configuration removal should be mentioned. Quite recently (and it’s an honest coincidence I’m mentioning Symfony here again), Cnet suffered an attack due to not removing their development configuration.

Cnet, one of the world’s largest tech news sites, is based on Symfony. Symfony, as you might know, features two entry points to your application: app.php and app_dev.php. By pointing your browser to one, you get the production environment. By pointing to the one with the _dev suffix, you obviously get the development version, which features a debugger, sensitive data, and more. Whether this is good or bad is a subject of many discussions (again, thanks to Ryan for pointing this out), but it’s undeniable that it opens some clumsier developers to errors such as those Cnet suffered from. What’s more, any other URLs accessed when on app_dev will get redirected to other app_dev URLs. In other words, it’s not just the index page that launches in development mode, it’s the entire website – in Cnet’s case, that’s a lot of access.

If you follow the discussion on Twitter, it gets emabrrasingly sad really fast – and what’s even sadder is that it could have been avoided in a second’s work:

  1. The devs could have removed app_dev.php from the production servers
  2. The devs could have whitelisted IPs allowed to access app_dev.php, which is how it works by default unless you loosen those restrictions up.

Either of these approaches would have completely prevented all problems. Remember, when pushing to production, make sure your development configuration is either fully inaccessible, or accessible only to a whitelisted set of IPs.

Conclusion

How do you feel about this list? Does it cover common aspects or is it too esoteric? Do you have some more common pitfalls the three posts in total have failed to mention? Let me know in the comments below and we’ll update the post if your advice is sound!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Brian Matheson

    That was helpfull thankts

  • http://knpuniversity.com/ weaverryan

    Hey Bruno!

    Just a quick comment on the last 2 points to help people :).

    1) Symfony is easy to upgrade, especially for maintenance versions (like security fixes). It involves “php composer.phar update symfony/symfony”. There’s a nice blog post about this: http://symfony.com/blog/upgrading-your-symfony-projects-the-easy-way

    2) There is a conversation on the app.php and app_dev.php and the value of it versus other approaches (https://github.com/symfony/symfony/issues/11310). It’s actually a feature that I like quite a bit and has some great advantages. But people leaving app_dev.php when they deploy is certainly a huge disadvantage (as we saw this week). As you mention, people should *not* deploy this… but of course, even the big companies sometimes don’t follow the rules :).

    Thanks for the post!

    • http://www.bitfalls.com/ Bruno Skvorc

      Thank you for these comments, I’ve altered the post to include them

  • jokeyrhyme

    I completely disagree with 6. Frankly, if you can’t keep up to date with critical security fixes, then you need to change processes at your company. The upstream project is doing the right thing by letting you know that there is an issue.

    If you can’t deal with upstream transparency, then don’t use open source libraries and frameworks.

    • Taylor Ren

      Take Symfony 2, it does have a LTS version. I think the commercially running site shall use its LTS version and patches with security leaks but without up the main rev.

    • http://www.bitfalls.com/ Bruno Skvorc

      There’s a big window in between the time when the security issue is announced, and the time when an upgrade can be run, especially in large teams and companies. LTS versions will have zero effect here, a bug is a bug. I agree with having to change the process at your company unless you can update at a moment’s notice, but if you’ve ever worked in a big one with several layers above you, you’ll know how tedious and nigh impossible it is to avoid bureaucracy and managers in situations like these, all contributing to the length of the window of insecurity.

      • jokeyrhyme

        This is still not the fault of the upstream open source project. It is your fault for not considering this risk when evaluating your choices: open source versus bespoke in-house libraries; or it is your organisation’s fault for not being agile enough.

        How on earth is an open source project supposed to fix the bug without telling everyone about the vulnerability? How can they know who to secretly notify without exposing the vulnerability to the general public?

        • http://www.bitfalls.com/ Bruno Skvorc

          If you look carefully, you’ll notice I’m not blaming the framework. In fact, the title of the post is “mistakes commonly made by PHP developers” – as in, end users of a framework in case #6. It’s absolutely and undeniably the developer’s own fault if they can’t upgrade in time, I agree completely.

          • Trent Reimer

            Jokeyrhyme is correct to say open source projects have an obligation to report vulnerabilities (at least once a patch is ready) but I have to agree with Bruno in that I did not read any “blame” in his post, just a matter of practical consideration. Blaming is just another obstacle to timely problem-solving.

            My question is, how long can one really hide their platform? Almost every major platform gives multiple clues in its HTML output. Does one take the time to build a misleading template?

          • http://www.bitfalls.com/ Bruno Skvorc

            True, but one could say all critical (i.e. people could lose jobs and money) projects use fully custom templates anyway. It’s not easy to obscure the back end completely, but it’s possible to make it opaque enough to get a delay when it’s needed.

      • jhenning

        I agree with most of what has been said in that regards, but there’s one thing a good framework could be helpful – by not putting in overdecorated default error templates and any other stuff revealing to much in the first place. Instead of fancy 500.tpl’s with expandable stack traces in all their Javascript-glory they could just provide a simple and clean error page with no fuss and focus on proper logging. Same goes for the dev-config issue. Does even a mature framework like Symfony not find a less obvious way to define which environment to use? Environment variables anybody?

  • Taylor Ren

    I have discussed a bit on the app_dev.php in my previous article for Sitepoint too. It has its merits in a way but of course, security control is topmost critical.

    BTW, @brunoskvorc:disqus, I want to translate this article into Chinese and publish it on my personal blog. Is it possible? Or do I need some more formal authorization?

    • http://www.bitfalls.com/ Bruno Skvorc

      You should take it up with @OphelieLechat:disqus

    • OphelieLechat

      Assuming @brunoskvorc:disqus is on board, that’s fine by me — send me an email to confirm, and thank you for checking!

  • ElDerecho

    I agree with every one of those, Bruno. Especially using PDO. I cringe every time I see a variable inserted directly into an SQL statement on StackOverflow.

  • Craig Buckler

    Great tips, Bruno. Part of the problem with the mysql extension is that it’s been around so long and there are far more examples on the web. Even though it’s been deprecated I suspect it’ll never be removed from PHP because it would break a large proportion of apps.

    If you have any doubts about the complexity or reasons to use PDO — try it. It’ll take a day to become familiar with the library but you’ll never look back.

    I’ve never been wholly convinced by the multi-database compatibility reasons because it’s too easy to write SQL which targets specific engines (the example above uses LIMIT is non-standard SQL and won’t work in SQL Server). However, don’t underestimate the benefits of a consistent API, prepared statements and named parameters!

    • http://www.bitfalls.com/ Bruno Skvorc

      Indeed, all good points. I hope it will get removed eventually, though, it does literally more harm than good.

      • http://dada.theblogbowl.in/ Shaumik Daityari

        The PHP site has a warning in all manual pages for mysql related functions saying that it will be removed in the future – no timeline is given though.
        http://php.net/manual/en/function.mysql-query.php

  • http://www.bitfalls.com/ Bruno Skvorc

    There’s some useful advice there, too.

  • Alessandro Pellizzari

    I don’t agree. They are maybe more common than those cited in this and the original article. So common, in fact, that even if they look “basic”, many professionals still do them.

  • http://www.orion-techs.com Oluwafemi William Babalola

    assignement in if condition :)

  • Jey Roik

    Disagree about links like par=1&par=2: it is a link (!)? not a letter to your granny! You should not be care about how it’s look. We are living in the 21th century!!! You are steel typing urls from friend by your hands?! Crazy…

    • http://www.bitfalls.com/ Bruno Skvorc

      No one is typing URLs by hand. But you’re missing out on a lot of search traffic by not using human readable URLs. You should absolutely care about the way your links look.

  • http://yapf.blogspot.nl/ vinny42

    The second argument is actually a common mistake in itself; PDO is not a magic bullet that makes accessing any database easier. In fact it can make things worse because the function calls are the same, but the underlying database behaves differently. You cannot fetch the last-insert-id in a PostgreSQL database and you will not get any warnings when you try to open a MySQL transaction that is already open.

    PDO is absolutely a much better interface for MySQL, but the interface to other databases are not as ugly as the MySQL ones, so PDO does not really solve any problems there, it just creates them.

    Speaking of other databases: give them a try sometime. I see way too many developers sticking to MySQL and perhaps MongoDB, thinking that other databases are complex and expensive and whatnot. There is a host of free databases out there, all of which can make your life as a PHP developer so much easier.

    • http://www.bitfalls.com/ Bruno Skvorc

      Excellent point, thanks for chiming in

    • http://robhammann.com Rob Hammann

      @vinny42:disqus Could you elaborate on some databases you might recommend? I don’t know about the rest of you but I often am in GSD mode and tend to take the path of least resistance when working on a PHP project. MySQL tends to be that path. However, I’m all ears if there are other developers who have tested and found other solutions that seem to work better.

      • http://yapf.blogspot.nl/ vinny42

        My personal favorite is PostgreSQL, specifically because of the GSD factor. It’s very strict about datatypes and it gives you error messages that actually mention what the error is. It has schemaless capabilities to store key/value pairs in HSTORE so you don’t have to go the EAV route. It can read/write and process JSON and XML strings so AJAX becomes a lot easier.

        It’s a bit offtopic to go into more details here, but have a look at the PostgreSQL manual about: Common Table Expressions, Windowing functions, pl/PgSQL, the INET datatype, Range types, infinity, Full Text Search (which support stemming, thesaurus and header extraction), Sequences, and CHECK constraints.

        I’m happy to answer more questions, I’m just not sure if this is the place to do it :-)

  • http://dada.theblogbowl.in/ Shaumik Daityari

    Great points.

    One thing that I like doing is create a class or a function that acts as a wrapper for all queries. That way, if some day, PDO becomes obsolete (which I am sure won’t happen any time soon), migrating the app to a different library would be pretty easy. For instance, take this queryDB class from ATutor – https://github.com/atutor/ATutor/blob/master/include/lib/mysql_connect.inc.php#L107

  • rosy lily

    I’ve made $80,000 so far this year working online and I’m a full time student. Im using an online business opportunity I heard about and I’ve made such great money. It’s really user friendly and I’m just so happy that I found out about it.

    Here ­­­­­­­­­is ­­­­­­­­­I ­­­­­started>>>>>>>>>➜➜➜➜➜➜➜

    ➜➜➜➜ W­W­W­.­W­O­R­K­J­U­R­Y­.ℭ­ℴ­m

    —————————————————–

    GO TO THE SITE –>>>CLICK NEXT TAB FOR MORE INFO AND HELP

  • http://www.bitfalls.com/ Bruno Skvorc

    Fair enough

  • Sp4cecat

    Supprising indeed.

  • gunjankumarverma

    nice article shared by you.

  • Philip C

    Thank you for the article Bruno. Being new to PHP (and enjoying it) I like to know I am learning the correct way. Having pointers like these to follow, really, really helps. I have been using PDO, yay for me? :)

    • http://www.bitfalls.com/ Bruno Skvorc

      Glad to help, and definitely points for you! :)

  • Karl Zinom

    PHP (LAMP Stack) is nearly available everywhere, at zero or very low costs, it is easy enough to learn to begin with and good enough for big Projects.

    I see nothing that could take over PHPs place in the ecosystem of server side languages in the next years.

    Trolling is not perse something “good” or “to be proud of”, so what are your intentions, kind sir? Are you ignorant, just childish or do you have a point why PHP is nothing good for a webproject?

  • http://www.xpertdeveloper.com/ Avinash

    Completely agree for not using PDO. Its far better that mysq extension.

  • Dominik

    Besides the risk of a typo (single = instead of ==), it’s because another developer reading your code will surely always have to double check and question the written expression. “Is it a mistake or was it by intention?”. Without analyzing you can’t tell the difference.

    However, I personally do use assignments in conditions, but always with this syntactic sugar:

    if (($value = foo($bar)) === WHATEVER) {
    ….
    }

    Notice the double parenthesis. An IMHO good IDE will be satified omit a warning.

  • Karl Zinom

    great Reply, thx. Makes a lot more sense than “just trolling”…

    More and more Universities and Schools start programming with python instead of PHP or JAVA. I think that is kind of a meta progress in programming. Although I mainly work with PHP and JAVA, I also would vote for python as superior. Unfortunately I do not have the time or right project to begin with python, all I ever did, was setting up an development enviroment and print “Hello World!”…

    • guix69

      …and yet with such “high experience” you claim “Python as superior”… Just trolling ;)

      Thanks to Bruno for the article. Some quite interesting points in there.

  • http://r.je Tom Butler

    Good post, However, I think “assignment in condition” is a little more complex an issue and not an “Avoid at all costs” issue as often they are intentional. For example, this is quite useful:

    if ($pos = strpos($foo, $bar)) { //do something with $pos
    }
    else //the substring wasn’t found, do something else

    While loops often utilise assignment in conditions. The old version of Zend Studio highlighted the code: while ($row = $pdo->fetch()) {} as an error, which is certainly intentional.

  • http://www.rvtechnologies.co.in/ Vikas Sharma

    Hey Bruno.
    I am new in the field of PHP development but you were right that most of the mistakes are mainly made in that areas. Even I have committed the 2nd and 5th. But for the next time, I will definately remember this post of yours.

  • http://www.skooppa.com scamo

    Thanks Bruno. Good post. I enjoyed it.

  • http://www.schmutzka.eu/ Tomáš Votruba

    I find difficult to make any of those “mistakes” (apart 6), because libs and software nowadays mostly eliminates that. I use Nette, Doctrine, Symfony, Composer and PhpStorm, so if just download these, I would have to really try to make some.

    These mistakes I would expect 2-3 years ago, when it was much easier to do it wrong. But maybe you find these mistakes for one reason: sticking to old habits, code, approach.

    So I would add just one mistake: not learning new stuff or not putting them into yours practice.

  • Dima Taras

    I love pdo. As for me it is the most usefull stuff php have introduced in the last few years.
    Even though is slower than mysqli a little but imo normal human won’t be using php for very high-load project.

  • Dima Taras

    dunno about python (seems to me its not go far from php) but I have like 5 times started to learn j2ee and all the times it was so much headache just simply to make some retarded hello world. In the installing tomcat maven or whatever (setup stage) you loose all your will to go on.

    so as Im making some simple not loaded web apps it’s like 100 times easier to make it on php although I want to leave it.

    The conclusion is simple: there must be some good tutorial to move to other language for general php dev (mostly noob) that will cover just setup, simple hello world and database integration and how the f*** to host it.

  • http://mattasbury.co.uk/ Matt Asbury

    Err… agree that it could be easy to use = instead of ==, but why are you using == and not ===? Surely that’s a bigger faux pas?