UKJester's "Basic PHP Tips" Rant
I am fairly active on a few PHP based forums and I keep seeing the same questions popping up time and time again. I thought I would collect these questions and answers, together with some extra points, and present them as a handy resource.
Hints and Tips
Here are a few basic tips that I wish I had known right at the start.
- [+] Get a local version of PHP.
When I started creating code, I would write code, upload it to an internet server, test it, modify it, upload it, test it, modify it, upload it . . . which took ages and it was a real pain to try and debug anything.
What I should have done is installed PHP on my home PC and done all the testing locally. I have since installed XAMPP (very easy install) that combines Apache, MySQL, PHP and Pearl which means my PC now acts almost exactly like my internet server but I have much more control.
- [+] Error Reporting.
PHP has a feature called Error Reporting that can notify you of actual, or potential errors in your code. There are different levels of reporting and this is usually set very low on live internet servers so it doesn't show errors to your users. This is great but you need to be able to see these errors yourself. If you have followed tip 1 and installed XAMPP or similar, you can alter the Error Reporting level yourself. You can either edit the php.ini file to alter the settings for your whole (local) site or you can change the setting on each php page itself by adding the following line near the top of each page.
error_reporting(E_ALL);
This works on internet hosts as well as your local server.
- [+] Get a decent code editor (IDE).
Don't settle for using Notepad or (even worse) Dreamweaver or any other WYSIWYG editors. Do some research on the current Integrated Development Environment software (I use PhpED) as they have some very usefull features not found in simple text editors.
Syntax highlighting is extremely usefull in visually seperating various parts of your code and can actually point out common errors in your code as you write it. Debugging is also a feature often included in good IDE's and can save countless hours of trawling through code trying to track down elusive bugs.
- [+] Debugging.
When you write code, it is inevitable that you will make some errors. Most of these errors will be simple typo's, like a missed semicolon, or a misspelled function name, that should be highlighted as you write them by your code editor (see tip 3). If you miss these errors during writing, they should get picked up at run time if you have error reporting enabled (see tip 2).
Other errors can be more elusive and your first option is NOT to post your code on a forum and ask for help. That is your LAST option. Your first option is to run your code through a debugging tool, step-by-step until you discover the problem. If you don't have a debugger, sprinkle some statements like these into your code.
echo 'The array, $my_array is: '; print_r($my_array);or
exit ("This variable is: " . $a);This will help check the variables you are using are what you expect them to be, a very common cause of errors.
A little code on the end of MySQL statements can help during developement but should be removed for safety reasons before your application goes live.
Add an 'or die' command to the end of your SQL operations. For example.$con = mysqli_connect($hostname, $user, $password, $database) or die("Connect failed: " . mysqli_connect_error());This will exit the code if there is an error and give you some useful information to help you solve the problem.
Only use forums and message boards if you have already tried to find a solution to the problem yourself. You will learn more and be more satisfied if you find and squash the bug on your own.
- [+] Single and Double Quotes.
There is a lot of confusion around single and double quotes and not very much clear information about them.
Variables inside double quotes are parsed.
1: $var = "test";
2: echo "This is a $var";
3: // Prints: This is a test
Variables inside single quotes are printed as text.
1: $var = "test";
2: echo 'This is a $var';
3: // Prints: This is a $var
You can concatenate (join) strings either way because variables outside quotes are always parsed.
1: $var = "test";
2: echo "This is a " . $var;
3: // Prints: This is a test
4: echo 'This is a ' . $var;
5: // Prints: This is a test
You can use single quotes inside double quotes (or vice versa) without problems.
1: echo "This is 'not' a problem";
2: // Prints: This is 'not' a problem
If you want to use (for example) double quotes inside double quotes you need to 'escape' the inside set with a backslash (so they are displayed as literal characters and not parsed as quotes).
1: echo "This is \"not\" a problem";
2: // Prints: This is "not" a problem
- [+] Escaping and Filtering data.
Some of the data that you use in your scripts is set and used inside the script and is safe to assume that it has not been tampered with.
Some of the data in your scripts could have been changed by unscrupulous users and may contain nasty code that can do serious damage to your application.
How do you know what has been tampered with and what is safe?
You don't, so you must escape and filter all data that could have been changed. This includes all data that originates from outside the current iteration of your script (including $_POST data sent to the same page because this is from an earlier iteration of the script).
Incomming Data
Data coming into your application (for example: from a database using a SQL call, from user input using a form, from $_POST, $_GET, $_SESSION from another script etc. etc.) should be filtered before you use it.
Outgoing Data
Data going out of your application (to a database, screen, email etc.) should be escaped to make sure the recipient gets the data you want it to get.
This is extremely important. - [+] Code Commenting.
Adding comments to your code makes it much easier to follow. A particular favourite of mine is to comment the start and end of major sections of code (the setting of initial variables, the creation or inclusion of functions etc).
1: ///////////////////////////////////
2: // GET AND SET INITIAL VARIABLES //
3: ///////////////////////////////////Don't go overboard by commenting everything though. The following code, for example, is obvious enough so doesn't need commenting.
1: if ($var == "test"){
2: echo "This is a test";
3: }
- [+] Comparison Operators.
Comparing variables is something you will be doing in every script you write. The basics are fairly straight forward but there are a few things you need to remember.
You need two equals signs if you want to check if variables are the same value.
1: if ($a == $b)
2: // $a is the same value as $b
You can use other operators.
1: if ($a < $b)
2: // $a is less than $b
3:
4: if ($a >= $b)
5: // $a is greater than or equal to $b
6:
7: if ($a != $b)
8: // $a is not equal to $b
This is fine if you are comparing variables of the same type (two integers for instance) but gets a little more complicated if you are comparing different types of variable.
I won't go into detail here but you can read about PHP's Type Juggling or check the PHP Manual for more detail. - [+] Functions.
Once you start getting stuck into PHP you are bound to jump into a fairly large scale project at some point. Your pages will start getting messy, your PHP will start getting mixed up with your HTML and you will find you are replicating code all over the place.
Functions are the answer (well, partly anyway).
Creating functions is an easy way to save you RSI but letting you write commonly used code just once, then referencing it whenever you need it.For example, say you have a website that has several forms where your users can send you information. You need to validate all the input from a user (NEVER TRUST USER DATA) but you don't need to write the same code on every form to validate the input. You can write a file called validate.php that contains the validation code and just include or require this page in all of your forms. An example validation function could be ...
1 : function check_text($data, $problem)
2 : {
3 : $function_error_message = "";
4 : $data = filter_var($data, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP);
5 : if (strlen($data) < "1" || strlen($data) > "1000"){
6 : $function_error_message = $problem;
7 : }
8 : $cleandata = array("data" => "$data", "error" => "$function_error_message");
9 : return $cleandata;
10: }You can then include the page before you run the checks on the form input ...
1: require ("validate.php");
2: $detailsarray = check_text($_POST['Details'], "The DETAILS must be between 1 and 1000 characters.");
3: $details = $detailsarray['data'];
4: $error_message .= $detailsarray['error'];
This will take the form value ($_POST['Details']) and a possible error message and run them through the function (check_text). It will return the validated value for $details and if there was an error it would add the error message to $error_message. If you ever change the validation script, you only have to change one page.
You can even use functions in a single page. Create the function near the top of your code then just call the function when you need it.
Writing functions is also a great way to get you into the habit of writing open code that can be used in multiple environments rather than writing closed code that will only work exaclty where it was written. - [+] Reference Sites.
As with any new language, there is a lot to learn and remember with PHP. The following links may come in handy.
PHP.net
Read it, download a copy, keep it open at all times.Zend Developer Zone
This is more of a collection of short but in-depth, connected tutorials than just a reference site. I found this site quite late but their PHP 101 set of (currently 15) tutorials is great!W3 Schools
Ok, I am adding this link with some cautionary notes. The first thing you need to understand is that W3Schools has no links or affiliation with the W3C. Their site contains some bad practices, some badly explained examples, some misleading examples and some examples that are just plain wrong.
On the other hand though, they explain things in a way that is easier for non-nerds to understand. I usually check W3Schools first, then confirm the info is correct on PHP.net.
In particular, I find their Function List very handy.Daniweb
Sometimes Google just doesn't give up the goods and you will need to ask some real humans for help. Daniweb is the forum site I use and they have a great community of very knowledgeable, like-minded enthusiasts. They won't tolerate idiots or rude people though and won't just answer questions unless you show that you have put some effort into it yourself. Like I said before, a forum should be your last port of call, not your first.
If you go on Daniweb, act like a Muppet and I flame you, you deserved it :)
FAQ
Common questions that keep getting asked.
- [+] What is PHP and what can it do?
PHP, rather absurdly, stands for "PHP Hypertext Preprocessor".
It is a common scripting language used to make websites dynamic and actually do stuff rather than just display stuff. You do not use PHP to write websites, you use PHP to add functionality to websites.
PHP is a server side language, which means the php code is processed on the server. Once it has finished, the result of what the PHP did is sent to the browser for the user to see. If you 'View Source' of a PHP page, you will not see any PHP code as this is never sent to the browser.
- [+] What do I need in order to build a modern website?
You will need to know (or learn) the following languages to the proficiency listed.
- HTML - Good understanding.
You will be writing the main structure of your website in HTML (or the strict version, XHTML) so knowing this is a must. If you are new to all of these languages, HTML(5) is the first one you should learn. The basics are fairly simple and won't take you long to learn. - CSS - Basic knowledge.
Cascading Style Sheets are used to add the styling to your website. HTML creates the structure of your website and contains the data, CSS creates the style of your website detailing colours, positioning and the overall look. CSS goes hand in hand with HTML really but is arguably less important. Your sites will look better if you understand CSS. CSS is the type of language that you never fully learn as it is constantly being updated and improved. Try to keep up with the flow if you want to be any where near cutting edge, graphically. - PHP - Good understanding.
PHP is used to change your website from a photo into a movie. Don't just display information, present it! Make it respond to your users and entertain them. You want a website people will enjoy using, and keep coming back to, so you NEED to know PHP. PHP is also an evolving language with new feature sets being added to open up new possibilities for website developers. Join a forum or mailing list to keep up to date with the latest PHP developments. - SQL - Optional. Basic Knowledge.
If you are using PHP to make killer sites, sooner or later your are going to need a database. MySQLi is one of the most common database and is the one I use but they all do more or less the same job, store lots of data. Whether the data is usernames and passwords, or the entire works of Shakespear, a database can store and sort all the information quickly and easily. Learning the very basics of MySQLi (or PDO or whatever) will not take long at all and will allow you to perform lots of data sorting tasks. Delve deeper into the language to learn how to manipulate data in more complicated and usefull ways. - JavaScript - Optional. Basic knowledge.
JavaScript is a client side language, which means it runs in your web browser so it can change the way a page would normally look and act. Although I say this is an optional language, if you want to perform a host of extremely handy little tricks you should learn JavaScript. Calendars, picture viewers, form validation, page redirects and much, much more can be accomplished with JavaScript. Two spin offs from JavaScript are becomming very popular due to the possibilities they open up. JQuery is a set of javascript tools compressed into a very tiny package. Most designers are using JQuery to perform all their JavaScript trickery instead of adding lots of separate scripts. AJAX is a way for the server to communicate directly with the browser without the need for the page to be reloaded. A simple example of AJAX is how Google searches for things as you type and displays the results without you having to click a 'Search' button.
- HTML - Good understanding.
- [+] How can I stop people stealing my code?
It depends what type of 'code' it is.
If it's PHP, the user won't ever see it as it's a 'server-side' language. It is processed on the server and the result is sent to the users browser. The user can only ever see the HTML that was generated by the PHP. The only way PHP can be seen by the user is if you have a broken server setup or if you have deliberately added measures to allow it.
If it's HTML, CSS or JavaScript the code needs to be sent to the users browser so it can be interpreted, so the full source is available on the users computer. It's a 'client-side' language.
There are ways to obfuscate (hide) your code but there are also ways of easily cutting through any unneeded clutter. There are no reliable ways to stop client-side code from being seen by people that really want to see it.
Code Examples
Some questions can only be explained with the help of sample code.
The examples shown here are not for complete beginners but some of the examples may be explained in greater detail in my other rants.
- [+] Ticking checkboxes on forms.
Let's say you have a form that displays data from a database and on this form there is a checkbox. How do you tick or untick this box depending on the value in the database?
1: // Assuming $my_checkbox is the value (1 or 0) already retrieved from the database.
2: <?php
3: $che = "";
4: if (isset($my_checkbox) && $my_checkbox == '1'){
5: $che = "checked='checked'";
6: }
7: ?>
8: <input type='checkbox' name='My_Checkbox' value='1' $che /> - [+] Dropdown List Links.
Let's say you have a form that displays data from a database and on this form there is a dropdown list. How do you turn the list into links so when a user clicks the link, the result is sent to another page (without having to click a submit button)?
1 : // Assuming $con is a valid database connection, MyTable is your database table name and MyList is the name of the table column.You can retrieve the chosen value (from destination_page.php) with
2 : $sql = "SELECT * FROM MyTable";
3 : $result = mysqli_query($con, $sql);
4 :
5 : echo "<script type='text/javascript'>
6 : function makeLink()
7 : {
8 : var link=document.getElementById('YourSelectField').value;
9 : window.location.replace('destination_page.php?ListSelection='+link);
10: }
11: </script>";
12:
13: echo "<form id='my_form' method='post' action=''>";
14: echo "<select id='YourSelectField' name='YourSelectField' onchange='makeLink()'>";
15: echo "<option value='Please Choose'>Please Choose</option>";
16: while ($row = mysqli_fetch_array($result)){
17: echo "<option value='$row[MyList]'>$row[MyList]</option>";
18: }
19: echo "</select>";
20: echo "</form>";$_GET['ListSelection'][note] Even though the form 'method=post', you still retrieve the values with $_GET due to the way the JavaScript function works. Also note that the results are sent to the page defined in the JavaScript function, not the 'action' tag of the HTML form.
Common Errors and Pitfalls
This is a list of a few common mistakes and errors encountered by people learning PHP.
- [+] Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given
Consider the following code:
1: $con = mysqli_connect('my_hostname', 'my_user', 'my_password', 'my_database');
2: $table = "user"; //Note: This is a non-existant table.
3: $result = mysqli_query($con, "SELECT * FROM $table WHERE Username='ukjester'");
4: echo mysqli_num_rows($result);This code may give the message Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in D:\xampp\htdocs\my_page.php on line 4
Let's break the error message down to understand what it is saying to us.
- Firstly we are told that it is a warning message, not an error message.
- The next part of the message explains that the mysqli_num_rows function didn't expect the parameter it was given. It expected the result of the query but it was given a boolean (TRUE or FALSE) value.
- The last part of the message shows us that the problem was found on line 4 in the file my_page.php.
Knowing whether it is an error message or warning message won't help us fix the problem, but it's good to know what the difference is.
When the PHP parser encounters an error, it stops processing the code on that line. If the parser encounters a warning, however, it will try to carry on running the rest of the code.When the message tells us the problem was encountered on line 4, this means the parser was happy running the code until it got to this line. It does NOT mean the problem is on this line. It means we start looking on this line, then move backwards through our code until we find the problem.
In our example, the error was encountered on line 4 when the parser tried to count the number of rows it returned from the database query. The mysqli_num_rows function wasn't given a database result, it was given the value FALSE because the query on line 3 failed. The query failed because it was given a non-existant table name on line 2.
If we had used the advice about debugging that I gave earlier, we would have been given a much better warning message.
Change line 3 of the code to:3: $result = mysqli_query($con, "SELECT * FROM $table WHERE Username='ukjester'") or die("MySQLi error on line 3. " . mysqli_error($con));We now get the helpful message MySQLi error on line 3. Table 'my_database.user' doesn't exist.
- [+] Parse error: syntax error, unexpected T_STRING
Consider the following code:
1: <?php
2: $message = "Hello World"
3: echo $message;
4: ?>This code will give the message Parse error: syntax error, unexpected T_STRING in D:\xampp\htdocs\my_page.php on line 3
The error message is slightly confusing because it looks like there is an error on line 3. What the message actually means is that PHP was happy working through your code until it got to the start of line 3, when it found a character it didn't expect to find.
The error is BEFORE line 3!
Start from line 3 and work backwards. The message said it found an unexpected character (T_STRING) so this probably means you forgot an ending tag, brace or semicolon.
In our case, we forgot a semicolon at the end of line 2.A good code editor with Syntax highlighting would point out this type of error as you write the code and should be the basis of your PHP toolkit.
- [+] Warning: Cannot modify header information - headers already sent
Consider the following (rather useless) code:
1 : <html>
2 : <head>
3 : <title>My Page</title>
4 : </head>
5 : <body>
6 : <p>Hello World</p>
7 : </body>
8 : </html>
9 : <?php
10: header("location:new_page.php");
11: ?>This code will give the message Warning: Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\my_page.php:9) in D:\xampp\htdocs\my_page.php on line 10
To understand this problem, we need to first understand how 'headers' are involved in the flow of a webpage.
To grossly over simplify things:- When your PHP webpage is parsed by the server, any code outside of <?php ?> tags (even blank lines) is treated and sent as 'header' information.
- Using the php function header("location:new_page.php"); is sending 'header' information.
- Header information can only be sent once.
In our example we see that we have sent HTML code between line 1 and line 8, then used the PHP header function on line 10. We have tried to send header information twice, so get the warning message.
Correct solution - Code Layout.
When writing your pages, place the PHP (that does stuff) at the top of the page, then place the HTML (that displays the stuff PHP did) at the bottom of the page. Most of the time it really is that simple.Commonly suggested solution - Output Buffer.
Although placing ob_start(); at the top of your page, and ob_end_flush(); at the bottom of your page will work, this is more of a hack than good coding practice.To solve this problem, try to arrange your code correctly first, and in very rare cases, use the output buffer.