Page 1 of 2 12 LastLast
Results 1 to 40 of 73
  1. #1
    Join Date
    May 2003
    Location
    United States
    Posts
    54

    How To : Improve Your PHP Programming

    Hello everyone,

    I've decided that I would make a thread here describing the different things that I do to improve other people's PHP scripts.

    Hope you enjoy it and learn a thing or two.

    1 - Your PHP Tags
    I know some of you prefer to use the short tags when writing PHP scripts <? ?> but this is not always the best way of doing it.
    The standard tags <?php ?> are much better as they will work on every server that you write your PHP code on. You may move to a server some day that doesn't allow the short tags or the ASP-style tags and you will have to sit for an hour and update your PHP scripts.

    2 - Debugging Your PHP Code
    Some of us may run into a problem when programming a PHP script and don't know what's wrong with it. The error_reporting() function in PHP helps you out by telling every error you have on your page. To show all of the errors on the page that you're editing, put this on the second line :
    PHP Code:
    error_reporting(E_ALL); 
    3 - Debugging Your PHP Code (again)
    When you finish editing your 1200-line PHP script, click onto it in your Internet browser, you see an error that says that is on line 561. Don't hit the panic-attack button quite yet, because there is an easy way to find out what line 561 is. Follow these easy steps :
    - Open up Microsoft Notepad
    - Paste your PHP script into it
    - Go to 'Edit' >> 'Go To...' (or Control+G)
    - Type in line #561 and hit the enter key
    - Your cursor is taken to line #561.
    - Look above and below line #561 to see if there is any kind of trouble.
    - Fix the error, re-upload the script to your website, and most likely it will work. If there is another error, repeat the above steps.

    4 - Using Comments
    If you have a 1200-line PHP script, it may be quite hard to figure out what's going on all through-out it. The solution to figure out what you're doing is to add PHP-comments.
    PHP-comments are different than the <!-- HTML Comments --> as they are not outputted to the user's page (meaning that they are not even going to see it in the source code).
    There are three ways to make comments in PHP :
    PHP Code:
    <?php
    // The double-backslash is my personal favorite.  I add another set after my code so that it looks even, though it is not necessary. //
    # The hash-style comment is another way of making a comment.
    /* And, this is the final way of making PHP-comments.  You can use
    multiple
    lines
    at a time by using this style. */
    ?>
    You can decorate it however you like, you are the only one who may use them.

    5 - Indenting Your PHP Codes
    I don't personally like to indent my PHP codes, but it helps when reading it. When I do have to, I use the tab key to accomplish this. Example :
    PHP Code:
    <?php
    // Settings //
        
    $var1 "This";

    // Showing Variables //
        
    if($var1 == "This"){
            echo
    "You said This";
        }else{
            echo
    "You said That";
        }
    ?>
    6 - Improving your PHP-File Includes
    I'm sure that most of us on here include a PHP file or two for our layouts. Well, what if your layout file was missing ? Wouldn't that look pretty unprofessional to the people on your website ?
    In every PHP-script that I write, I make sure that the file exists before it is even included. Here's an example :
    PHP Code:
    <?php
    if(!file_exists("layout.inc.php")){exit("Error :  LayOut File Missing");}else{include_once("layout.inc.php");}
    ?>
    I'm sure that a small error message will seem better than half a page that is all messed-up looking.

    7 - Your MySQL Queries
    Sometimes when you're writing a PHP script that includes connections to your MySQL database, you may run into a few problems. Most everyone that had MySQL problems ran a command like this one :
    PHP Code:
    <?php
    mysql_query
    ("INSERT INTO tableName ('id','name') VALUES('1','Mike')");
    ?>
    ..and they figure out that it's not inserting into their database. Here's the solution to this :
    PHP Code:
    <?php
    mysql_query
    ("INSERT INTO tableName ('id','name') VALUES('1','Mike')") or exit("MySQL Error :  " mysql_error());
    ?>
    8 - Combining Alike If-Then Statements
    You may have a register page, and want to make sure that everything has been filled-in. You may use many if-then statements like so :
    PHP Code:
    <?php
    if(!$_POST[name]){exit("Sorry, but you did not fill-in all of the requested fields.");}
    if(!
    $_POST[email]){exit("Sorry, but you did not fill-in all of the requested fields.");}
    ?>
    You can combine these two lines into one by joining their if-then statements together :
    PHP Code:
    <?php
    if((!$_POST[name]) || (!$_POST[email])){exit("Sorry, but you did not fill-in all of the requested fields.");}
    ?>
    Simply, || is the same thing as OR and && is the same as AND.

    9 - Using echo or print ?
    Most of you may say 'echo is the same thing as print', in which I agree with you all. The echo command is much faster than the print command, and is one less character to type. The echo command came later than the print command (I believe), so you make the judement on which to use.

    10 - Printing out a Huge Chunk of HTML at a Time
    Well, I'm sure that many of us found a way to get around this, but I'd like to share with you a few of the ways you can do it.

    1 - Break off your PHP-code, print the HTML, and start your PHP-code up again. (I don't prefer doing this as it looks pretty unprofessional to me).
    2 - Adding backslashes to each HTML tag. (It works, but takes forever to do).
    3 - Using the echo/print command, but without having to do much work. (I recommend) :
    PHP Code:
    <?php
    // Showing a huge chunk of HTML at a time //
    echo<<<END
    <font face="Verdana" color="Orange" size="3">Large, Orange Text in Font Size 3</font>
    <br><br>
    More HTML down here..
    <br><br>
    <div align="Center">Centered text</div>
    END;
    ?>
    Well, I have many other things to tell about sprucing up your PHP-code, but I don't want to bore you.

    I hope I've helped.

    Best Regards,
    - Mike.
    Last edited by giropets; 07-21-2004 at 01:40 AM.
      0 Not allowed!

  2. #2
    Very nice How To , and its not boring at all..your writing style is very interesting and i hope to have more ideas from your mind in the future. Thanx for sharing these tips.
    MaJiD SaeeD Khan
    Software Engineer - Bahriasoft
    http://www.Bahriasoft.com
      0 Not allowed!

  3. #3
    Ild just like to point out something on the echo and print argument. You say "The echo command is much faster than the print command". I'ld like to point out why.

    Print has a return value, echo does not.


    Consider:


    PHP Code:
    <?php

    if (print('foo')) { print('foo printed'); } // Will be true

    if (echo('foo')) { echo('foo printed'); } // Will be false

    ?>
    Evidently print will always return logical true (1), unless there is a serious error with PHP and the string does not print. Obviously PHP uses C prototypes but I will convert them into PHP so we can see what is going on.

    PHP Code:
    <?php

    function print($stringToPrint) {
      
    system.out($stringToPrint);
      return 
    1;
    }

    function echo (
    $stringToPrint) {
      
    system.out($stringToPrint);
    }

    ?>
    Hope that helps clear that up.

    - Kar
      0 Not allowed!

  4. #4
    Join Date
    Jul 2004
    Location
    Ann Arbor, MI
    Posts
    13
    The only things I would point out are:

    1. Use variable names that make sense.

    a) $string is a string, and $string_array is an array for example. $flag is a flag...

    2. Put your code into functions as much as possible, and write your functions so they can be used in multiple projects - try not to write code that is proprietary to the project at hand.

    a) save your functions in library files that you can use the 'include' command to call them up again in your projects.
    -------------------------------------------
    http://www.jmrtechnet.com
      0 Not allowed!

  5. #5
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    Hello again everyone,

    Since all of you thought it was not boring, I've decided that I would add a few more to my list.

    11 - Multiple Items in the If-Then Statement
    As said in #8, you can combine alike if-then statements into one. This also works...
    PHP Code:
    if($this == "that" && $that == "this"){echo"This and that match";} 
    But from experience, it is best to assign seperate brackets () around them as it does not confuse the code...
    PHP Code:
    if(($this == "that") && ($that == "this")){echo"This and that match";} 
    12 - Saving Time with Varibles
    When using functions, and you want to include a load of settings, you need to include every single of them at a time, as so...
    PHP Code:
    <?php
    $time 
    date("Y-m-d:H.i.s");
    $name "Mike";
    $comment "Just a simple comment";
    function 
    show(){
    global 
    $time,$name,$comment;
    echo
    "$time - $name - $comment";
    }
    show();
    ?>
    ..But you can save your time by including only one variable instead of three, as so...
    PHP Code:
    <?php
    $_SETTINGS
    [time] = date("Y-m-d:H.i.s");
    $_SETTINGS[name] = "Mike";
    $_SETTINGS[comment] = "Just a simple comment";
    function 
    show(){
    global 
    $_SETTINGS;
    echo
    "$_SETTINGS[time] - $_SETTINGS[name] - $_SETTINGS[comment]";
    }
    show();
    ?>
    ..Even though you'll spend a little more time by typing $_SETTINGS[] or just by copying and pasting it.

    13 - Shortening exit(); and die(); Functions
    If you want to stop the page load, you can use the exit(); or die(); functions. But, if this is all you want to do, then you can shorten it...
    PHP Code:
    exit();
    exit;

    die();
    die; 
    14 - More Usage of exit; and die;
    If you want to stop the page load and show text, you can do this..
    PHP Code:
    echo"You did not finish all of the required fields.";
    exit; 
    ...Or...
    PHP Code:
    exit("You did not finish all of the required fields."); 
    15 - Using arrays to Store Data
    Arrays are used to store temporary data in a PHP code. Here's an example...
    PHP Code:
    <?php
    $names 
    = array("Mike","Charlie","Amanda","Caroline");
    echo 
    $names[0]; // Outputs 'Mike'
    echo $names[1]; // Outputs 'Charlie'
    echo $names[2]; // Outputs 'Amanda'
    echo $names[3]; // Outputs 'Caroline'
    ?>
    That's all I can really suggest for now, some methods of doing things may work better than others, but you're the one to decide what works best.

    Best of luck,
    - Mike.
    Last edited by giropets; 07-28-2004 at 10:48 PM.
      0 Not allowed!

  6. #6
    Join Date
    Jun 2004
    Location
    USA, Ohio
    Posts
    95
    Very nicely done giropets.. *cheers*
      0 Not allowed!

  7. #7
    Join Date
    Aug 2004
    Location
    Canada
    Posts
    3,571
    That's very nice and informative for anyone specially beginners

    Some other stuff to keep your code more clean and manageble would be to keep HTML and PHP completly seperate for the most part seperate files for them. So useing functions to call the html keep it much cleaner or a template system. Obviously functions like jasonr33 said specially for database stuff make it much easier.

    Heck I've had the same functions for quite a while the same mysql, template and functions files you'd be surprised how much time is saved when all your php scripts use the same set of functions.
      0 Not allowed!

  8. #8

    Re: How To : Improve Your PHP Programming

    Originally posted by giropets


    3 - Debugging Your PHP Code (again)
    When you finish editing your 1200-line PHP script, click onto it in your Internet browser, you see an error that says that is on line 561. Don't hit the panic-attack button quite yet, because there is an easy way to find out what line 561 is. Follow these easy steps :
    - Open up Microsoft Notepad
    - Paste your PHP script into it
    - Go to 'Edit' >> 'Go To...' (or Control+G)
    - Type in line #561 and hit the enter key
    - Your cursor is taken to line #561.
    - Look above and below line #561 to see if there is any kind of trouble.
    - Fix the error, re-upload the script to your website, and most likely it will work. If there is another error, repeat the above steps.

    Best Regards,
    - Mike.
    Well Mike not a bad how-to, but this part IMHO is very wrong.
    I strongly suggest that instead of using plain notepad/wordpad or ms-word to code your scripts you get a proper PHP editor such as PHPcoder or the one by Zend. (which is great, I love it. )

    it has a ton of time saving advantages such as syntax highlighting and line numbering, 'etc.


    Eugene
    IWDN - Really smart web developers... and me!
    More than any time in history mankind faces a crossroads.
    One path leads to despair and utter hopelessness, the other to total extinction.
    Let us pray that we have the wisdom to choose correctly.
      0 Not allowed!

  9. #9
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    I think I've figured it out the hard way, but thanks for letting me know as I take interest in it.
      0 Not allowed!

  10. #10
    I have recently begun to comment all my closing tags and that is really helping a lot. Like I did in the last two lines of this dummy code below. If there is a lot of stuff contains in the if tags where the opening and closing tags are far apart it helps to know where one starts and ends, as well as telling if your number of brackets match up.

    PHP Code:
    if ($something == "this") {
      for(
    $i=0$i<10$i++) {
        echo 
    $i;
        
    $double[$i] = $i*2;
      } 
    // for
    // if 
      0 Not allowed!

  11. #11
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    That's actually not a bad idea, I should try using that from now on.
      0 Not allowed!

  12. #12
    Join Date
    Aug 2004
    Posts
    40
    Yes. For clarity you can even do this for nested statements like
    Code:
    for($i = 0; $i < 10; $i++) {
    for( ; ; ) {
    break;
    } // inner for
    } // outer for
      0 Not allowed!

  13. #13
    Join Date
    May 2003
    Posts
    43
    <?php
    if(!file_exists("layout.inc.php")){exit("Error : LayOut File Missing");}else{include_once("layout.inc.php");}
    ?>
    I prefer to use a function to do this, for example...

    Code:
    function includeme ($addr) 
    {
    	//Check that file exists
    	if (! file_exists($addr)) 
    	{
    		exit("Error :  '$addr' File Missing");		
    	}
    	
    	//Include File
    	include($addr);
    }
    This would go into your functions file which you include, the only down-side is you cant use the function for including your functions file :p
      0 Not allowed!

  14. #14
    PHP Code:
    <?php
    mysql_query
    ("INSERT INTO tableName ('id','name') VALUES('1','Mike')") or exit("MySQL Error :  " mysql_error());
    ?>
    One step furter is:

    PHP Code:
    <?php
    $sql 
    "SELECT value FROM table";
    $query mysql_query($sql
    or die(
    "You got the error: " mysql_error() . "with the query: $sql");
    ?>



    You should never make a variable like $_SETTINGS. The _ is there to show that it is a system (php-specific) variable like $_POST, $_GET and $_SERVER. Rather do $settings then!

    PHP Code:
    <?php
    $_SETTINGS
    [time] = date("Y-m-d:H.i.s");
    $_SETTINGS[name] = "Mike";
    $_SETTINGS[comment] = "Just a simple comment";
    function 
    show(){
    global 
    $_SETTINGS;
    echo
    "$_SETTINGS[time] - $_SETTINGS[name] - $_SETTINGS[comment]";
    }
    show();
    ?>
      0 Not allowed!

  15. #15
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    Thanks for pointing those out, scuba. I should try using the SQL lines you done in my code to help debug even better.
      0 Not allowed!

  16. #16
    Just a quick comment:
    '&&' and 'AND' aren't exactly the same, they have different precedence. For example:

    Code:
    <PRE>
    <?php
      $a = "hello\n";
      $b = "goodbye\n";
    
      print "First trial\n";
      if (print $a && print $b) {
        print "Bad\n";
      }
    
      print "\nSecond trial\n";
      if (print $a and print $b) {
        print "Good\n";
      }
    ?>
    </PRE>
    Returns the following:
    First trial
    goodbye
    1Bad

    Second trial
    hello
    goodbye
    Good
    Same with OR and ||
      0 Not allowed!

  17. #17

    Advantage of PHP?

    May i know what PHP can be used for?
    How powerful is this language?
    Thanks!
      0 Not allowed!

  18. #18
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    Well, PHP can be used for a lot of things on the internet.

    I programmed a whole entire site with my friend that was a web game with PHP back-end programming.

    It is very powerful - just depending on how you want to use it.
      0 Not allowed!

  19. #19
    Wouldn't it be better and easier to make a web game using Flash instead of PHP? If not, what advantages does PHP have over Flash?
      0 Not allowed!

  20. #20
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    GiroPets.net is the web game that I made. It includes a few Flash games as well. I recently sold the site (I should get myself a new screen name for WHT)...
      0 Not allowed!

  21. #21
    Join Date
    Jun 2002
    Location
    Minnesota
    Posts
    8
    thanks for this post
      0 Not allowed!

  22. #22
    Join Date
    Jul 2004
    Posts
    352
    Thanks to everyone that posted ideas and how-to's on this board.

    I have succesffully created a few php programs - but my coding was sloppy and hard to change.

    On my next few programs I plan on changing that and this post will definitly help me keep my code clean and concise.

    Billy
      0 Not allowed!

  23. #23
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    Originally posted by billy79
    Thanks to everyone that posted ideas and how-to's on this board.

    I have succesffully created a few php programs - but my coding was sloppy and hard to change.

    On my next few programs I plan on changing that and this post will definitly help me keep my code clean and concise.

    Billy
    I can totally relate to that. I code sloppily too and it's hard for me to tab over...I will have to try starting that habbit too.
      0 Not allowed!

  24. #24
    Join Date
    Oct 2004
    Posts
    89
    Also, read the Open Web Application Security Project guide:
    http://www.owasp.org/documentation/g...ide_about.html
      0 Not allowed!

  25. #25
    Join Date
    Jun 2004
    Posts
    109
    Just a little something to add:

    * switch/case is faster than an if condition
    * Type cast any foreach arguments to avoid error messages
    PHP Code:
    <?php
        
    //Assume $someArray is the return value of a function
        //and it will only be an array if the function
        //was successful
        
    $someArray = (array) $someArray;
        foreach(
    $someArray as $eachElement)
        {
            echo 
    $eachElement '<hr />';
        }
    ?>
    * Commas are apaprently faster than periods when it comes to concatenation
    * To view the contents of a variable, you can use print_r() which will print the variable out in a human readable format.
    * You can use var_dump() or var_export() to view the values and types of a variable. The latter will show the values in a format that can be used within a PHP script directly (i.e. it wont cause any parse errors)
    * When using comparison operators, you can either use == or === The latter will check for the type as well as the value and it is faster.
    PHP Code:
    <?php
        $boolTrue 
    TRUE;
        
    $boolFalse FALSE;
        
    $intOne 1;
        
    $intZero 0;
        
    $intOther 5;

        
    //This evaulates to true
        
    if($intOne == $boolTrue)
        {
            echo 
    'Loose checking';
        }

        
    //This is false because one is an
        //integer, while the other is a boolean
        
    if($intOne === $boolTrue)
        {
            echo 
    'Strict checking';
        }
    ?>
    * To iterate through an associative array (eg.: $_GET, $_POST, etc.), you can do this:
    PHP Code:
    <?php
    //This snippet will strip any tags off all GET arguments
    foreach($_GET as $myKey => $myValue)
    {
        
    $_GET[$myKey] = strip_tags($myValue);
    }
    ?>
    * If you prepend a function with an AT sign (@), it will not spit out any errors. The same applies to user defined functions.
    PHP Code:
    <?php
        
    //This will output an error if the password is wrong
        
    mysql_connect('localhost''username''wrongPassword');

        
    //This will not display any error messages
        
    @mysql_connect('localhost''username''wrongPassword');

        
    //Assuming the method myMethod has an error in it,
        //it wont spit out any warnings because of the @ prepend
        
    @$myObj->myMethod($myArgument);
    ?>
      0 Not allowed!

  26. #26
    Here is an alternative for including files and checking for errors (versus checking if the file exists first)

    Sample code:

    PHP Code:
    if([email protected]_once("file.inc")) { echo "There was an error including an important file."; exit(0); } 
    The @ symbol will supress the error thrown by PHP when the file cannot be included. The ! symbol is used to cause the if statement to be true when the the include_once function is false/fails.
      0 Not allowed!

  27. #27
    giropets, nicly done but it's :
    PHP Code:
    $_SETTINGS['time'] = date('Y-m-d:H.i.s');
    $_SETTINGS['name'] = 'Mike';
    $_SETTINGS['comment'] = 'Just a simple comment'
    why? because your code will bounce few notices about constants not being found..
    and since we came about quotes, I will add:

    Using Single Quotes VS. Duoble Quotes
    some poeple don't know the difference between single and double quotes..
    single quotes are faster than double ones because it wont parse variables while the double quotes will look for variables to parse ..
    so if you have only hardcoded text, use single quotes but if you have variables use duoble quotes..
    example:
    PHP Code:
    $var 'value';

    echo 
    'this is $var'//prints "this is $var"
    echo "this is $var"//prints "this is value" 
    We don't need a reason to help people
      0 Not allowed!

  28. #28
    Join Date
    Jan 2005
    Location
    California
    Posts
    18
    Thanks a bunch giro
      0 Not allowed!

  29. #29
    Join Date
    Dec 2004
    Location
    Canada
    Posts
    1,082
    Not bad. Good pointers, though that include code is really quite unreadable, considering your point about readability later on...

    Want to also point out that using globals is generally bad practice. Avoid them if you can. For things like settings, or DB pointers they're fine, but try to avoid using them for data that may change through the script's execution. They're a big pain to debug when you run into problems, and just poor design in general. Also, there's nothing there about OO.

    Now, for my own points:

    Curly braces are unnecessary if you only need to execute a single statement. You *need* to indent things nicely if you do this though, or it's completely unreadable (note that this applies to for, foreach and while statements as well):
    PHP Code:
    if (!$user->loggedin)
       
    error_message("You aren't logged in! You can't access this page."); 
    or even:
    PHP Code:
    if (!$user->loggedinerror_message("You aren't logged in! You can't access this page."); 
    If you need more than one statement to be executed in the conditional, you of course need to use the braces.

    Ternary conditionals are handy too. A bit confusing at first, but handy once you learn them. They 'return' a value based on the condition given. Here's a simple example:
    PHP Code:
    echo ($user->is_admin) ? "You're an admin!" "You're not an admin."
    I find this very useful in form processing code where you might use it to assign default values if the input is invalid:
    PHP Code:
    $params['description'] = (preg_match("/^[A-z0-9]{5,30}$/"$_POST['description'])) ? $_POST['description'] : "Default"
    Also keep in mind the difference between require() and include(). Generally, it's a good idea to use require() where the code to be included is absolutely required, as the script will die if it can't be included. For things like authentication code, this is definitely important.

    Oh, another thing I see a lot that really is quite pointless. Don't use an if construct where it's not required. Generally this is when returning from a function. Granted, this is much more ambiguous in a loosely typed language, but the point stands. Example:
    PHP Code:
    if ($user->loggedin && $user->is_admin) return true;
    else return 
    false
    is equivalent to
    PHP Code:
    return ($user->loggedin && $user->is_admin); 
    And lastly, try to keep your SQL statements in one place. My personal suggestion is to write a DB abstraction class that contains methods such as insert_user() that completely remove any SQL calls from your program logic. This makes things a lot easier to change in the future (all your SQL code is in one place, and you don't have identical SQL in multiple places that all need to be updated), and if you ever need to switch databases, all of your queries and mysql_* or pg_* calls are centralized and can be easily changed. It also reduces the amount of duplicate code you have, and generally leaves less room for errors in input validation etcetera. If you don't use a DB class, at least store your queries in an associative array somewhere and use sprintf to add the parameters at run time.

    That's all I've got for now.
      0 Not allowed!

  30. #30
    Join Date
    Dec 2004
    Location
    Canada
    Posts
    1,082
    Well, since the end of my post was about SQL, it's time to rant about database design. It's not really 'PHP programming' as the title suggests, but beginners almost always are interested in using the two together. Other data storage methods are clumsy and much more difficult to implement.

    So, without further ado, my attempt at explaining database normalisation. For those who already understand normal forms, please understand that I'm trying to give practical guidelines, not theoretical strict definitions here.

    When you're designing your tables (you ARE designing before you implement, aren't you?), you want to keep things fairly normalised. Now, what exactly does that mean?

    First, and most importantly, every column in each table should depend on an individual instance of what that table is describing. For example, if you have a comments table and you want this table to also contain information about the user that posted the comment, say the user's name and tagline, you wouldn't actually store the username and tagline inside the comments table. Since I'm not very eloquent at describing this stuff, here's an example:
    Code:
    CREATE TABLE users (
       uid INT NOT NULL AUTO_INCREMENT,
       username VARCHAR(32) NOT NULL,
       tagline VARCHAR(64) DEFAULT '',
       -- ... rest of the fields here
       PRIMARY KEY(uid),
       UNIQUE(username)
    );
    
    CREATE TABLE comments (
       cid INT NOT NULL AUTO_INCREMENT,
       uid INT NOT NULL, -- in a proper RDBMS (which MySQL is NOT), you'd reference the users table here as a foreign key)
       pid INT NOT NULL, -- ditto
       comment_body TEXT,
       -- ... more fields
       PRIMARY KEY(cid),
       INDEX(pid)
    );
    You can think of this concept as reducing duplication. You're already storing the username in a table, so don't store it again in the comments table, just store a reference to the primary key of the user's table. We'll see how to access this in a single query in a few moments.

    On with database normalisation concept #2 - don't store multiple values in a single column:

    Let's say you have the users table above, and you decide that you want to store every IP address the user has ever logged in under. Now, a novice developer may think that this data belongs in the users table as well, since it depends directly on the user. They might opt to use a VARCHAR or TEXT field and store the values there in some fashion (separated by a delimiter, or perhaps as a serialized array). This is bad practice and leads to all sorts of issues, and also reduces the flexibility of your database. There are two 'correct' ways to accomplish this sort of one to many relationship. The first, and (IMO) correct way in this case is to create a separate table for IPs:
    Code:
    CREATE TABLE user_ips (
       uid INT NOT NULL, -- foreign key
       ip VARCHAR(15) NOT NULL,
       PRIMARY KEY(uid, ip),
       INDEX(ip)
    );
    This can be easily fetched in any combination...and can also easily achieve the reverse ip->user query that's not possible with the other implementation (as well as other ip-related queries).

    Now for another similar example to show the other technique. Let's say you're writing something like a blog, where you might have a number of posts as well as a number of categories, where each post can be in an arbitrary number of categories. For this you're going to want a separate table for both posts and categories, and you'd want to create a third table to map the two together (we'll use the users table from above):
    Code:
    CREATE TABLE posts (
       pid INT NOT NULL AUTO_INCREMENT,
       uid INT NOT NULL, -- again, foreign key definition would go here
       post_content TEXT,
       -- more...
       PRIMARY KEY(pid),
       INDEX(uid)
    );
    CREATE TABLE categories (
       cat_id INT NOT NULL AUTO_INCREMENT,
       name VARCHAR(64),
       -- etc...
       PRIMARY KEY(cat_id)
    );
    CREATE TABLE cat_posts_map (
       pid INT NOT NULL, -- FK
       cat_id INT NOT NULL, -- FK
       INDEX(pid),
       INDEX(cat_id)
    );
    Okay, now you're probably wondering how this makes things *easier* since at first glance, it looks like this is going to force you to do half a dozen queries just to get all the information you need for a single post. It's not quite that bad .

    First, let's take our most recent example -- getting a single post and the categories it's in. What we need to do is map the three tables (posts, users, categories)...well actually four if we count the mapping table...into a single result table. There are two syntaxes for doing this. I'm only going to cover the conditional one, as I think it's easier to understand. If you want to look into the JOIN syntax, you can find it on the JOIN syntax page.

    Now before we give some examples for this, let's populate our database with some data:
    Code:
    INSERT INTO users (username, tagline) VALUES ('user1', 'im a test user');
    INSERT INTO users(username, tagline) VALUES ('user2', 'im another test user');
    
    INSERT INTO posts (uid, post_content) VALUES (1, 'test post');
    INSERT INTO posts (uid, post_content) VALUES (1, 'another post');
    
    INSERT INTO categories (name) VALUES ('test_cat');
    INSERT INTO categories (name) VALUES ('another_cat');
    
    INSERT INTO cat_posts_map (pid, cat_id) VALUES (1, 1);
    INSERT INTO cat_posts_map (pid, cat_id) VALUES (1, 2); -- put post 1 in both categories
    
    INSERT INTO comments (uid, pid, comment_body) VALUES (1, 1, 'comment 1');
    INSERT INTO comments (uid, pid, comment_body) VALUES (2, 1, 'comment 2, new user');
    Alright, so let's get post id 1, and all of it's associated data:
    Code:
    SELECT posts.*, users.*, categories.* FROM posts, users, categories, cat_posts_map
       WHERE
          posts.pid = 1 AND
          posts.uid = users.uid AND
          posts.pid = cat_posts_map.pid AND
          cat_posts_map.cat_id = categories.cat_id;
    The SQL server will join all of the tables together, and you'll get two rows back - each with identical data except for the data from the categories table:
    Code:
    +-----+-----+--------------+-----+----------+----------------+--------+-------------+
    | pid | uid | post_content | uid | username | tagline        | cat_id | name        |
    +-----+-----+--------------+-----+----------+----------------+--------+-------------+
    |   1 |   1 | test post    |   1 | user1    | im a test user |      1 | test_cat    |
    |   1 |   1 | test post    |   1 | user1    | im a test user |      2 | another_cat |
    +-----+-----+--------------+-----+----------+----------------+--------+-------------+
    This may seem clumsy, but it allows the reverse mapping (get all posts in a single category) just as easily, by changing only a single condition in the query. You may just want a list of categories for that post as well, this query is simple as well (modify what's being selected to just categories.*, remove the users table from the query entirely).

    The query to retrieve all the comments for a post is similar:
    Code:
    SELECT comments.* FROM comments, posts -- we only care about the comment data here
       WHERE
          posts.pid = 1 AND
          comments.pid = posts.pid;
    This returns all the comments attached to post 1:
    Code:
    +-----+-----+-----+---------------------+
    | cid | uid | pid | comment_body        |
    +-----+-----+-----+---------------------+
    |   1 |   1 |   1 | comment 1           |
    |   2 |   2 |   1 | comment 2, new user |
    +-----+-----+-----+---------------------+
    The one other point I wanted to touch on, which doesn't really need examples, is that your columns should never depend on any external data. An example might be storing year-end totals for different products (with each product on a row) in a different column, with separate columns for each year. That'd require adding a new column every year, and you should never EVER modify the DB schema under normal operation (adding and removing fields is fine, but you shouldn't have to do maintenance of this type on the database). This sort of concept should be represented as two tables. I won't give an example, it's not difficult to figure out.

    So I hope I didn't just waste an hour of my day. It's not simple stuff, but if you can grasp the concepts, you'll have an easier time designing databases and queries that are more complicated than a simple row/column relationship.
      0 Not allowed!

  31. #31
    in a proper RDBMS (which MySQL is NOT), you'd reference the users table here as a foreign key)
    Tsk..tsk.

    Do you have something against using InnoDB tables in mysql?
    "The only difference between a poor person and a rich person is what they do in their spare time."
    "If youth is wasted on the young, then retirement is wasted on the old"
      0 Not allowed!

  32. #32
    Join Date
    Jan 2005
    Location
    Manchester, UK
    Posts
    194

    Re: How To : Improve Your PHP Programming

    Originally posted by giropets
    PHP Code:
    <?php
    if(!file_exists("layout.inc.php")){exit("Error :  LayOut File Missing");}else{include_once("layout.inc.php");}
    ?>
    I'm sure that a small error message will seem better than half a page that is all messed-up looking.
    Well erm, this is a rather masssiiive if, dont you think?
    PHP Code:
    if(!file_exists("layout.inc.php")){exit("Error :  LayOut File Missing");}else{include_once("layout.inc.php");} 
    so instead, use the more compact version..
    PHP Code:
    (!file_exists("layout.inc.php")) ? exit("Error :  LayOut File Missing") ? include_once("layout.inc.php"); 
    Thats simply (ifstatment) ? true : false;
    7 - Your MySQL Queries
    Sometimes when you're writing a PHP script that includes connections to your MySQL database, you may run into a few problems. Most everyone that had MySQL problems ran a command like this one :
    PHP Code:
    <?php
    mysql_query
    ("INSERT INTO tableName ('id','name') VALUES('1','Mike')");
    ?>
    ..and they figure out that it's not inserting into their database. Here's the solution to this :
    PHP Code:
    <?php
    mysql_query
    ("INSERT INTO tableName ('id','name') VALUES('1','Mike')") or exit("MySQL Error :  " mysql_error());
    ?>
    This is incorrect, INSERT INTO table ($keys) VALUES ($values) ... $keys must be ` ` and $values must be ' '.
    example, `id`,`name` .


    Just wanted to point these out - ..
    Splamoni

    www.imgdoc.net - Free Image and Document Hosting!!
      0 Not allowed!

  33. #33

    Re: How To : Improve Your PHP Programming

    Originally posted by splamoni
    so instead, use the more compact version..
    PHP Code:
    (!file_exists("layout.inc.php")) ? exit("Error :  LayOut File Missing") ? include_once("layout.inc.php"); 
    Thats simply (ifstatment) ? true : false;
    you mean:
    PHP Code:
    (!file_exists('layout.inc.php')) ? exit('Error :  LayOut File Missing') : include_once('layout.inc.php'); 
    but I am not sure if this is correct because here is what php manual says:
    Because include() and require() are special language constructs, you must enclose them within a statement block if it's inside a conditional block.
    Example 11-6. include() and conditional blocks
    PHP Code:
    <?php
    // This is WRONG and will not work as desired.
    if ($condition)
        include 
    $file;
    else
        include 
    $other;

    // This is CORRECT.
    if ($condition) {
        include 
    $file;
    } else {
        include 
    $other;
    }
    ?>
    you are not enclosing the inculde() in a block, but I am not sure about that...

    as for
    This is incorrect, INSERT INTO table ($keys) VALUES ($values) ... $keys must be ` ` and $values must be ' '.
    example, `id`,`name` .
    you are NOT obligated to put field names in back quotes `, it's optional..
    We don't need a reason to help people
      0 Not allowed!

  34. #34
    Join Date
    Jan 2005
    Location
    Manchester, UK
    Posts
    194
    Yea i apologize bout that double ? ,
    its (if) ? true : false;
    But about the ``, you dont have to put `key` etc, but it is better coding standards, plus i was correcting the original which was ' ' which wouldnt work.
    And seeming as this is about improving php coding, the `` 's are better to use.

    Thanks anyways,
    Splamoni
    http://www.imgdoc.net/ - Free Online Image and Document Hosting
      0 Not allowed!

  35. #35
    Join Date
    May 2003
    Location
    United States
    Posts
    54
    Most everyone here can probably agree that I'm not the best programmer around, so thanks for your comments about that.
      0 Not allowed!

  36. #36
    Join Date
    Feb 2005
    Location
    Seattle, Washington
    Posts
    144
    I would just like to point out that include|require(_once) are language constructs, so you do not need to use ( ) when using them. Instead, just do require_once 'File.php';

    Another comment, unless text needs to be parsed(i.e. has \n or variables etc in it), you should always use ' for enclosing strings, instead of "

    Also, it is better to do !isset($_POST['name']) instead of !$_POST[name] (do this for any var, not just $_POST).

    Also, someone was using globals above, you should try and avoid using globals, its a horrible practice. Instead, pass the values to the array.
    Regards,
    Matthew Fonda
    PHP Developer
      0 Not allowed!

  37. #37
    And when you have a massive load on your server knowing how to optimize your script will be important.
    The following link will tell you some teqniues.
    http://www.php.lt/benchmark/phpbench.php
    http://DNSDigger.com - Shows what other sites is hosted on that IP/host/range.
      0 Not allowed!

  38. #38

    Re: Re: How To : Improve Your PHP Programming

    Originally posted by websterworld
    get a proper PHP editor such as PHPcoder or the one by zend . (which is great, I love it. )

    it has a ton of time saving advantages such as syntax highlighting and line numbering, 'etc.


    Eugene

    You are talking about Zend Studio, right?
    Last edited by JonBlower; 07-15-2005 at 05:49 PM.
    Jon
    ---------
    imgholder.com
      0 Not allowed!

  39. #39
    Join Date
    Mar 2005
    Posts
    31

    Question Re: How To : Improve Your PHP Programming

    Thanks for sharing the PHP expertise. I'm impressed with how PHP is apparently free and developed by folks all over the world (like Linux). When companies have their own software that they sell us along with their hosting (for example regarding forums or databases), and they charge for bandwidth as well, it's not always easy to view their software "upgrades" with suspicion when bandwidth consumption charges subsequently increase. At least with PHP there doesn't tend to be that potential conflict of interest, it would seem.

    Might anyone here care to comment on whether PHPbb would be my best bet for creating a membership database, affordably? I'm hoping to gradually fill it up with over 50,000 members (if not more, ideally), and to have considerable data on each one (that they could include and update, in their own language but more often than not in Spanish). Then when I need to find members with certain characteristics, I can search the database and mass-mail the ones who satisfy the criteria.
    Ideally I could offer cookies so that they wouldn't have to log in each time they visit, and so that I could tailor the interface precisely for them and folks of their demographics to make it more interesting (and to streamline communications, requiring as few clicks as possible). I'd like to be able to represent in good conscience that the data's secure, too. Unfortunately I'm not a computer programmer as a specialist, but I know html pretty well. I'm tempted to get a hosting account somewhere and gradually learn the ropes with the assistance of the host, but it may be that PHPbb isn't really the most suitable language and I should know that before selecting a host. Affordability is a significant concern though. Any thoughts, friends?
      0 Not allowed!

  40. #40
    Join Date
    Jan 2006
    Posts
    31
    sometimes, we need to have some randomized values. I just create my own random function to something like this

    toss($from,$to)

    inside toss is a code that will generate a random number between $from and $to...

    so if i need three values, toss(1,3) will return any value from 1 to 3.
      0 Not allowed!

Page 1 of 2 12 LastLast

Posting Permissions

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