I deal with alot of different coders from all walks of life and man, have I seen some nasty code. Its really important when coding in a team that certain practices are followed so that the codebase takes on a readable and easier to work with format.
I apply these practices whenever I can and expect anyone working with/form me to do the same.
1. PHP OPEN TAGS
Never use shorthand or ASP style PHP start tags. Always use full PHP tags.
1 2 3 | <?php echo $code ?> //correct <? echo $code ?> //incorrect <% echo $code %> //incorrect |
2. NAMING CONVENTIONS FOR FILE NAMES
Use lowercase letters and hyphens to seperate the descriptive words in a file name. This method allows the file structure to be more easily readable.
1 2 3 | my-new-file.php CORRECT! my_new_file.php INCORRECT! mynewfile.php INCORRECT! |
3. NAMING CONVENTIONS FOR VARIABLES
We never use camel case variable names and we always use underscores in order to make the variables easier to read. This allows variables to be almost self commenting.
1 2 3 | $this_is_variable //correct $ThisIsAVariable //incorrect $This_Is_A_Variable //incorrect |
4. SINGLE OR DOUBLE QUOTES
Use single and double quotes when appropriate. If you’re not evaluating anything in the string, use single quotes.
correct: ‘this is a string’
incorrect: “this is a string”
5. CLEVER CODING
In general, readability is more important than cleverness or brevity.
1 | isset($var) || $var = some_function(); |
Although the above line is clever, it takes a while to understand if you’re not familiar with it.
So, just write it like this:
1 2 | if(!isset($var)) $var = some_function(); |
6. COMMENTING CODE
In order for other coders to pick up the code easier rather than having to guess what each and every function does, its very important to put in php code comments. It does not have to be a life story but a few short comments telling what certain custom lines do is always a big help when troubleshooting code.
Here is a good example of commenting.
1 2 3 4 | //check if the $var variable is set and if its available execute some_function() //added by craig@123marbella.com on 24/12/2013 if(!isset($var)) $var = some_function(); |
7. AVOID NESTING USING EXCESSIVE IF AND ELSE
If you have a long piece of code that is dependant on various logic in order to continue to execute or exit then its better to split up the code into blocks and use logic parameters.
In the example below, we exit the script at the top of the page allowing us to easily trouble shoot each section of code.
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 20 | function write_file_function() { // ... if (is_writable($folder)) { if ($fp = fopen($file_path,'w')) { if ($stuff = extractSomeStuff()) { if (fwrite($fp,$stuff)) { // ... } else { return false; } } else { return false; } } else { return false; } } else { return false; } } |
Obviously, the code on the above is difficult to read and understand. To enhance the readability,it is always possible to reduce the level of nesting as follow:
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 | function write_file_function() { if (!is_writable($folder)) { return false; } if (!$fp = fopen($file_path,'w')) { return false; } if (!$stuff = extractSomeStuff()) { return false; } if (fwrite($fp,$stuff)) { } else { return false; } } |
8. SETTING VARIABLES
If you are setting a variable then you need to leave a space either side of the = sign. This makes it easier to identify new variables within the code.
1 2 | $var = 1; //correct $var=1; //incorrect |
9. NEVER HARD CODE ROOT DIRECTORY PATHS
When you are building an application its a bad idea to hard code a root directory path because if you move the application to a different server, the application path might be different resulting in the application breaking and you having to make manual changes to code.
1 2 3 4 56 7 8 9 10 | //Never hard code file paths like this, its a bad idea $path = "/home/some_user/public_html/includes/some_dir/"; //Get root path of the site on the server $root = realpath($_SERVER["DOCUMENT_ROOT"]);$path = "$root"; #outputs /home/some_user/public_html/ $path = "$root/includes/some_dir/" #outputs /home/some_user/public_html/includes/some_dir/ |
10. USE THE DRY APPROACH
DRY stands for Don’t Repeat Yourself, and it’s a valuable programming concept, no matter what the language. DRY programming, as the name implies, is ensuring that you don’t write redundant code.
This code:
1 2 3 4 56 7 8 9 1011 12 13 | //embedded approach (incorrect) $mysql = mysql_connect('localhost', 'some_user', 'secret_hash'); mysql_select_db('some_db') or die("cannot select DB"); //Now using DRY approach (correct) $db_host = 'localhost'; $db_user = 'some_user'; $db_password = 'secret_hash'; $db_database = 'some_db'; $mysql = mysql_connect($db_host, $db_user, $db_password); mysql_select_db($db_database); |
11. DO NOT TRUST THE USERS – PROTECT AGAINST SQL INJECTION
If you don’t escape your characters used in SQL strings, your code is vulnerable to SQL injections. You can avoid this by either using the mysql_real_escape_string, or by using prepared statements.
1 2 | $username = mysql_real_escape_string( $GET['username'] ); //correct $username = $GET['username']; //incorrect |
12. PROTECT PHPINFO
The php info file is a very useful tool during development or troubleshooting process, however leaving it in a live location on a web server is a really bad idea. Use $_SERVER[‘REMOTE_ADDR’] to lock down the phpinfo file to your own ip address.
Here is how to lock down the phpinfo to your ip address.
1 2 3 | if($_SERVER["REMOTE_ADDR"] == "255.255.255.255") { phpinfo(); } |
If you have more than one user on the team and need to allow multiple ip’s then use the following code.
1
2
3
4
56
7
8
9
| $allowed_ips = array( "255.255.255.1", //my ip "255.255.255.2", //my buddys ip "255.255.255.3" //someone elses ip "; if(in_array($_SERVER['REMOTE_ADDR'], $allowed_ips)){ phpinfo(); } |
13. PHP ERROR LOGGING
The php error log is an essential tool when developing applications as you can see through the logs any major issues that will cause your users any possible disruptions.
Firstly, you should define the location of your php error log and then lock down access to the log file so malicious users cannot see any details about possible vulnerabilities on your system.
Add the following lines to your root php.ini file.
1 2 | log_errors = On error_log = '{path_to_error_log}/PHP_errors.log' |
After that you need to make sure no-one can view the file online so you need to lock it down through the .htaccess file like so:
1
2
3
4
56
7
8
9
| ###################################### # PREVENT PHP ERROR LOG FROM BEING READ (see php.ini) # added by craig@craig-edmonds.com ###################################### <Files PHP_errors.log> Order allow,deny Deny from all Satisfy All </Files> |
14. SET TIMEZONE
Depending where the hosting server is located you should define the correct timezone for the application. For example, if the server is located in New York but the owner of the site is in London and they work on London time, then you should be setting the timezone to London otherwise any dates inserted through php, will be logged in New York time, which is not helpful for the client at all.
Simply add the following line to your php.ini file.
A full list of timezone formats can be obtained from http://php.net/manual/en/timezones.php
1 | date.timezone = "Europe/London" |
15. DONT HARD CODE URLS IN YOUR SOFTWARE MORE THAN ONCE
This is an extension of the DRY approach, but if a url (or setting) is to be used multiple times throughout an application, then avoid hardcoding the url.
Rather, use a “define” to define the url throughout the whole application. This way if something changes in the settings, then you do not need to go about changing it manually.
16. DONT USE $_GET TO PASS HTML/MESSAGES TO YOUR PAGES
If you need to post a message on a thank you page, NEVER pass any text through the GET parameter. Its possible through Cross Site Scripting someone could inadvertently post html/links/malware to your web pages through a browser request.
1
2
3
4
56
7
8
9
| //this is BAD $message = $_GET['message']; echo $message; //this is BETTER$message = $_GET['message']; if($message = 'thanks') { echo 'Thank you for filling in our form'; } |