Thursday, 12 April 2012

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 dont cause serious problems but they reduce effect of programs 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 its 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 its 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 dont cause serious problems but they reduce effect of programs 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 codes 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 programs 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 variables 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 its 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 files 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 ($fp1024) )

  {
    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 its 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 its 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 programs 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 youve 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 companys 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 isnt obvious, you are to add information about purpose of this part. Later youll 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 dont use $idx because
          // we dont need access to the single elements
          // of the massive weights

          
$randomAr[] = $element;
        }
      }
    }
    else {
      
$randomAr $elements;
    }

    
$random_element mt_rand (0count ($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. Its 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?! Its 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 codes speed its 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 codes 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 codes 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 havent used standard PHP functions.
And finally this makes program slower. The reason is not only the necessity to process larger codes volume but also the fact that the call of such users 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 (its 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 doesnt mean that you have to rewrite a code and replace them by standard functions.

16. Client part of a program isnt separated from its server part

Many programmers recommend uniting HTML code (interpreted on the clients side) with PHP code (which is done by server) into one big file.
Perhaps, its 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"
;
    }
}
?>
Its obvious that this code is easier to read. Another advantage of this conceptions 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
  • Its 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 users 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 templates 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 dont 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.
  • Its 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 shouldnt rewrite it according to the new rules of the language. You simply shouldnt use it when writing new programs.
Example of old language constructions usage:
<?php

  
// Old style

  
while (1):
    print 
"5";
    if ( 
$idx++ == ):
      break;
    endif;
  endwhile;

  
// Youd better write so:

// (anyway you may optimize the code)

  
while (1)
  {
    print 
"5";
    if ( 
$idx++ == ) {
      break;
    }
  }
?>
Why should you follow the new standards? The reasons are following:
  • Old constructions usage isnt 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 codes 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 youll never have to write users functions doing the same work as the standard ones.

Summary

In this article weve treated the first 7 from 21 mostly common errors of a PHP programmer. As a rule they didnt 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 dont have enough time to analyze all the languages 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 youve made.
  • Too many time variables: its 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 shouldnt 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.