21 errors of a PHP-programmer. Part I.
Seven ‘childish’ errors are described (21-15 backwards according to the grade of their importance in our classification). Such errors don’t cause serious problems but they reduce effect of program’s work and are also expressed in a bulky difficult to read code which is also difficult to change.
:One of the main advantages of PHP is its disadvantage at the same time: PHP is very easy to learn. This attracts many people but in spite of its false easiness it’s rather difficult to learn right and effective usage of this language.
As a rule we deal with insufficient programming praxis. Inexperienced programmers face the necessity of complicated web-applications creation. Thus the mistakes are frequently done which an experienced programmer could evade such as unjustified usage of printf() function or wrong usage of PHP semantics.
In this series including three articles the most typical from our point of view errors are presented. These errors may be classified on some categories from non-critic to the fatal ones. Together with these errors’ analysis the ways of their evading are described and also some little tricks which have been collected for many years of programming praxis are presented.
Audience of the article
This series of articles is meant for those PHP-programmers who want to evade the mostly common errors in the code writing. The reader is at least supposed to know general PHP syntax; some experience of practical language usage is also very desirable.
Introduction
One of the main advantages of PHP is its disadvantage at the same time: PHP is very easy to learn. This attracts many people but in spite of its false easiness it’s rather difficult to learn right and effective usage of this language.
As a rule we deal with insufficient programming praxis. Inexperienced programmers face the necessity of complicated web-applications creation. Thus the mistakes are frequently done which an experienced programmer could evade such as unjustified usage of printf() function or wrong usage of PHP semantics.
In this series including three articles the most typical from our point of view errors are presented. These errors may be classified on some categories from non-critic to the fatal ones. Together with these errors’ analysis the ways of their evading are described and also some little tricks which have been collected for many years of programming praxis are presented.
Part I: 7 ‘childish’ errors are described (21-15 backwards according to the grade of their importance in our classification). Such errors don’t cause serious problems but they reduce effect of program’s work and are also expressed in a bulky difficult to read code which is also difficult to change.
Part II: The next 7 error (14-8) which are classified as ‘serious’. They lead to the considerable reduction of code’s completion speed and scripts’ safety reduction; the code becomes even more complicated.
Part III: Description of the last seven ‘fatal’ errors. These errors are conceptual on their nature and cause errors described in the 1st and 2nd part of the article. They include such errors as insufficient attention paid to the project as a whole and to the program’s code as their part.
21. Unjustified usage of printf() function
Function printf() is meant for the output of formatted data.
For example, it should be used in case of necessity of variable’s output in the format with a shifting comma with definite accuracy or in any other case when we have necessity in changing of output data format.
Below the example of justified printf() function usage is given. In the given case it is used for the formatted output of ‘pi’ number:
<?php
printf ("Number Pi: %2f\n<br>\n", M_PI);
printf ("This is also number Pi: %3f\n<br>\n", M_PI);
printf ("And this is Pi: %4f\n<br>\n", M_PI);
?>
Notice: There are some cases of pathological fear caused by printf() function when people sometimes write their functions of formatted output having 30-40-strings length though all the problems could be solved by a single printf() function usage.
Many programmers use printf() function for the output of variables, results of functions’ requests and sometimes even for usual text data. Two following cases are the most frequent:
- When you should use print() function;
- By the output of results returned with functions.
Cases in which you are to use printf()
Function printf() addressing is often used in cases where you should use print(). In the following example function print() is used for the output of four variables:
<?php
$name = "Sterling Hughes";
$job = "Senior Engineer";
$company = "DesignMultimedia";
$email = "shughes@designmultimedia.com";
printf ( "My name is %s\n<br>\n
I work %s, %s\n<br>\n
My e-mail address is:%s\n<br>\n",
$name, $job, $company, $email );
?>
In the given case it’s possible (and desirable!) to use print():
print " My name is $name\n<br>\n
I work in $company, $job\n<br>\n
My e-mail address is: $email\n<br>\n";
Usage of print() instead of printf() in cases of non-formatted data output, as in the given example, has following advantages
- Increasing of productivity: function printf() formats its arguments before output. Thus the time of its execution is more than for functions print() or echo().
- Clearer code: nevertheless you should admit that usage of printf() function complicates code reading (for those who have sufficient experience of programming on C it is, of course, not so important). In order to evade unexpected behavior of printf() you should know syntax of the given function (%s determines string output format and %d the decimal one) and knowledge of variables’ types as well.
Usage of printf() function for output of the meaning returned by function
Another typical error in function printf() usage is output of the meaning returned by function as in the following example:
<?php
printf ("%d entrances of string %s are found", count ($result), $search_term);
?>
Beside print() function by its usage for the same purposes you are to use operator "." In the given case this operator adds text to the result of the function selection:
<?php
print "Found " .
count ($result) .
" entrances of string $search_term";
?>
Usage of operator together with function print() allows to evade usage of the slower function printf().
20. Wrong application of the language semantics
Many programmers use PHP in their work without actual understanding of its peculiarities. One of such peculiarities is the difference between syntax and semantics of PHP.
- Syntax of PHP represents a set of rules for the language elements’ definition. For example, how do we define a variable? We put sign $ before its name. How do we define a function? In general case by usage of brackets, arguments and so on.
- PHP semantics represents a set of rule for the syntax usage. For example, we take a function with two arguments which is defined with its syntax. As arguments it should have transferred variables of the string type which is defined by semantics.
Mention: I said ‘should’. In the languages with precise types’ separation (such as Java or C) there is no such idea as should (in the general case though exceptions are possible). In such a case compiler will make you use variables of the strictly defined type.
Languages in which the definition of variables’ types itself is absent offer us more flexibility in writing a code. But nevertheless in case of wrong semantics usage for the most of PHP functions you are to expect appearance of an error message.
We take a part a code which opens a file and puts it out string-by-string:
<?php
$fp = @fopen ( "somefile.txt", "r" )
or die ( "Cannot open file somefile.txt" );
while ($line = @fgets ( "$fp", 1024)) // Error!
{
print $line;
}
@fclose ("$fp") // And here is also color
or die( "Cannot shut file somefile.txt" );
?>
In this case such error message appears:
"Warning: Supplied argument is not a valid File-Handle resource in tst.php on line 4"
("Attention: the argument cannot be a file’s descriptor")
This is caused by the fact that variable $fp is concluded into double inverted commas what certainly defines it as a line by the time when function fgets() awaits as the first argument for descriptor, not for string. Accordingly you are to use a variable which may contain descriptor.
Notice: In the given case the string type is admitted syntactically.
To solve this problem you are simply to delete double inverted commas:
<?php
$fp = @fopen ( "somefile.txt", "r" )
or die ( "Cannot open file somefile.txt" );
while ( $line = @fgets ($fp, 1024) )
{
print $line;
}
@fclose ($fp)
or die ( "Cannot shut file somefile.txt" );
?>
How to evade wrong semantics application?
In the given example an error message is generated. But PHP gives a programmer more freedom than other traditional programming languages. This enables getting interesting results. At least it’s theoretically possible to write a correct code by wrong language semantics usage.
But be careful playing your games with language semantics! Errors which are difficult to catch may appear in programs. If you decided to do some experiments anyway, you are to understand three main points:
- Types. In PHP each variable in every period of time is related to the definite type. And this is in spite of the fact we can change its type freely. In other words, a variable cannot exist in PHP language without being related to definite type (and, accordingly, without having characteristics which are significant for this type). There are 7 basic variables’ types in PHP: Boolean, resource, integer, double, string, array and object.
- Vision area. In PHP variables have their vision area which defines from where it can be available and how long it will exist. Insufficient understanding of ‘vision area’ conception may result into ‘shifting’ errors of different kind.
- php.ini. By writing a code you should understand that not all users have the same configuration of program and machine resources as you do. Thus it’s quite necessary to make sure one more time if the working ability of your code will be saved in the configuration in which the program should work not in that it was worked out.
19. Insufficiently or excessively commented text
Badly documented program text testifies to selfishness of a programmer. All efforts of your program’s analysis in order to improve it result in nothing but headache. Auto documented code is considered to be a good form by all the programmers; but at the same time these programmers write comments rather seldom.
You should also evade excessive comments. It is also seen rather seldom and also creates such source which is difficult to read. The following example illustrates that:
<?php // Beginning of the code
$age = 18; // Age is equal to 18
$age++; // Increase $age for one year
// Type a greeting
print "Now you are 19 which means you’ve already been:";
print "\n<br>\n<br>\n";
// Cycle ‘for’ to put out all
// all the before going meanings of age
for ($idx = 0; $idx < $age; $idx++)
{
// Type each age meaning
print "$idx years \n<br>\n";
}
// The end of the code
?>
Anyway, where is the golden mean?
So what commentaries’ value should be put into a script? It depends on many reasons: on the time you have, on the company’s policy, on the complication of the project and so on. Nevertheless you are to memorize some basic principles which you should follow when writing a program independently from your decision:
- Always place commentary with purpose of the function before its body.
- Add commentaries in questionable parts of a code when you are not sure it will work properly.
- If the purpose of the code isn’t obvious, you are to add information about purpose of this part. Later you’ll use this commentary yourself.
- Evade commentaries of type # - use only /* */ or //.
Following example illustrates good commentary style:
<?php
// Random_Numbers.lib
// Generation of random numbers of different type
mt_srand((double)microtime()*1000000);
//
// mixed random_element(array $elements[, array weights])
// Returns random element of massive-argument
// Massive weights contains relative probabilities
// elements’ selections
//
function random_element ($elements, $weights = array())
{
// For the correct functioning of this algorithm
//quantity of massive elements must be equal to
// the quantity of elements in relative probabilities massive
if (count ($weights) == count ($elements)) {
foreach ($elements as $element) {
foreach ($weights as $idx) {
// Notice: we don’t use $idx because
// we don’t need access to the single elements
// of the massive weights
$randomAr[] = $element;
}
}
}
else {
$randomAr = $elements;
}
$random_element = mt_rand (0, count ($randomAr) - 1);
return $randomAr [$random_element];
}
?>
18. Too many variables – too much time for accomplishment
Some people are obsessed by the idea to insert variables in all the possible and impossible places. It’s quite impossible to understand what guided the man who wrote such code:
<?php
$tmp = date ("F d, h:i a"); // it means date format February 23, 2:30 pm
print $tmp;
?>
What is the time variable used for?! It’s simply unnecessary:
<?php
print date ("F d, h:i a");
?>
Unfortunately many programmers cannot manage to give up this bad habit. Usage of time variables makes program accomplishment slower. For increasing of code’s speed it’s better to use sub-functions when possible. Usage of time variables often increases time of scripts’ accomplishment nearly at a quarter.
Another reason to evade over usage of time variables is worsening of code’s reading ability. Compare the two examples given. Which of them looks more sophisticated – with time variable usage or without it? Which code is easier to read? Usage of spare time variables leads to writing a code which is not so clear and easy to read.
Advantages of time variables’ usage
Input of time variables allows simplifying some complicated expressions or functions’ requests. They also bring some profit when let us evade repeated function request with the same arguments.
Here is the example without spare variables’ usage:
<?php
// string reverse_characters (string str)
// Reverses characters’ string
function reverse_characters ($str)
{
return implode ("", array_reverse (preg_split ("//", $str)));
}
?>
The result of sub-functions accomplishment is transferred to the function implode() call as one of the parameters so such code is difficult to read. In the given case we can be helped by time variable usage a lot:
<?php
// string reverse_characters (string str)
// Reverses characters’ string
function reverse_characters ($str)
{
$characters = preg_split ("//", $str);
$characters = array_reverse ($characters);
return implode ("", $characters);
}
?>
Golden rule
If you ponder about question whether you need one more time variable, ask yourself two questions:
- Will you use this variable at least twice?
- Will the code’s reading ability improve a lot with its input?
If you asked ‘yes’ on any of this questions, then you can insert a variable. Otherwise combine functions’ calls (if necessary) and evade its usage.
17. Rewriting of standard functions
Some people recommend to rename standard functions in order to make Visual Basic programmers’ transfer to PHP usage easier:
<?php
function len ($str) {
return strlen ($str);
}
?>
There are also some recommendations about renaming of sub-functions with more familiar name when stating programming on PHP.
There are at least two reasons not to do this. First and the most important is that we get a code that is more difficult to read. People who read your code will see a lot of obviously useless function and will be surprise a lot with the fact you haven’t used standard PHP functions.
And finally this makes program slower. The reason is not only the necessity to process larger code’s volume but also the fact that the call of such user’s function will take you more time than direct call of a standard function.
Use standard language functions!
Sometimes we can hardly resist! A programmer seldom knows all the functions’ set at all – he usually has no time to memorize them all. Why not to rename a function? But, we repeat it, you are to evade this because of the reasons described before.
It would be great to have an available manual on PHP functions (it’s convenient to use indexed version in PDF format). And before writing some function you are to look attentively if it already exists in the standard functions’ list.
But it should be mentioned that you may see in program codes such users’ functions which have been written before their input as the standard ones. It doesn’t mean that you have to rewrite a code and replace them by standard functions.
16. Client part of a program isn’t separated from its server part
Many programmers recommend uniting HTML code (interpreted on the client’s side) with PHP code (which is done by server) into one big file.
Perhaps, it’s not so bad for small sites. But when your site starts increasing you may face problems of necessity to add some new functions. Such programming style results into ‘naughty’ and bulky code.
API functions
If you are going to separate PHP code from HTML code, you have two variants. The first method is to create functions of dynamic code formation and place them into necessary part of web-page.
For example, like this:
index.php – code of a page
<?php include_once ("site.lib"); ?>
<html>
<head>
<title><?php print_header (); ?></title>
</head>
<body>
<h1><?php print_header (); ?></h1>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="25%">
<?php print_links (); ?>
</td>
<td>
<?php print_body (); ?>
</td>
</tr>
</table>
</body>
</html>
site.lib – The program code itself
<?php
$dbh = mysql_connect ("localhost", "sh", "pass")
or die (sprintf ("Cannot connect to MySQL [%s]: %s",
mysql_errno (), mysql_error ()));
@mysql_select_db ("MainSite")
or die (sprintf ("Cannot select data base [%s]: %s",
mysql_errno (), mysql_error ()));
$sth = @mysql_query ("SELECT * FROM site", $dbh)
or die (sprintf ("Cannot send a request [%s]: %s",
mysql_errno (), mysql_error ()));
$site_info = mysql_fetch_object ($sth);
function print_header ()
{
global $site_info;
print $site_info->header;
}
function print_body ()
{
global $site_info;
print nl2br ($site_info->body);
}
function print_links ()
{
global $site_info;
$links = explode ("\n", $site_info->links);
$names = explode ("\n", $site_info->link_names);
for ($i = 0; $i < count ($links); $i++)
{
print "\t\t\t
<a href=\"$links[$i]\">$names[$i]</a>
\n<br>\n";
}
}
?>
It’s obvious that this code is easier to read. Another advantage of this conception’s usage is the possibility to change design without modification of the program code itself.
Advantages of API functions’ usage
- Relatively clean and clear code
- Fast code
Disadvantages of API functions’ usage
- It’s not so visual as templates’ system
- You need some knowledge of PHP for design modifying
Templates’ system
The second method which is used for the PHP and HTML code separation is the usage of templates. In this case some design elements are replaced with user’s tags and the program itself scans file for their presence and replaces them with the necessary information.
Example of templates’ usage:
<html>
<head>
<title>%%PAGE_TITLE%%</title>
</head>
<body %%BODY_PROPERTIES%%>
<h1>%%PAGE_TITLE%%</h1>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="25%">%%PAGE_LINKS%%</td>
<td>%%PAGE_CONTENT%%</td>
</tr>
</table>
</body>
</html>
Then we write a program which runs over template’s code and replaces tags of type %%SOME%% with necessary information by the output.
Notice: rather suitable class for usage in the templates’ system – FastTemplate, it can be loaded on http://www.thewebmasters.net/.
Advantages of templates’ usage:
- Extremely easy and clear
- You don’t need any of PHP knowledge to change templates.
Disadvantages of templates’ usage:
- This is slower method – you need to scan the whole template and only after this put out the data.
- It’s more complicated in the practical usage.
15. Usage of ‘out of date’ syntax and functions
Some programmers keep on using old libraries and old devices. For example code which has been written for PHP 2 is still used with PHP4 although already from PHP3 version new standard functions were added that realize the same.
Usage of ‘out of date’ functions and syntax can reduce speed of code execution and, besides that, make it unreadable. Other programmers may have no idea about old functions. But nevertheless if you met a part of old code, you shouldn’t rewrite it according to the new rules of the language. You simply shouldn’t use it when writing new programs.
Example of old language constructions’ usage:
<?php
// Old style
while (1):
print "5";
if ( $idx++ == 5 ):
break;
endif;
endwhile;
// You’d better write so:
// (anyway you may optimize the code)
while (1)
{
print "5";
if ( $idx++ == 5 ) {
break;
}
}
?>
Why should you follow the new standards? The reasons are following:
- Old constructions’ usage isn’t widespread and thus the PHP-beginners will be confused when watching two different syntax variants.
- Old syntax differs from other programming languages and so by transfer to PHP from another language it will be more difficult to a programmer to understand and get accustomed.
- But the main thing is that in one of new versions supporting of the old syntax will, perhaps, be excluded and thus this will make you to rewrite a code. Anyway brackets will always be the part of PHP language.
Similar code’s parts may be seen in many programs. Usually you are to obey the rules which are described in PHP documentation which is mostly renewed – it reflects the language development. Time-by-time you should look through the documentation thus the language is developing and new functions appear. So you’ll never have to write users’ functions doing the same work as the standard ones.
Summary
In this article we’ve treated the first 7 from 21 mostly common errors of a PHP programmer. As a rule they didn’t disturb working ability of programs but nevertheless you should evade them:
- Unjustified usage of printf() function: it should be used for the formatted data output only.
- Wrong language semantics’ application: many programmers don’t have enough time to analyze all the language’s peculiarities what later results into wrong code.
- Badly commented code: always write comments! Before each function indicate what the given function does and which arguments it demands. Also comment difficult code parts and the changes you’ve made.
- Too many time variables: it’s good to use time variables to evade repeated call of a function or functions’ succession.
- We do useless things – rewrite a standard function: first look up the PHP manual if the function you are going to write for extension of the standard PHP functions’ set is described there.
- PHP and HTML codes are mixed: try to make your code as much modulated as you can. Then you (and others) will be able to change design of a page without changing PHP code.
- ‘Out of date’ language constructions and functions are used: you shouldn’t always do what you can. Look up PHP documentation and literature to find out how to write correctly. Wonderful books are ‘Web Application Development with PHP’ and ‘Professional PHP’.



