Register

If this is your first visit, please click the Sign Up now button to begin the process of creating your account so you can begin posting on our forums! The Sign Up process will only take up about a minute of two of your time.

Page 1 of 3 1 2 3 LastLast
Results 1 to 10 of 26
Like Tree1Likes

Thread: Top 21 PHP Programming mistakes

  1. #1
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    Top 21 PHP Programming mistakes Part 5

    *****
    Picked from an old article on Zend.com.
    *****

    21. Improper use of printf
    The printf() function is intended for printing formatted data.

    It should be used, for example, when you need to print out a double with two-digit precision, or any other case where you might need to change the format of your output before displaying it.

    In the example below, the correct usage of printf()is presented. The function is used to format the value of M_PI (’) to the desired precision:

    <?php
    /*
    * The three faces of ?
    */

    printf ("Pi is: %.2f\n<br>\n", M_PI);
    printf ("Pi is also: %.3f\n<br>\n", M_PI);
    printf ("Pi is also: %.4f\n<br>\n", M_PI);
    ?>
    Note: I've seen cases where people have had printf()-phobia, writing custom functions to format output, sometimes as long as 30-40 lines, when a single call to printf() would have done all of the formatting for them.

    Many programmers misuse the printf() function by using it to display variables, function call results, or sometimes just plain data. Misuse of the printf() most often takes place under one of the following scenarios:

    When the print() statement is more appropriate.
    When displaying the output of a function call.
    When print()Is More Appropriate
    Programmers often use the printf() function where the print() statement would suffice. In the following example, printf() is used to print out four variables:

    <?php
    $name = 'Sterling Hughes';
    $job = 'Senior Engineer';
    $company = 'DesignMultimedia';
    $email = 'shughes@designmultimedia.com';


    printf ("My name is: %s\n<br>\n
    My Job is: %s, %s\n<br>\n
    My E-mail is: %s\n<br>\n",
    $name, $job, $company, $email);
    ?>
    The print() function could have been used in place of printf()as follows:

    print "My Name is: $name\n<br>\n
    My Job is: $job, $company\n<br>\n
    My E-mail is: $email\n<br>\n";
    Using print() instead of printf() when you don't need to print formatted data, as in the above example, provides the following benefits:

    Faster Performance: The printf() function formats your output before it displays your text. Therefore, it will take longer to execute than a print() or echo() statement.
    Cleaner code: Let's face it, using the printf() function is a little messy for people to read (unless of course they have a C background). It requires knowledge of printf() syntax, (i.e. %s denotes a string whereas %d represents a decimal) as well as knowledge of types so that printf() doesn't mess up your results.
    Using printf() to output the value of a function call.
    Another common error is using printf() to output function call values, such as the count function shown in the example below:

    <?php
    printf ("%d occurrences of %s found.",
    count($result), $search_term);
    ?>
    When outputting function call values, the . operator should be used in conjunction with print(), as shown in the example below:

    <?php

    print count($result) .
    " occurrences of $search_term found.";
    ?>
    The . operator appends the results of your function call to the text you want to display. Using the . operator saves you from using printf(), which is slower. The reason being that it tries to format your output before it is displayed to the screen.

    20. Misapplying Semantics
    Many programmers use PHP without really understanding the finer points of the language. One fine point is the difference between PHP syntax and PHP semantics.

    PHP Syntax: Represents the body of rules for defining a PHP element. For example, how do you define a variable? Place a $ in front of the word; How do you define a function? Generally speaking, use brackets and arguments etc....
    PHP Semantics: Represents the body of rules for applying the syntax. For example, take a PHP function that requires 2 arguments as defined by its syntax. Both arguments, however, should be strings ? this is semantics.
    Notice how we say "should". For strictly-typed languages such as Java or C there is not really such a thing as "should" (with exceptions). A compiler will force you to use a type in a prescribed, exact manner.

    In loosely-typed languages such as PHP, however, you have more flexibility over how you formulate a code statement.

    For most defined PHP functions, however, you should expect an error statement if you deviate from the prescribed semantics.

    Consider the following example of opening a file and printing out all of its lines:

    <?php
    $fp = @fopen ('somefile.txt', 'r')
    or die ('Cannot open somefile.txt');

    while ($line = @fgets ("$fp", 1024)) // error
    {
    print $line;
    }

    @fclose ("$fp") // error
    or die ('Cannot close somefile.txt');
    ?>
    The example above would generate an error message such as:

    "Warning: Supplied argument is not a valid File-Handle resource in C:\Inetpub\wwwroot\tst.php on line 4."

    This is because the $fp variable was passed in double quotes, thereby making it a string. However, the fopen() function expects a resource identifier as its first argument, and not a string. You would need to maintain this argument as a resource identifier.

    Note: The string, however, was correctly typed in syntactically.

    To correct the problem you would simply eliminate the double quotes a follows:

    <?php

    $fp = @fopen ('somefile.txt', 'r')
    or die ('Cannot open somefile.txt');

    while ($line = @fgets ($fp, 1024))
    {
    print $line;
    }

    @fclose ($fp)
    or die ('Cannot close somefile.txt');
    ?>
    But could you get away with misapplying semantics?
    Our example above generated an error statement. But PHP enables you to customize your scripts to fit a unique scenario or output requirement. So, it is at least theoretically possible to "get away" with misapplying a semantic.

    Therefore, be aware of the possible outcomes if you decide to play with PHP semantics. Misapplying semantics can generate subtle errors if you're not paying attention.

    If you would like to customize your scripts you should be sure to understand the following key topics:

    Types: In PHP, every variable will have a defined type at any point in time. This is despite the fact that its type can be freely converted. In other words, a PHP variable will not exist without having some defined type (along with that type's characteristics). PHP contains 7 fundamental types: Boolean, resource, integer, double, string, array and object.
    Scope: In PHP, variables have a scope. A variable's scope determines where the variable can be accessed and for how long it will exist. Misunderstanding the concept of "scope", then, can lead to both subtle bugs and major errors.
    php.ini: When writing scripts that need to be portable it is important to understand that not all users will have the same configuration that you do. Therefore it is necessary that you add checks in your code to ensure that your code runs with the user's current configuration.
    19. Lack of Inline Documentation
    Poorly documented source code is, in my opinion, the root of all selfish programming. It can lead to incorrect fixes, misconstrued meanings and leave people who are reading your code with ear splitting headaches. In general, inline documentation is universally agreed to as being a good thing, but rarely is it present.

    There is also such a thing as too much documentation. While rare, it is also a problem because it leads to overly cluttered source code.

    The following is an example of applying too much documentation:

    <?php // Start off PHP code
    $age = 18; // assign 18 to age
    $age++; // increment $age by one

    // print out introductory text
    print "You are now 19, which means you have been:";
    print "\n<br>\n<br>\n";

    // A for loop to print out all of the
    // previous ages
    for ($idx = 0; $idx < $age; $idx++)
    {
    // Print out an individual age
    print "$idx years old\n<br>\n";
    }
    // End the PHP code
    ?>
    How much documentation?
    To what extent, then, should documentation be added to your script? It can depend on any number of things such as your budget, company policy, or a script's complexity, etc... There are, however, a few guidelines that you can follow regardless of how you decide to document your code:

    Always put a short description of the purpose of a function above the function itself.
    Add comments where things are hacks, or might appear to be wrong but that are in fact correct.
    If a piece of code seems confusing, add a little note about its purpose in your script. You'll be thankful for that note later.
    Use a consistent style of commenting, either /* */ style comments or the // style comments (avoid # style comments).
    The following is a brief example of a good commenting style for your code:

    <?php
    // Random_Numbers.lib
    // Generate different types of random numbers.

    mt_srand((double)microtime()*1000000);

    //
    // mixed random_element(array elements[, array weights])
    // Extract a random element from elements. Weights is
    // the relative probability that each element will be
    // selected.
    //

    function random_element ($elements, $weights=array())
    {

    // There must be exactly the same amount of elements as
    // there are weights for this algorithm to work properly

    if (count ($weights) == count ($elements)) {
    foreach ($elements as $element)
    {
    foreach ($weights as $idx)
    {
    // Note: we don't use $idx, since we
    // don't want to override elements.
    $randomAr[] = $element;
    }
    }
    } else {
    $randomAr = $elements;
    }

    $random_element = mt_rand (0, count ($randomAr)-1);
    return $randomAr[ $random_element ];
    }
    ?>

    18. Too many variables, too much time
    Some people have this utter obsession with temporary variables. I just can't seem to understand it whenever I see something like:

    <?php
    $tmp = date ("F d, h:i a"); /* ie January 3, 2:30 pm */
    print $tmp;
    ?>
    Why the temporary variable? It is simply not necessary:

    <?php
    print date ("F d, h:i a");
    ?>

    Unfortunately, it seems that many users have difficulty breaking out of this bad habit. Temporary variables slow down the execution time of your program. It's faster to omit them altogether and bundle the function calls together. Users who use temporary variables often add on 25% to the execution time of their scripts.

    Another reason for avoiding too many temporary variables is because they just don't look elegant. From our example above, which is more concise, the one with the temporary variable or the one without? Which one is easier on the eyes? Using too many temporary variables can lead to less readable and less concise code.

    Beneficial Uses of Extra Variables
    Temporary variables are useful for replacing long-winded functions or expressions. They can serve as an alias of sorts. This is especially true when you need to apply the function or expression a number of times.

    Consider the following example, which does not use any more variables then necessary:

    <?php

    // string reverse_characters(string str)
    // Reverse all of the characters in a string.
    function reverse_characters ($str)
    {
    return implode ("", array_reverse (preg_split("//", $str)));
    }

    ?>

    The implode function's content is long-winded and thereby difficult to read. The use of one or more temporary variables will definitely help us out:

    <?php

    // string reverse_characters(string str)
    // Reverse all of the characters in a string.
    function reverse_characters ($str)
    {
    $characters = preg_split ("//", $str);
    $characters = array_reverse ($characters);

    return implode ("", $characters);
    }

    ?>
    General Rules of Thumb
    When deciding whether or not to use a temporary variable, you should keep the following 2 questions in mind:

    Will you be using the variable at least two times?
    Will the readability of the code be significantly improved?
    If the answer is yes to either of these questions then use the variable. Otherwise, turf it and combine function calls (as necessary).

    17. Rewriting existing PHP functions
    A certain PHP source advocated changing the name of the following pre-existing function to make it easier for VB programmers to move over to PHP:

    <?php

    function len ($str)
    {
    return strlen ($str);
    }
    ?>
    Some users insist on rewriting common PHP functions instead of learning the functions the language provides in the first place.

    There are at least two reasons why this should be discouraged. First and foremost is that it leads to less readable code. People reading or modifying your code will see a bunch of (seemingly) unnecessary functions that you have written, and wonder why you defined them in this manner rather than using a PHP pre-defined function.

    Defining your own functions in this manner also slows down your program. Not only is there more code to be processed, but every time you call a user-defined function that imitates a pre-existing function, you've added execution time to the function call's overhead.

    Avoid Rewriting Pre-existing PHP Functions
    Let's face it. Sometimes it's hard to resist. After all, a programmer can't possibly keep up with all of PHP's functions at once, and who has the time to look things up? Why not just rewrite it?

    What I do to avoid rewriting existing PHP functions is to have a copy of the PHP Manual handy whenever I'm writing a program (I use the indexed PDF version). Then, if I need to write a function that "extends" PHP's functionality, I'll peruse through the manual to check if that function already exists.

    However, it must be noted, due to the open source nature of PHP, you might discover user-defined functions defined before they were added to PHP's functionality (such as finding the difference between two arrays). This doesn't necessarily mean that you should have to correct the code.

    16. Not separating client side from server side
    Some programmers insist on clumping the entire program together, meaning the HTML (client-side) with the PHP code (server-side) into one enormous file.

    While this may be fine for smaller sites, it can develop into a real problem as a site begins to grow bigger and more features are added. Programming in this manner can lead to the problem of extremely hard-to-maintain and unwieldy files.

    Function API
    When it comes to separating client-side code from server-side code there are a couple of options. One method is to create functions that will display the dynamically generated content and then place those functions in the correct place on the web page.

    The following example illustrates this concept:

    index.php ? The Client side

    <?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 server side code


    <?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 database [%s]: %s",
    mysql_errno (), mysql_error ()));

    $sth = @mysql_query ("SELECT * FROM site", $dbh)
    or die (sprintf ("Cannot execute query [%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";
    }
    }
    ?>

    As you can see from the above example, separating the client-side code from the server-side code adds to the code's readability. Another benefit is that once you have your API functions for displaying data, you can have your designers go in and change the basic layout of the page without requiring you to modify the code.

    Advantages to the function API
    Relatively clean
    Fast, almost no overhead
    Disadvantages
    Not as clean or easy as the template system.
    Requires some PHP knowledge to modify the template.
    Template System
    Another method for separating client-side code from server-side code is to use a template system. That is, to have little placeholders for content and then having your program parse the file, replacing each placeholder with the necessary information.

    For example you could have a file like:

    <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>

    You could then write code that would parse the file and replace the information inside of the %% delimiters with the appropriate information.

    Note: A good class which enables template systems is the FastTemplate class, available from http://www.thewebmasters.net/.

    Advantages to the Template system
    Extremely clean.
    No Knowledge of PHP required to modify the template.
    Disadvantages
    Slower; You need to parse the entire template file and then output it.
    More complicated to implement.
    15. Using Outdated Paradigms
    Many users seem to use the same outdated code and libraries over and over again. For example, they may have written a function using PHP 2 and still use it with PHP4, even though a function that achieves the same purpose was added in PHP3.

    Using outdated paradigms can slow down your script, as well as make it unreadable. Readers of your script might not be familiar with PHP's outdated functions. Nevertheless, if outdated code is discovered, don't feel it is necessary to replace it. Just be sure to avoid using this code for future scripting.

    An example of an outdated paradigm, which many programmers seem to grasp onto, is the beginControlStructure .. endControlStructure; syntax:

    <?php

    // Bad/Outdated Practice

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

    // Better Practice
    // (the code could be optimized though)

    while (1)
    {
    print "5";
    if ($idx++ == 5) {
    break;
    }
    }

    ?>
    This is a bad practice for the following reasons:

    It is not widely used, and therefore, many people learning the language will be confused by the two syntaxes.
    It is not compatible with other languages, meaning that it is harder to read for people who are transitioning.
    Most importantly, someday in the future it might be disabled, forcing you to rewrite the code that implemented it. Brackets, however, will always be a part of the PHP language.
    The above is but one outdated paradigm example seen in a great amount of PHP code. There are more. As a rule, you should follow the style present in the PHP manual. For the most part it is up to date. It also uses the latest functions for its examples. Regularly check the manual if you're considering extending PHP's functionality. In this manner, you won't end up writing functions that already exist.


    ********
    htmlcode likes this.
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  2.  

  3. #2
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    Top 21 PHP Programming mistakes Part 4

    14. Not Following Basic Naming Conventions
    One of the most serious errors that a programmer can commit is to define a poor naming convention. I've taken over projects where I've had to spend numerous hours just trying to understand the program because the programmer decided to name its variables $fred and $barney instead of common sense names such as $email and $name. I am referring to a project where the incumbent programmer decided to give the entire program a Flinstones naming theme (no joke).

    How you assign names to your variables and functions is central to building readable scripts. Many programmers make the mistake of defining variables and functions with names that:

    Are too brief or too long.
    Do not relate to the script's context.
    Do not take into account case sensitivity.
    Inhibit code readability (functions in particular).
    Variable Naming
    Case Sensitivity
    In PHP, variable names are case sensitive, meaning $user and $User are completely different symbol table entries. Some users exploit this feature by having variables with the same name but using different cases. This is a horrible practice. Case should never be used to differentiate between variable names. Every variable name in the current scope should be absolutely unique.

    Names that are too short
    Many users assign cryptic acronym names to their variables and then later regret having forgotten what they meant in the first place. Variable names should describe the content that they (will) contain, using either complete words or understandable abbreviations.

    Names that are too long
    On the other hand, some users use variable names that are far too long. Generally speaking, a variable name should not be longer than two words. The two words can be separated by a '_' or delimited by having the second word begin with an uppercase letter.

    Good Practice
    The following are good examples of variable names:


    $username = 'sterling';
    $password = 'secret';

    $teachers = array ('Sadlon',
    'Lane',
    'Patterson',
    'Perry',
    'Sandler',
    'Mendick',
    'Zung');

    foreach ($teachers as $teacher);
    Bad Practice
    The following are some exaggerated examples of poor variable naming:

    $username_for_database = 'sterling';
    $guMbi = 'secret'; // for the $password

    $thelastnamesofteachers = array ('Sadlon',
    'Lane',
    'Patterson',
    'Perry',
    'Sandler',
    'Mendick',
    'Zung');

    foreach ($thelastnamesofteachers as
    $TeaChER);
    Function Naming
    All of the concepts that apply to variable naming also apply to function naming. However, grammar is particularly relevant for functions.

    Note that PHP functions whether built-in or user-defined are not case sensitive.

    Using Verbs
    PHP functions are equivalent to a spoken language's verbs. Function names, therefore, should be action oriented. They should also be defined in the present tense.

    For example, if you have a function that generates a gaussian random number, it should convey that it uses the gaussian distributed random number formula as follows: generate_gaussian_rand().

    Note the usage of the action verb in the function name. This places the function in its proper context:

    <?php
    list ($num1, $num2) = generate_gaussian_rand();
    list ($num3, $num4) = generate_gaussian_rand();
    ?>
    By way of comparison, consider the following:


    <?php
    list ($num1, $num2) = gaussian_rand_generator();
    list ($num1, $num2) = gaussian_rand_generator();
    ?>
    See the difference? This second example uses a noun as the function title rather than an action statement. While the function's purpose is still conveyed, its title inhibits a fluid reading of the code.

    Use a verb!

    13. Not Thinking Things Through: Databases & SQL
    It is truly amazing the number of ways people concoct to access a database and retrieve a result set. Examples that I have seen include combinations of if statements with do .. while loops, multiple calls, and sql_result() functions inside of a for loop.

    What do these people think they are doing?

    Writing hit-or-miss code demonstrates a lack of focus. Individuals who direct their efforts on just getting the job done rather than on getting the job done right, end up costing their benefactors plenty of time and money down the road.

    Incorrect data sampling is a good example of this problem. Some coders do not take the time to think things through. True, there might not be a single "correct" way of data sampling, but there are plenty of incorrect ways.

    This section covers the following areas under this topic:

    Misapplying database functions
    Misusing SQL: Not fetching what you need
    Using PHP to sort the results
    Misapplying database functions
    One PHP source advocated the following syntax for retrieving result sets from a database (presented below using a generalized set of SQL functions):


    if (!($row = sql_fetch_row ($result))) {
    print "An error occurred: no rows found";
    exit;
    }

    do {
    print "$row[0]: $row[1]\n<br>\n";
    } while ($row = sql_fetch_row ($result));
    Note: In the above, and subsequent examples, $result represents the handle or pointer to a query's result set. In other words, a query has already been submitted and a set of results has been extracted from a database. The examples deal with how we should effectively work with this result set.

    There are a couple of problems with this code:

    It checks for the "no incidents" case by fetching rows.
    It does not store the result set into an associative array.
    Checking for No Rows ($result): The wrong way
    By using sql_fetch_row() , the PHP source advocated an implicit approach to determining whether or not there are any incidents of $result. A more direct or explicit method is to count the number of rows having $result using sql_num_rows()as shown below:


    <?php

    if (sql_num_rows ($result) <= 0) {
    print "An error occurred: no rows found";
    exit;
    }

    while ($row = sql_fetch_row ($result)){
    print "$row[0]: $row[1]\n<br>\n";
    }

    ?>
    Getting rid of the Do..While loop
    First and foremost, the nasty do..while loop is no longer needed because when using sql_num_row(), we do not initially fetch the first row of the result set into $row when checking for the empty set.

    The PHP Source presented an example where, if the result set was not empty, the set's first row would be received by executing sql_fetch_row() within the if statement. The do..while structure is required under these circumstances because a fetch to the database will always advance the counter. Therefore, you must process the first row ("do") initially since it has already been retrieved. The next fetch execution would retrieve the second row and so on.

    Why is the do..while considered "nasty"?

    The example only presents one loop action ? a single print statement. Imagine if we had 10 actions in the loop. A code reviewer would have to search through the code for the while condition after the do statement. An annoying exercise.
    While conditions generally begin a structure rather than completing it. A reviewer must be extra careful not to confuse the ending while condition of a do..while structure for the beginning while condition for a standard loop.
    Keeping things straight and simple
    For the emply result set case sql_num_rows()gets straight to the point, while sql_fetch_row() does not:

    sql_fetch_row()says "I found no rows in the result set. This must mean that there are none."
    sql_num_rows()says "The number of rows in the result set is 0."
    But what difference does this really make?

    Consider the same comparison, but this time within the context of the if condition and expressed in Pseudo-code:

    if(!($row = sql_fetch_row($result))){Print Error}:
    Fetch a row from the result set.
    If the result set is empty, assign $row a value of 0; Zero has the boolean value of False, so consequently !(0) = True; Print the error message.
    Otherwise, if the set is not empty, retrieve the first row and assign it to $row; $row is not zero and has a boolean value of True. Consequently !(True) = False, and continue with the do..while structure.
    if((sql_num_rows($result)<= 0){Print Error}:
    Count the number of rows in the result set.
    If less or equal to 0, Print the error message.
    Otherwise, continue.
    Which expression is easier to comprehend? Clearly, counting the number of rows is more straight-forward.

    What is the practical difference now? From one simple if statement, there is not much to be gained one way or the other.

    However, for over 10,000 lines of script code, taking the time to think of the clearest way of writing code can save a reviewer hours of analysis (to name just one benefit). Other benefits can include faster and more fluid development of your scripts.

    When your DBMS does not support sql_num_row()
    Some DBMS's may not support the sql_num_row() function. I offer my sympathies to you if your DBMS happens to be one of them. You will have to search for the empty set case by fetching rows. However, even under these circumstances it is preferable to use a boolean variable as follows:

    <?php

    $found = false;

    while ($row = sql_fetch_array($result)){
    $found = true;
    }

    if (!$found){
    print "Error";
    }
    ?>
    Fetching the result set: being useful
    A second problem with this code is its use of the sql_fetch_row() function to fetch the result set. The sql_fetch_row() function will only return a numerically indexed array. The sql_fetch_array() however, returns both a numerically and string indexed array as follows:


    $row = sql_fetch_array ($result);
    print $row[1]; // Second column
    print $row[name]; // The name column
    Note: There are different conventions regarding the use of quotation marks when adding a string argument. In the name column above and throughout this article, it was decided to leave them out.

    From a developer's point of view, which function will provide a coder with a more useful result? String indexed arrays enable a reader to understand exactly what is being fetched from the database just by reading the code, as shown in the corrected example below:


    <?php

    if (sql_num_rows ($result) <= 0) {
    print "An error occurred: no rows found";
    exit;
    }

    while ($row = sql_fetch_array ($result)) {
    print "$row[name]: $row[phone_number]\n<br>\n";
    }

    ?>
    When sql_fetch_row($result) should be used
    I'm not really a fan of the sql_fetch_row() function. However, there is one situation in which it may be used without decreasing readability ? when the user defines the query.

    The examples to this point have been dealing with a known query that was generated by the developer. Sometimes you may have the user define his/her own query. Under these circumstances you will not know the number of columns in the result set.

    Therefore, you can use the sql_fetch_row() function along with the count() function, to effectively process the columns in a row:


    <?php

    for ($i = 0; $i < count($row); $i++){
    print "Column". ($i + 1). $row[$i]. "\n<BR>\n";
    }

    ?>
    Misusing SQL: Not Fetching What You Need
    As a matter of practice, it is simply wrong to use PHP to process the rows of an entire database. I've seen cases where people had used PHP to run a simple search over a 2MB database and then wonder why the language was so slow. Fetching 2 MB of data from the database will take forever.

    Standard Query Language (SQL) was specifically designed to query and retrieve data samples from your tables. The idea is to filter out the unnecessary data (using SQL), leaving a relevant data set from which to work (using PHP).

    If you are fetching more data records than are necessary, it's a sure sign that the SQL code being applied has not be optimized.

    The WHERE Clause
    A classic example of the effective use of SQL is in regards to the where clause.

    Consider the following section of code that retrieves a result set and prints out the user's name and phone number whenever it encounters a row where the id field is equal to 5:


    <?php

    //
    // The connection is established and $conn is
    // defined as the connection handle before this
    // code.

    $statement = "SELECT name, phone, id FROM samp_table";
    $result = @sql_query ($statement, $conn);

    if (!$result) {
    die (sprintf ("Error [%d]: %s",
    sql_errno (), sql_error ()));
    }

    if (@sql_num_rows ($result) <= 0) {
    die ("No results retrieved from Database");
    }

    while ($row = @sql_fetch_array ($result)){
    if ($row[id] & 5) {
    print "Name: $row[name]\n<br>\n";
    print "Phone: $row[phone]\n<br>\n";
    break;
    }
    }

    ?>
    The code above is not optimized; we're using PHP to search through an entire database set! While this might not be significant when working with smaller sized databases, as the size of your database increases you'll definitely feel a big performance hit.

    The solution is simple: modify your SQL statement to contain a WHERE clause:


    $statement = "SELECT name, phone FROM samp_table";
    $statement .= " WHERE id='5'";
    The WHERE clause enables you to be more selective when extracting results from a database. The where clause's limit of the selection is a function of it's argument. In the above example that argument is "id=5".

    Now that you've selected the desired data set, you can use PHP to simply print out your data thereafter:


    if (@sql_num_rows ($result) != 1) {
    die ("Incorrect number of results retrieved from DB");
    }

    $row = @sql_fetch_array ($result);
    print "Name: $row[name]\n<br>\n";
    print "Phone Number: $row[phone]\n<br>\n";

    Using PHP to sort the results
    Many people grab their result sets unsorted, with the intention of subsequently using PHP to do the sorting. This is simply inefficient as SQL sorting facilities are faster than PHP.

    Use SQL's ORDER BY syntax over that of PHP's ksort() function.

    Consider the following which uses PHP's ksort() function to sort a result set by the name:


    $statement = "SELECT name, email, phone FROM some_table ";
    $statement .= "WHERE name IS LIKE '%baggins'";

    $result = @sql_db_query ($statement, "samp_db", $conn);

    if (!$result) {
    die (sprintf ("Error [%d]: %s",
    sql_errno (),sql_error ()));
    }

    while ($row = @sql_fetch_array ($result)){
    $matches[ $row[name] ] = array ($row[email],
    $row[phone]);
    }

    ksort ($matches);
    But why not sort the result set at the time it is defined? This can save us from having to run through the set of records a second time.

    Therefore, remove the ksort() function from the above script and replace the SQL code with the following, which features the ORDER BY syntax:


    $statement = "SELECT name, email, phone FROM some_table ";
    $statement .= "WHERE name IS LIKE '%baggins' ORDER BY name";
    12. Lack of Error Checking
    I have seen many scripts lacking a sufficient amount of error checking. It results mostly from programmers that do not take the time to properly plan their script and identify all the possible places where something can go wrong. Error checking should not begin after the code has been written. This lack in foresight can lead to fatal bugs that will not only generate incorrect results but may even cause your system to crash!

    Expect the worst
    All scripts have the possibility of failure under the "wrong" conditions. In order to minimize such a risk, you should plan to:

    Check the results of function calls:
    Check the results of system calls:
    Set the error_reporting level to E_ALL in your php.ini file:
    Check the results of function calls
    Whenever you call a function that returns data to be manipulated, always check to make sure that the return data is in a range of allowable values.

    In the example below, an illegal division by zero error is generated on the 6th iteration of the for loop, as $i is incremented by one while $j is decremented by one. On the sixth time through $i = $j = 0.


    <?php

    mt_srand((double)microtime() * 10000000);

    function do_math ($a, $b)
    {
    return (($a - $b) * 2) / mt_rand();
    }

    for ($i = 5, $j = -5; $i > -5; $i--, $j++){
    print $j / do_math ($i, $j) . "\n";
    }

    ?>
    Check the results of system calls
    Always ensure when you're dealing with processes or files external to PHP that everything has functioned correctly.

    A perfect example is checking the output of a system call when using a sql_connect() function. Validate the output to ensure that the connection to the database actually took place. Failure to do so can result in failed queries and lost data without you even knowing it.


    $conn = @sql_connect ($host, $user, $pass);

    if (!$conn) {
    die (sprintf ("Error [%d]: %s",
    sql_errno (), sql_error ()));
    }
    Set the error_reporting level to E_ALL in your php.ini file.
    Be sure to configure PHP to provide you with the highest level of error reporting possible. If you don't set it to the highest level at least when debugging, you might miss errors such as invalid regular expressions and incorrect values.

    Consider once more the example I gave for checking the output of function calls, shown below. Assume you set the error reporting to a lower level, say E_ERROR.

    Take note from the sample output below how the script executes the do_math function but does not report the illegal division by zero error that took place (no output was generated for $i = $j = 0):


    <?php
    error_reporting (E_ERROR);

    mt_srand ((double)microtime() * 1000000);

    function do_math ($a, $b)
    {
    return (($a - $b) * 2) / mt_rand();
    }

    for ($i = 5, $j = -5; $i > -5; $i--, $j++){
    print $j / do_math ($i, $j) . "\n";
    }

    ?>

    Sample Output:

    -5148.25
    -5271
    -323.75
    -4931
    -7713.5

    -4702.5
    -488.5
    -928.5
    -1394.75
    Custom Error Handlers
    PHP often displays execution errors to the browser, preventing you from suppressing and capturing them. However, with PHP4 you can now catch errors using the set_error_handler() function.

    The set_error_handler() function can be used to log errors that occur in your script. Instead of troubling the user with error messages, you can capture all of the errors for yourself, by setting a custom error handling function.

    In the example below, set_error_handler()is used to designate the error_handler() function as the default error handler.

    When an error takes place, error_handler()is called and PHP's error_log() function is used to log the error to the error_file file.

    If the error is of type E_ERROR, we exit out of the script and print an error message.


    <?php

    // void error_handler(string type, string message, string file, int line)
    // Custom error handler, set by the set_error_handler()
    // function.
    //

    function error_handler ($type,
    $message,
    $file=__FILE__,
    $line=__LINE__)
    {
    error_log("$message, $file, $line", 3, 'error_file');

    if ($type & E_ERROR) {
    print 'An error occurred, it has been logged
    and it will be addressed.';
    exit;
    }
    }

    set_error_handler('error_handler');

    ?>
    11. Overusing OO
    The OO paradigm is a wonderful concept. It has numerous benefits, the most notable being the ability to reuse code easily. However, as we've all come to understand: 'PHP is not an OO language'.

    While PHP does offer adequate object oriented support, it is neither efficient nor wise to use its object oriented features when you can make use of other methods to achieve the same result. The reason for this is that PHP's OO support is not full blown.

    While most of the major elements are present, PHP still lacks some of the more advanced features (such as protected membersor private variables) that a "true" OO language (For example, C++ , Java) would have.

    Nor is the code behind PHP's OO support very efficient or fine tuned. This means that when you use the OO paradigm with PHP, you may in fact be slowing down the execution time of your programs considerably.

    Note: Generally speaking, an application that uses OO support will be slower just as using eval() will be slower than normal code. To amply show places where OO support gets somewhat ugly, I'd have to use advanced PHP features and concepts, some of which have not even been documented yet.

    What can we do without OO?
    If you are coming to PHP from a language such as Java or C++ where you can't really create complex programs without using object oriented features, bypassing PHP's OO support may be difficult. Let me assure you, however, that powerful applications can be written without the use of any OO concepts and methodologies (PHP was written in C, which has no OO support).

    So for those of you unaccustomed to using non-OO practices, here are some different techniques for creating cohesive and extensible applications without the use of OO paradigms:

    Creating an API.
    Creating a naming sequence (and sticking by it).
    Grouping related functions into the same file.
    Creating an API
    Apply three layers to your program:

    First, functions that actually do the work.
    Secondly, a function API. These are the functions that you use to build the specific application,
    Thirdly, the application itself:

    MortgageRate.php


    <?php

    // The internal functions are layer 1

    // Internal function to calculate the correct
    // interest rate to be used given the amount per month
    // and the time it is to be paid in

    function _mort_find_interest_rate ($total)

    {
    if ($total < 30000)
    return (7.4);
    elseif ($total > 30000)
    return (3.2);
    elseif ($total > 50000)
    return (2.5);
    else
    return (1.7);
    }


    // The API is layer 2

    // double calculate_mortgage_rate (int money, int time, int month)
    // Calculate the mortgage rate given the
    // the total money, time its paid over and
    // the intervals

    function calculate_mortgage_rate ($money, $time, $month)

    {
    $rate = _mort_find_interest_rate ($money) / 100;
    $money /= ($time / $month);
    return ($rate * $money) + $money;
    }

    ?>

    CalcMortgage.php


    <?php

    // The actual application is layer 3

    // $money, $time and $period are submitted
    // from a form

    include_once 'MortgageRate.php';

    $price = calculate_mortgage_rate ($money, $time, $period);

    print "Your $period month cost is $price";

    ?>
    Creating a naming sequence and sticking by it.
    One of the major problems in any large project is namespace collision. Classes segment the namespace. Therefore, different classes can:

    Be assigned a property with the identical name, or
    Contain a method with the identical name.
    For example class Phillips and class Normal can both have a method named screwdriver.

    In general, before starting a large project you should define a naming sequence for everything, namely, how you separate global variables from regular variables, how you define library functions, etc.

    Grouping related concepts into a file.
    Group similar API functions into the same file just as you would group similar methods into a class. Try to think in terms of every file you create being a class in and of itself, with each function being a method. In this manner, your functions will have a clear definition and structure.

    For example you might want to group all functions related to database access in a file named DB.php.

    OO, like everything, is fine in moderation
    Let me just clarify something. I'm not advocating that you abandon PHP's object oriented features entirely. Rather, I'm just trying to warn you not to use PHP like it was Java or C++ where one would freely use OO.

    Carefully balance the benefits with the drawbacks before you decide to use an object oriented approach with PHP.

    *****
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  4. #3
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    Top 21 PHP Programming mistakes Part 3

    10. Misusing Regular Expressions
    Regular expressions are powerful tools for searching and organizing data, such as validating an e-mail address or matching a URL. However, they are also slower than some of the other tools that PHP offers for simple tasks.

    For example, if you wanted to capitalize an entire string, the novice PHP user might do the following:


    <?php

    $URL = "http://www.php.net";

    $fp = @fopen ($URL, "r");
    if (!$fp) {
    die ("Cannot open website $URL!");
    }

    while ($line = @fgets ($fp, 1024)){
    $data .= $line;
    }

    @fclose ($fp)
    or warn ("Cannot close website handle, $URL");

    $data = ereg_replace ("[a-z]", "[A-Z]", $data);

    print $data;

    ?>
    However, they would be wasting execution time by using the slower ereg_replace() to do what the lightning fast strtoupper() function would do much better:


    $data = strtoupper ($data);
    In general, you should always try to use simpler alternatives to regular expressions as it will speed up your code tremendously.

    Functions you should know
    There are a few functions that are essential to saving script execution time when used in place of a regular expression. Below is a list of these "essential" functions:

    strtoupper(); strtolower(); ucfirst(); strtr(); str_replace(); trim(); explode(); implode(); substr(); strcmp()

    If you replace your regular expression with one of the above functions you should expect to see a great jump in performance, especially as the string size that you are dealing with begins to increase.

    9. Programming PHP Like It Was Some Other Language
    Many people get started with PHP after having become proficient in another language such as Perl, C, Java or (gasp) ASP. In doing so, they bring along programming paradigms which might not always be in line with the methodologies employed by PHP.

    Unfortunately, some of these individuals fail to take the time to learn how to program PHP in a manner more suitable to PHP's way of doing things. Instead, they prefer to get PHP to work with as few new concepts being introduced as possible.

    When you program PHP like its some other language, it often leads to slower and less maintainable code. You often see people making the mistake of programming PHP like it is another show up when you see:

    Perl "one liners". PHP as a language is not really optimized for the "one-liner" approach to writing a program. Instead, expand the complicated set of combined function calls and regular expressions into a more hierarchical format.
    Perl


    while (<STDIN>) {
    @_ = split /:/;
    $quotes{shift} = shift;
    }

    print map { "$_: ", reverse split //,$quotes->{$_},"\n";
    } keys %quotes;

    PHP

    <?php

    $fp = @fopen('php://stdin', 'r');
    if (!$fp) {
    die ('Cannot open STDIN');
    }

    while ($line = @fgets ($fp, 1024)){
    list($name, $quote) = explode (':', $line);
    $quotes[ $name ] = $quote;
    }

    foreach ($quotes as $name => $quote){
    print "$name: ";
    print implode (" ", array_reverse (preg_split ('//',
    $quote)));
    print "\n";
    }

    @fclose ($fp);

    ?>
    Not using built-in functions: Many PHP programmers who come from a C background, don't seem to realize that PHP provides many built-in functions which eliminate lengthy blocks of code. If you come to PHP from C, I suggest you make sure to have a look at the PHP manual before you write a block of code to see what functions PHP has to offer to make your life easier.
    Renaming existing PHP functions: I see users rename PHP's existing functions just to make it easier for them to remember. Not only does this slow down the execution time of your program, but it also decreases the code's readability.
    Overusing OO features: PHP is not an object oriented language, while it does provide object oriented features, you should always be conscious of the fact that using PHP's object oriented features will significantly slow down your code.
    Where to get the information
    Luckily there is a lot of information out there on how to program PHP, some of the best are:

    Zend.com: Obviously. You're reading this article, right??
    Professional PHP: One of the best overall books on PHP, good for non-programmers and programmers alike.
    Web Application Development with PHP: A great book teaching both the concepts in Web development as well as some of PHP's more advanced features. Contains the official Zend API documentation.
    The PHP Developer's Cookbook: A solutions oriented book covering the common problems that PHP developers encounter (Coming out November 2000, written by myself with Andrei Zmievski).
    8. Not Being Security Conscious
    Our users will not always work within our systems. It is our responsibility as programmers to design secure and forgiving systems that will account for, and work with user mistakes.

    When designing systems you must put yourself in the mind of your user. See where they might commit errors and locate the potential security breaches. Then you can design your programs to account for those errors and eliminate the potential security breaches. It is also important to remember that while a user's errors and system attacks may be their fault, you're the one who is held responsible if you write a program with a security hole or miss a level of error checking that leaves you vulnerable to corrupt data.

    For example, I've seen many scripts that do not utilize PHP's built-in mail() function which connects in a secure way. Instead, the script will pass a users e-mail to sendmail, through the popen() This can lead to many security holes (such as /etc/passwd being sent to the end user).

    Some areas where security breaches are most common, or the potential for data corruption is greatest are:

    When making system calls. I can't stress this point enough. Always make sure that any data a user gives you is safe before passing it to a system call. NEVER TRUST THE USER BLINDLY BY PLACING THEIR DATA IN A SYSTEM CALL WITHOUT CHECKING IT FIRST.
    When registering users. If you expect accurate results, always check and make sure that the registration of the user has a few checks in place. First of all, there are many ways to validate an e-mail address. Ensure that the user has a valid e-mail address. Furthermore, you should check to make sure that the user's age is within a certain range. As generalization, you can be pretty sure there are no 200 year olds running around with the ability to operate a computer.
    When accepting credit cards. Some programmers will only use simple algorithms which can easily be spoofed when doing checks with credit cards. Always gain an account with a major corporation to check the validity of a credit card number before actually accepting the user's credit card. DO NOT TRUST AN ALGORITHM.
    System Call Security
    Whenever you place user data in a system call you're going to want to sanity check that data. Make sure that nothing dangerous is contained in the data that can "spoof" your system into executing unwanted commands. PHP offers a function that does just that: the EscapeShellCmd() function.

    Whenever you are passing a command that contains sensitive data, always escape that data with the EscapeShellCmd() function:

    Note: Escaping the data means places a backslash \ in front of characters that might be used to spoof a system (#&;ī'\"|*?~<>^()[]{}$\\\x0A\xFF to be exact).


    <html>
    <head>
    <title>Name Lookup</title>
    </head>
    <body>
    <h1>Name Lookup</h1>
    <?php
    if ($name) {
    system (EscapeShellCmd ("lookup $name"));
    print "<br>\n\n";
    }
    ?>
    <form action="<?php print $PHP_SELF; ?>" method="GET">
    Enter a name to lookup:
    <input type="text" name="name">
    <input type="submit" value="Lookup Name">
    </form>
    </body>
    </html>
    Note: While the EscapeShellCmd() is a worthy function for checking a command to make sure it is safe from spoofs, you should still try and make specific checks depending on the type of data that is being submitted. The EscapeShellCmd() will not check for the validity of the submitted data, it will just prevent the user from doing anything unauthorized.

    Taking it one step further
    As a rule, it is better to check for characters which are allowed, rather than for characters which are not.

    For example, make sure that $name only contains alphanumeric characters. In this manner, new ways of exploiting your system are less likely to slip through your filter.

    Checking an e-mail address
    One of the most common forms of validation is checking an e-mail address to make sure that it is valid. Many novice programmers will just use a regular expression that they grabbed off one of the mailing lists or from a code repository. However, a regular expression is not sufficient if you want to secure accurate results. There are a couple methods you can use, instead, that are more secure:

    Socket Validation
    InteractiveValidation
    Socket validation
    One way of validating an e-mail address without directly involving the user is to open up a socket to the server they give you for their e-mail address and check to find their username.

    Advantages

    No inconvenience to the user as everything is done transparently.
    Weeds out many phony addresses that wouldn't be caught by a regular expression (such as joe@fgsdh.com).
    Disadvantages

    Will not catch valid but mistaken addresses. For example, if John Doe submits my e-mail address, (sterling@php.net), the message will be processed, in spite of it being my address instead of his.
    Slower than using a regular expression to validate an e-mail address.
    User's mail server may be temporarily down, causing a valid address to not be recognized.
    Interactive Validation
    Another method of validating an e-mail address is by sending a special "key" to the users e-mail box, and then requiring the user to enter in that special key in order to continue. This ensures that not only that the e-mail address will be valid, but that the user will also have legal access to an e-mail account.

    Advantages

    It is the best way to ensure that a user has a valid e-mail address. (They must have access to the e-mail address they give you in order to register.)
    Disadvantages

    Requires that a user take extra steps in order to submit their data. This will annoy users intended on fooling you.
    Like every method, it is not fool proof. The user can create a temporary account with Hotmail or Netaddress and then use that account to register onto your site.

    7. Cut and Paste Coding: The Wrong Way
    I have seen novice programmers copy code that, for example, validates an e-mail address, sends an e-mail, and takes the values of a form to build an e-mail message. They would paste it all into their program with the result being a working mess of code statements that insecurely sends a form.

    While the code would work under optimal conditions, it would fail under any real test for good code. The patchwork job would not be:

    Extendible: The code will look as if it were bits of unrelated snippets slapped together. Ask an experienced programmer to modify the script and they'll prefer to re-write the entire thing. Un-readable code is un-extendible code.


    Secure: You would be placing other people's code into your scripts without fully understanding what the code does. Think about this. What if the code you copied had a bogus system call, which removed all the files from your hard drive? Moreover, the same code would not always be secure on different systems and configurations. Lastly, your program would be vulnerable to bugs inherent in other people's code.


    Fast: When code is pasted together it probably isn't very fast, since it doesn't have a logical progression - the most important thing when it comes to creating fast scripts.


    Doing It the Right Way: Learn first, Then Copy
    Study another programmer's code thoroughly before copying. Analyze what was done. Only when the code is readable, consistent with your program's logic, and free of errors, should it be considered as a candidate for copying. Integrating the code at this point will enable you to fit it with the rest of your script more smoothly.

    Libraries are Fine
    Only use PHP libraries from a trusted source such as PEAR, or the PHP Classes Repository. For pre-packaged API's, it is fine to use the extra functionality these API's can provide your program. In fact, if you can find a pre-written library from a trusted source, it is most often better to use those libraries in your code.

    6. Not Having Project Code Guidelines
    Once, when I was just starting programming, I worked on a basic project (in Perl) with three other programmers. As I was young (and I wasn't the lead developer on the project), we didn't have any coding guidelines for the project. We were each assigned a portion of the project and went off separately to do our part. When we finally got together to implement the final product (tie all the different components together), each of the different parts of the project looked completely different.

    For example, one of the programmers I worked with preferred the studlyCaps style of naming functions and variables. I, myself, preferred using underscores to delineate my functions and variables. The project leader had an even more interesting programming style. Depending on his mood he'd either use studlyCaps or underscores to delineate words in variable and function names (which actually caused some namespace conflicts which were a headache in and of themselves).

    In short, the project was a mess. It required around 20 hours more than it should've taken, if we'd taken the time to plan it out correctly and set program wide coding guidelines.

    Code guidelines are a way of defining the structure and appearance of your code, they describe the method and the style you should use when implementing your project.

    Every project should follow a set of guidelines. This would include anywhere from general issues such as how to divide the source code (i.e., file structure) to more specific issues such as the exact variable naming sequences (i.e., prefixes and suffixes, upper-casing global variables).

    Guidelines define a standard set of conventions that should be followed regardless of the programmers individual style. They can serve to define all of the unknowns in your code such as:

    Which variables are global and how they should be marked as global.


    The document structure, meaning when a certain file should be placed in the lib directory as opposed to the src directory.


    Commenting style and conventions.


    Documentation procedures.


    Line width.


    Guidelines should be written up in a formal document and adhered to by every programmer in the project. When the project is finished, this document would be stored for future reference.

    A Sample Project Guideline Document
    Let's create a very short sample guidelines document. We won't go into the specifics, but rather create a skeletal outline. It will have all the required elements but will not go into detail. An actual guidelines document could easily run anywhere from 10-40 pages. Note that you would not have to recreate these documents for every project. The template could always be modified a little bit when necessary.

    Style Guidelines for DesignMultimedia.com
    Here's an example of a Style Guidelines outline. Once you have this document completed, you can focus solely on implementing your project. You should not have to worry about inconsistent source code, naming conventions or site organization when you implement your site.

    Introduction
    This document contains the following information:

    File Structure


    Page Headers and Footers


    Code Documentation


    Commenting Style, Comment Meanings and Definitions


    Implementation Guidelines


    Variable Naming


    File Structure
    The DesignMultimedia.com application has the following structure:

    <A description of how the files for your application should be stored (i.e., what goes where), as well as the naming conventions for each file.>

    Explanation of the structure:

    <Explain each of the individual conventions so there are no misunderstandings as to what, exactly, you mean.>

    Page Headers and Footers
    Every page in the program should have the following header:

    <A page header would go here. It could be anything from some code snippet to a simple copyright.>

    For example, all the .c and .h files in PHP4 have the following standard header:

    /*
    +------------------------------------------------------------------------ +
    | PHP version 4.0 |
    +------------------------------------------------------------------------ +
    | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
    +------------------------------------------------------------------------ +
    | This source file is subject to version 2.02 of the PHP license, |
    | that is bundled with this package in the file LICENSE, and is |
    | available at through the world-wide-web at |
    | http://www.php.net/license/2_02.txt. |
    | If you did not receive a copy of the PHP license and are unable |
    | obtain it through the world-wide-web, please send a note to |
    | license@php.net so we can mail you a copy immediately. |
    +------------------------------------------------------------------------ +
    | Authors: Sterling Hughes |
    +------------------------------------------------------------------------ +
    */


    And the following footer:

    <Here you would put your sites standard footer, for example the following is found at the bottom of all the .c and .h files in PHP):>

    /*
    * Local variables:
    * tab-width: 4
    * c-basic-offset: 4
    * End:
    */

    Explanation if necessary:

    <Explain the conventions for the headers and footers, and perhaps why they're required (depending on the content of your header and footer).>

    Code Documentation
    <Here is where you lay out the specifics for how code will be presented in the application, whether it is by using the javadoc documentation style or XML documentation using the Docbook stylesheets.>

    Commenting Style
    <This describes the different types of comments used in addition to defining what any abbreviations or "phrases" mean.>

    Implementation Guidelines
    <This is the site's do's and don'ts: For example, don't keep different classes in the same file or do keep every class in its own file.>

    Variable Naming
    <For example, you can write in the following:>

    This site follows the following naming conventions:

    [1] All classes are of mixed case.

    [2] All functions are lowercase with words separated by a underscore (_).

    [3] More rules on the specific naming conventions.

    ******
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  5. #4
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    Top 21 PHP Programming mistakes Part 2

    5. Not Doing a Code Review
    The idea for this article series stemmed from a code review that I conducted for a friend. When reading his code I was able to cut the number of variables by one third, giving a 400% speed increase in database access time. Moreover, I cut the number of lines of code in half as well as other improvements which lead to a whopping 1000% overall speed increase (10 times faster).

    What's the moral of this story? Having another experienced programmer go over your code with a fine-toothed comb will greatly increase the quality, speed and security of your code. They will find bugs that you did not even realized existed and will identify easier ways of doing things. Furthermore, they will identify areas of your code that are slowing PHP down or that could be causing major security flaws.

    One of the reasons that PHP, as an open source language, makes terrific business sense, is that other developers can review code that has been committed to the PHP source. Thousands of free code reviews take place examining the PHP source code for flaws, potential crashes and leaks, compatibility breaks and speed. Therefore, by the time that a new PHP version has been released, at least 2 or 3 expert programmers have looked at committed source code.

    Ideally, scripts for a medium-sized/large project should be reviewed by at least two different programmers who were not involved with creating the source code. As with writing, fresh perspectives to a snippet of code can only be helpful. In most cases, however, you can get away with having one expert programmer reviewing the code.

    A qualified reviewer is one who can quickly assess the workings of your code and provide constructive suggestions for both code content and implementation.

    Often, it is helpful to draft a short questionnaire for the reviewer. Some examples that I have found particular helpful include:

    What is the purpose of XXX code?


    How does XXX file relate to the rest of the project?


    What is the program's standard error checking mechanism?


    Can we trace the actions of a standard user working with this program?


    Where might the user encounter errors?


    4. Hacking at Design Flaws
    You create an application and then realize that certain things were not done as well as they should have been. Hacking at design flaws is when you put in temporary patches instead of addressing the flaw's underlying, more serious problem.

    When you commit this type of mistake, it can lead to working code with serious flaws that will compromise both the speed and security of your application.

    Design Flaw Indicators
    Naturally, when you initially plan your project, you think that you're going about things in the right manner. You might not realize that you have taken a wrong path until you have already gotten into the specifics of the application's design (or within its parts thereof).

    Here are two indicators that your project plan has gone astray:

    Excessive Kludging: You are "kludging" the code. A "kludge" is a solution that makes the code work, but doesn't fit into the design of your program. Alternatively, it might not be the most optimal solution, but it is the best solution you can get within your current design.


    Over-Complicated Solutions. You find yourself doing complex operations to implement simple systems. Take the following example that uses a for loop to print out a string:


    <?php

    $GeorgeBush = "If you look at the trends, I think you'll see that most of our imports come
    from other countries";

    for ($idx = 0; $idx < strlen($GeorgeBush); $idx++)
    {
    print $GeorgeBush[$idx];
    }
    ?>
    The above code is well written; it loops through a string and prints out a quote from George Bush. It has proper indentation and correct syntax. Nevertheless, the same purpose could have been achieved by simple using a print statement on the entire string.

    Correcting Design Flaws
    When you realize that your program has been written with faults or with an non-optimal design, the necessary corrective steps can range anywhere from leaving your program as it is, to modifying only parts of the program design, all the way to re-designing the entire application.

    In most cases, it is a good idea to have someone independent of your program's development, review it and evaluate what needs to be done.

    Let's look at three categories of mistakes:

    Small, localized design flaws: Sometimes the flaws in your program design may not be that critical. Small flaws won't break the farm and aren't worth the time and money required to re-implement the flawed design.


    Corrective Action: In this case, you should take note of the flaw or the hack for further inspection. In the event that you decide to redesign and implement your application in the future, you can implement any changes at that time. An example of this might be using the incorrect type of data-structure for a particular part of your program (a numerically indexed array where an associative array would be appropriate, or a stack where a tree would be appropriate.)
    Significant, localized design flaws: In other cases, it turns out that only part of your application really needs to be re-designed. Perhaps you're creating an Operating System, and your window manager has a bunch of hacks in it, but the underlying OS code is fine.


    Corrective Action: All you'll really need to re-design is the Window Manager (not the entire OS). This is probably the most common case, where parts of the design are flawed, but the overall structure of the design is fine.
    Significant, global design flaws: Under the most extreme case, the application's infrastructure design itself is flawed.


    Corrective Action: When the infrastructure is flawed, this usually requires a complete re-organization of the code and how the different parts of your program interact. This is by far the most complex and time-consuming case, and is rarely done with projects that have progressed far enough that hacks become necessary. An example of this might be to use flat files to store all the information for a major search engine like Yahoo.
    3. Excluding the User from the Design Process
    Have you ever had the following happen to you?

    You've been assigned the task of designing and producing a corporate wide in-house application tailored specifically to your organization. You've spent hours fact finding and documenting pages of requirements. You cost out the project, assign tasks, and do it.

    Three months later you present your working model only to gain the following user feedback:

    "That's not what we wanted".


    "The requirements have changed".


    "Good, but...".


    "Err...what application?" (the original user contact left the company!!!!).


    The ultimate judge of your application's quality will be the user. By definition, they are the ones who will be using your application (and trying to abuse it in many cases). Many programmers create applications that are masterpieces in and of themselves, but nonetheless fail to meet expectations. This is often due to one or more "misunderstandings".

    Misunderstandings come about when you divorce the user from the design process. When creating an application, always keep your users in mind. Always bear in mind what they want you to do and how the application is meant to achieve that desired goal. Most importantly, however, stay in contact with them by making time for:

    Continuous User Feedback


    Prototyping


    Beta Testing


    Continuous User Feedback
    As Benjamin Franklin wrote in Poor Richard's almanac "A stitch in time saves nine." The same holds true with applications. If you want to save time in the long run it is important to have constant user feedback, having the user tell you whether the application is useful. What do they like? What don't they like? What would make the application better?

    Prototyping
    Prototyping is a structured process of testing and soliciting user feedback over the course of an application's development. Testing a web application under prototyping, then, is an ongoing phase. You begin this process by defining a user test group.

    Test the application against user requirements, but be sure to solicit direct feedback as well. Many programmers make the mistake of only testing the application after it has been completed. This can be a recipe for failure, as there often will be discrepancies between what the user really wants and what you have put together. Moreover, users get a better appreciation for what they really want when they see some tangible example. In short, user requirements cannot be written in stone (even though that's what every programmer wants).

    I suggest that you define milestones over the course of your application's development. At the end of every milestone ponder over the following:

    Does the work that you've done provide benefits to the user?


    What would they like to see in the application that isn't already there?


    Would they use this functionality that you've added?


    What is the net gain for the application?


    Do your improvements make it better or worse?


    When should milestones be set?
    Usually it is a good practice to define your milestones whenever (another) significant portion of the UI (user interface) has been completed.

    For example, I often place my first milestone when the interface to the application is first completed. This is the point when the designers have a basic template of the site laid out. The next UI test could be when you've gotten a very basic demo of the applications functionality to work.

    Thereafter, I would test the UI after the completion of every application "module" or "component". A module or component might be something like the user management system of an application, or perhaps a site search engine. At these milestones, I would take my initial test group (as well as any new testers that might be especially relevant to what I'm currently testing), and have them go over the original questions I proposed. Doing so enables you to see the "entire" effect of the modifications you've just made. You can define additional sets of questions at every milestone or stick with a standard set.

    Beta Testing
    This is a common form of testing that has the flavor of prototyping, but is often left to the very end of the process. Sample customers are given the opportunity to test out the application and submit their comments and bug reports. It is not as interactive as prototyping and really should be undertaken much earlier in the process. Nonetheless, it is a necessary task that developers should undertake before going live with their applications.

    2. Not Sticking to a Project Plan
    Many software projects these days eventually lead to "making it up as you go along". On one of my first projects, for example, I created an application based on a 40-minute phone call. Now, while the application turned out ok, the risk of failure was far greater than had I put in the proper time to plan and design the application before I went ahead and implemented it.

    For example, when I finished the project, nothing was abstracted. This means that if the user had wanted to use MySQL instead of MSSQL, the application would have needed a re-write. Moreover, much of the security was a hack implementation. I stored all of the application data in the cookie. There were a couple of other flaws - some too embarrassing to mention...

    When Fred Brooks outlined the software development cycle in The Mythical Man Month, he gave the following as an optimal schedule:

    1/3 Planning: Here is where you design the way that your application works, what are the different components of the application (and the sub-components) and how do they interact? What should the application do? Answering these fundamental questions is the basis of planning an application.


    1/6 Coding: What we all love to do. Transform the design into reality.


    1/4 Component test and early system test: When developing large applications there comes a point when the application itself might not be complete but the application is finished enough that testing of the basic functionality can begin.


    1/4 System test all components in hand: This is the final stage where we have the finished application, now the application must be tested and re-tested to make sure it is as bug free as possible.


    Today we are lucky if even 1/6 of the dedicated project time is spent on planning. Programmers begin right away, furiously pumping out code without having a clear idea of the requirements, an appreciation for the problem, or a viable approach to solving that problem. This scenario is analogous to writing a term paper or an article without having an outline.

    Coding should just be the process of placing down what you have already planned. A lot of programmers (me being one of them) go as far as writing their entire application (or tricky parts of their application) in pseudo-code prior to coding it with a real language such as PHP.

    Note: The process of planning the look, feel and functionality requirements of an application is what is known as information architecture.

    Project Phases
    There is a lot that can be said about the stages of a project plan. For example, mention can be made of debugging, flowcharting, modeling, project management and setting target dates. However, I will only cover a basic outline.

    A Standard Project Plan will include a:

    Requirements Analysis Phase


    Program Design Phase


    Testing Phase


    Requirements Analysis Phase
    The first part of planning a project is to create a requirement analysis; this is where you define exactly what is needed. You specify exactly what the program must do and how the program should work. This is one of the most important phases of designing a web application.

    Determining User Requirements
    So how do you find out what exactly the user requires for an application? Take the role of a consultant to determine their needs, namely get to know your client well. For example:

    What do they do?


    What makes their product superior (or unique)?


    How do they want to present themselves to their audience?


    What features in the site will help them reach their market?


    This last one I've found is a great way to make your projects larger. Can you find a way that adding functionality to their web site will help them? If so, you've just got a more satisfied customer, as well as a larger (and better paying) project on your hands.

    Methods of research can vary from distributing surveys or questionnaires to interviewing the key decision makers in the company. In whatever manner you go about collecting your information, it is critically important to keep the above points in mind.

    Determining Technology Requirements
    Here is where you decide what technology your application will need to use and how you will need to use it. The overriding question is do we have the capability and know-how to meet the user requirements? This can include for example, the programming language (in addition to PHP), the OS, the server speed, connection speed, etc.

    Program Design Phase
    You have the specifications. Here is where you decide how to write the application, what happens when; perhaps even some pseudo-code if you encounter a tricky point of implementation. In short, you will need to:

    Model it


    Illustrate it


    Draft Pseudo-code


    Model it
    Before you code an application, conceptualize how the different parts of your application will interface with each other.

    For example, let's design a simple form application:

    We consider the possible actions a user can do when accessing a simple mail sending script. In the most abstracted view of the application, there are two possible options. They have submitted form data or they have not.

    If they have not submitted any form data, then we should send them the initial form page. Otherwise, we should (again) do one of the following two things.

    If the data submitted is valid (meaning it conforms to the criteria for valid form data) then send the mail to the user and output a thank you message.


    Otherwise, send error message informing them of what went wrong, and giving them the option to correct this error.


    Illustrate It
    A very simple diagram showing the flow of an application is displayed below. It was done in Microsoft Visioš and is perfectly suitable for a simple form mail application.



    However, when it comes to more advanced applications, it is often useful to have a specialized tool that will help you diagram your applications. For information on three popular tools, check out: Dia, Visio, and UML.

    Draft Pseudo Code
    Writing pseudo code, meaning code that describes the application but does not really work, is a common practice that many developers often use. Generally it is employed when they're stuck on a tricky bit of implementation or they can't fully see how a particular aspect of the application would fit in. I've also found that pseudo-code is useful when defining application interfaces, namely, where other programmers will need to use the interfaces that I design. It helps to see what will be necessary and the easiest ways to go about it.

    For example, the pseudo-code below can be drafted when creating our simple Web site form-mail application.

    if (formSubmitted)
    {
    valid_name(name) or error() and output_form();
    valid_email(email) or error() and output_form();
    valid_message(message) or error() and output_form();

    message = name & email;

    send_mail(email, message);

    print "Thank you for your feedback";
    }
    else
    {
    print "Send us feedback";
    formelement(name);
    formelement(email);
    formelement(message);
    }
    The pseudo-code above defines the basic structure of the script and shows all of the specific required elements. The code does not have to be valid running PHP code (although it can be). What pseudo-code should do is define the different tasks of the application and perhaps the theory behind those tasks.

    The level at which you abstract your psuedo-code is of course up to you. Personally, I'm more inclined to a less abstracted form of psuedo-code than many people. It all depends on how comfortable you are with programming.

    Finally, once you have planned the whole application you can then start to code your application knowing all the steps you're going to need to take and what exactly you have to create.

    Testing Phase
    One of the most important stages of application development that is often left out is the (final) testing phase. Often due to time and/or management pressure, final testing is shortened or bypassed with the application being deemed production ready.

    Let's be honest, programmers hate testing. It's probably one of the most tedious and annoying stages of developing an application. It often consists of wild goose chases, hours of debugging, and testing all of the different bounds to make sure that your code works correctly in most cases. To top this off, you'll never have bug free code! You can always expect to miss something. You know, the one thing you would never think would happen, takes place anyway.

    Regression Testing
    Applications are perpetual "works in progress". It is important to ensure that when you add new functionality, you don't compromise the old functionality that your users have come to depend on. Therefore, you need what is known as a Regression Testing Suite. This is a set of tests that makes sure that functionality that currently works does not break down due to the new changes that you make.

    PHP itself has a regression-testing suite to make sure that all functions and processes work correctly so when you make a change to PHP you're sure that you haven't broken another part of PHP. This helps PHP not only keep backwards compatibility (i.e., when new features are added, your old scripts don't break). But it also is a way of making sure that none of the changes made actually break functions (not just change their behavior).

    Stress Testing
    OK, so your application works great with 1 user - everything seems to be going perfectly and with tremendous speed. But what about when your application is used by 20 users? 30 users? Or even a 100 users simultaneously? How fast is your application then? Does your application suddenly emit strange errors? Whenever you test an application you should always make sure to stress test it to make sure that it does not implode under high loads and varying conditions.

    This does not mean passing over the testing phase to the user. You know, just get it out and wait for the bug reports and feedback. Beta test it (as mentioned in the previous mistake). Moreover, there are some automated tools that emulate the testing over a large user pool. One that comes to mind is Apache's ab tool. AB, or Apache Benchmark, will perform a certain amount of requests on your Web page and return the success rate, failure rate, the average time, etc.

    I suggest that you use ab on all of your Web pages (that is, if you've made the infinitely wise decision to go with Apache). Then you can identify and optimize those pages that are memory hogs or take a long time to load.

    (Also, look into purchasing Zend's powerful script caching utility ? The Zend Cache).
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  6. #5
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    Top 21 PHP Programming mistakes Part 1

    1. Getting Lost in Time
    The number one mistake is a timeless problem that programmers have had to deal with ? getting lost in time. Face it, we are optimists. It is natural for us to assume that a software project will take just as long as it should take. We don't account for everything that could go wrong. For example, the fact that we might have trouble with the implementation of something might not even cross our minds.

    So, we must suppress our gut feelings and crunch those numbers. As a rule of thumb whenever I contract a software project, I always take into account every factor that I can think of, and come up with an estimated time. Then I double this estimate. It is hardly ever inaccurate, and companies are rarely disappointed when you finish your software ahead of time (whereas if you're late, they're not quite as happy).

    This "armchair" method of estimating helps me set an ample time to do a quality job on the program without falling behind schedule. But, in truth, it depends on the accuracy of my initial estimate.

    Every programmer underestimates (or in rare cases overestimates) the time necessary to complete a project by a certain amount, for me the mean is about 2x, for someone else it might be 1.5x, and a third person might underestimate actual time required by 3x. The trick is to figure out what your average error is when estimating the time necessary for projects and consistently tacking on that error margin to all of your projects.

    Not allocating enough time to your project will have a few effects (which I know of all too well):

    You will forfeit much of your social life until the project is finished. All your days and nights will be spent programming, leaving little time for relaxation (not that programming isn't fun, but programming non-stop is horrible).


    You will be rushed, meaning that you will spend less time on making your code secure, readable and fast. Instead, your focus will only be on banging out your code by the deadline.


    You may have to skip crucial steps, such as a code review or debugging, which, in turn, will lead to irate clients and even more work.


    You may have to add more manpower, which costs you more money, and may not help (according to Brook's Law, especially on large projects).


    Always make sure to allocate enough time in your projects for a lengthy debugging process (just as long or longer than the development process, itself), and 1/3 of the total project time for planning. These are the two most important parts of the development process.

    SterlingWonderfulToyland.com: An Example
    Let's take a sample site, SterlingWonderfulToyland.com. This is a simple e-commerce site that has been designated to sell its limited selection of Playstation 2's and Video Games over the Internet at discount prices.

    Being an old fashioned kind of guy, the owner John Giuseppe, also wants to encourage customers to come into the toy store itself and pick out the toys at the store. Therefore, the site has two main sections:

    An e-commerce end of the site.


    The plain jane portion of the site - giving you the directions to the Toy store and a store layout.


    When planning, I would come up with separate estimates for each section of the Web site. I would then combine the two resulting deadlines, add around a week to integrate the two sections and lastly pitch the deadline to the client for the whole site (stating the deadline as if there was just one unified section).

    The Plain Jane Section
    For the simple, non-dynamic portion of the web site, I would take a stab at how long it would take to make each page with an editor such as Macromedia's Dreamweaverš. Since there is really nothing dynamic about it, I would multiply that estimated time by the total estimated number of pages (of course this assumes that the design of the Web site has already been done). I would then double that estimate (as my personal error margin is usually 2x). For this section no real planning is needed (I mean heck, once you have a diagram of how it should look, given to you by your designer, all you have to do is lay it out in Dreamweaver).

    Note: Factor in up to an additional 1/3 of the time you expect will be spent implementing the application. This amount is for planning the application. For example, if you expect that it will take 9 days to implement a credit card validation program, then tag on an extra 2-3 days.

    The E-commerce Portion
    For the e-commerce portion, planning out the required time is pretty tricky. What I find that helps is to simply break the task up into even simpler components (such as credit card transactions, one-click ordering, product browser, product management, etc), and estimate the different components without applying the margin of error. I would then combine them, and multiply the sum by my margin of error. Then at this point, I would allocate an additional 1/3 of the time I expect it to take to complete the project, solely to testing and debugging, to make sure that I deliver the client a bug free product.

    Note: Factor in up to an additional 1/3 of the time for planning, as for the Plane Jane component.

    Selling deadlines
    Even if you can appropriately set a project date, your boss or client will not be as happy as you are with your deadline. Sometimes a deadline that is too long can be a deal-breaker. Other contractors will give a deadline that they can't possibly keep to get the deal and then simply be late with the project. So how do you set a deadline that your boss/client will be happy with and you can honestly keep?

    Here's where you've got to sell yourself and your deadlines... What can you offer the client with deadlines? What makes your deadlines feasible and why are your deadlines set as they are? It often helps to role-play, pretending you are the client, and asking yourself what would be fair to expect from a potential programmer?

    Some points that I have found to be important include:

    Do it right. Other programmers may do it a little faster, but you'll do it correctly which saves the client money and time in the long run (this is especially useful if you charge by the hour).


    Stick to your word. The deadlines that you are setting are deadlines that you intend to keep. Other programmers may give deadlines that look better, but they have no intention of keeping to them.


    Provide Client recommendations. Your previous jobs speak for themselves, have your satisfied clients give you recommendations that you can then show to your boss/potential clients.


    Be thorough! Run your proposals through spell-check, have someone proof them for grammar. Add diagrams, and clearly state everything that you plan to do and how long each of the tasks you define will take.


    Give ranges. Don't just tell clients how long you think it will take - provide them with scenarios. What is the best-case scenario? What is the worst-case scenario?


    Set short deliverable dates. The further in the future a target date is set, the more likely it will not be met.


    When you don't allocate enough time
    Sometimes you don't allocate enough time for a project, leaving you very far behind... When this happens you still have many options (that aren't always clear at the time).

    Communicate! Communication between you and your client is the most important thing possible. Constantly inform them of what your currently doing. If you see that you may need to extend a deadline a little it won't be as hard as if you haven't communicated all along.


    Show your boss/client a partial version of the Web site: It often helps when asking for time extensions to show the work that you've already done. Demonstrate that you have been working on the project.


    Blame Canada: Take full responsibility for being late with the project, but don't forget to mention any external factors that caused you to be late.


    Cut corners: This is nasty, but if you're really late with a project cut some corners to get a working version of your application for the client, with the hacks in your code clearly marked, then, during your testing phase and later on, go back and fix those hacks.


    Go GUI: If I'm creating an application I really prefer to handcraft my HTML, I don't trust the output generated by any WYSIWYG editors. However, if you are in a time crunch consider constructing your HTML with the WYSIWYG editors.


    *****
    jessraju likes this.
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  7. #6
    Senior Member
    Join Date
    Apr 2002
    Location
    Cocooned in her thoughts
    Posts
    312
    Member #
    67
    Liked
    3 times
    These 21 Mistakes are from an old article on zend.com.
    jessraju likes this.
    Don't look so frightened
    This is just a passing phase

    One of my bad days...

  8. #7
    Junior Member
    Join Date
    Dec 2002
    Location
    chennai , tamil nadu , India
    Posts
    13
    Member #
    384
    custom freelance mysql php and web development programming

    Testing Phase
    Regarding testing

    Yes I sometimes find it tedious to find "all possible scenarios" for a particular test field

    for example

    for credit card numbers

    1) alphabets and special characters must not be allowed
    2) spaces can be allowed
    3) check digit testing for visa and mastercard etc

    so my question is , is there anywhere in the net I can find full comprehensive test scenarios ..it must list every possible situation for a test condition...
    Chris, Developer, Chrisranjana.com
    Software developers,
    Php and RoR programmers,
    http://www.chrisranjana.com

  9. #8
    410
    410 is offline
    Senior Member 410's Avatar
    Join Date
    Nov 2002
    Posts
    109
    Member #
    284
    next time link use or make it a atachment please... I scrolled for like 5ins on this one... lol

    BTW my biggest mistake is i always forget the ;

  10. #9
    Junior Member
    Join Date
    Apr 2003
    Posts
    3
    Member #
    1059
    template engines

    For the love of God, if you're going to use a template engine, don't use FastTemplates. it's been benchmarked against other template negines and it's the most outdated and slow template engine avaliable to users. There is parsing overhead when sing FastTemplates. instead, try using Smarty.

    http://smarty.php.net

  11. #10
    Junior Member
    Join Date
    Apr 2003
    Posts
    22
    Member #
    1060
    is smarty like phpnuke and phpmyadmin


Page 1 of 3 1 2 3 LastLast

Remove Ads

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Search tags for this page

21 php mis take
,
biggest mistakes programmers make in php
,

content

,
mistakes by php programmer
,
top 10 php developer mistakes
,
top 21 php programming mistakes
,
top 21 programming mistakes
Click on a term to search for related topics.
All times are GMT -6. The time now is 12:32 PM.
Powered by vBulletin® Version 4.2.3
Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.
vBulletin Skin By: PurevB.com