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"
;
=
"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
,
);
?>
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
"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!
{
$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
(
$fp
,
1024
) )
{$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"Now you are 19 which means youve already been:"
;
"\n<br>\n<br>\n"
;
// Cycle for to put out all
// all the before going meanings of agefor (
$idx
=
0
;
$idx
<
$age
;
$idx
++)
{
// Type each age meaning
"$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
(
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.
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
$tmp
;
?>
What is the time variable used
for?! Its simply unnecessary:
<?php
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 stringfunction
reverse_characters
(
$str
)
{
returnimplode
(
""
,
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 stringfunction
reverse_characters
(
$str
)
{
$characters
=
preg_split
(
"//"
,
$str
);
$characters
=
array_reverse
(
$characters
);
returnimplode
(
""
,
$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
) {
returnstrlen
(
$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
);
functionprint_header
()
{
global$site_info
;
$site_info
->
header
;
}
functionprint_body
()
{
global$site_info
;
nl2br
(
$site_info
->
body
);
}
functionprint_links
()
{
global$site_info
;
$links
=
explode
(
"\n"
,
$site_info
->
links
);
$names
=
explode
(
"\n"
,
$site_info
->
link_names
);
for ($i
=
0
;
$i
<
count
(
$links
);
$i
++)
{"\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
):
"5"
;
if ($idx
++ ==
5
):
break;
endif;
endwhile;
// Youd better write so:
// (anyway you may optimize the code)
while (
1
)
{"5"
;
if ($idx
++ ==
5
) {
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.